Como posso executar um trecho de código em segundo plano?

Como posso executar um trecho de código em segundo plano?

Posso executar um trecho de código em segundo plano em vez de usar outro script?

[sesiv@itseelm-lx4151 ~]$ cat ./testback2
#!/bin/bash
start_time=$(date +%s)

for i in {1..5}
do
./testscript &
done
wait

        finish_time=$(date +%s)
        seconds=$((finish_time - start_time))
        hours=$((seconds / 3600))
        seconds=$((seconds % 3600))
        minutes=$((seconds / 60))
        seconds=$((seconds % 60))
        echo "Time Taken :"
        echo "$hours hour(s) $minutes minute(s) $seconds second(s)"

[sesiv@itseelm-lx4151 ~]$ ./testback2
sleeping 22436
sleeping 22438
sleeping 22440
sleeping 22442
sleeping 22435
Time Taken :
0 hour(s) 0 minute(s) 3 second(s)

Tentei algo como abaixo, mas fornece o ID do processo pai. Eu esperava 5 IDs de processos filhos diferentes, como acima. Mas o tempo aqui é de apenas 3 segundos.

#!/bin/bash
start_time=$(date +%s)
fun() {
echo "$1 $$"
sleep 3
}


for i in {1..5}
do
fun sleeping &
done
wait

        finish_time=$(date +%s)
        seconds=$((finish_time - start_time))
        hours=$((seconds / 3600))
        seconds=$((seconds % 3600))
        minutes=$((seconds / 60))
        seconds=$((seconds % 60))
        echo "Time Taken :"
        echo "$hours hour(s) $minutes minute(s) $seconds second(s)"

output :
sleeping 22028
sleeping 22028
sleeping 22028
sleeping 22028
sleeping 22028
Time Taken :
0 hour(s) 0 minute(s) 3 second(s)

NOTA: este é o testscriptcódigo

#!/bin/bash
fun() {
echo "$1 $$"
sleep 3
}

fun sleeping

Responder1

Há algumas ocasiões em que o bash cria um novo processo, mas o valor antigo de $$é mantido. Em vez disso, tente $BASHPID.

Responder2

Não tenho certeza se entendi sua pergunta, mas você pode usar um subshell:

for i in {1..5}
do
 ( # bash code
 ) &
done

O código bash dentro do ()estará no mesmo script, mas rodando em um subshell

Responder3

$$é o PID do processo shell original que está executando o script. Não é o PID do processo shell que está fazendo a expansão. $$não muda em um subshell.

Se você precisar do PID do subshell, um método portátil é executar sh -c 'echo $PPID'. No bash ≥4, o PID do processo shell que faz a expansão está na BASHPIDvariável mágica.

fun() {
  if [ -n "$BASHPID" ]; then
    echo "$1 $BASHPID"
  else
    echo "$1 $(sh -c 'echo $PPID')"
  fi
  sleep 3
}

Responder4

Não sei se estou certo, mas fiz isso para emular o bashpid para o bash 3x e surpreendentemente os resultados foram bons:

[aehj@itseelm-lx4151 ~]$ cat t
#!/bin/bash
start_time=$(date +%s)
fun() {
bashpid=`cut -d " " -f 4 /proc/self/stat`
echo "$1 $bashpid"
sleep 3
}

echo $$
for i in {1..5}
do
fun sleeping &
done
wait

        finish_time=$(date +%s)
        seconds=$((finish_time - start_time))
        hours=$((seconds / 3600))
        seconds=$((seconds % 3600))
        minutes=$((seconds / 60))
        seconds=$((seconds % 60))
        echo "Time Taken :"
        echo "$hours hour(s) $minutes minute(s) $seconds second(s)"
[aehj@itseelm-lx4151 ~]$ ./t
25578
sleeping 25580
sleeping 25583
sleeping 25586
sleeping 25589
sleeping 25592
Time Taken :
0 hour(s) 0 minute(s) 3 second(s)

outra maneira:

[aehj@itseelm-lx4151 ~]$ cat u
#!/bin/bash
start_time=$(date +%s)

echo $$
for i in {1..5}
do
{
        fun() {
        BASHPID=`cut -d " " -f 4 /proc/self/stat`
        echo "$1 $BASHPID"
        sleep 3
        }
        fun sleeping
} &

done
wait

        finish_time=$(date +%s)
        seconds=$((finish_time - start_time))
        hours=$((seconds / 3600))
        seconds=$((seconds % 3600))
        minutes=$((seconds / 60))
        seconds=$((seconds % 60))
        echo "Time Taken :"
        echo "$hours hour(s) $minutes minute(s) $seconds second(s)"
[aehj@itseelm-lx4151 ~]$ ./u
25635
sleeping 25637
sleeping 25640
sleeping 25643
sleeping 25646
sleeping 25648
Time Taken :
0 hour(s) 0 minute(s) 4 second(s)

informação relacionada