Em um script de shell, como posso (1) iniciar um comando em segundo plano (2) wait x seconds (3) executar um segundo comando enquanto esse comando estiver em execução?

11

Isso é o que preciso acontecer:

  1. inicie o processo A em segundo plano
  2. aguarde x segundos
  3. inicie o processo B em primeiro plano

Como posso fazer a espera acontecer?

Estou vendo que 'dormir' parece parar tudo e eu não quero realmente 'esperar' que o processo A termine inteiramente. Eu vi alguns loops baseados no tempo, mas estou me perguntando se há algo mais limpo.

    
por Julie 01.12.2017 / 16:24

3 respostas

28

A menos que eu esteja entendendo mal sua pergunta, ela pode ser simplesmente obtida com este pequeno script:

#!/bin/bash

process_a &
sleep x
process_b

(e adicione um wait extra no final se quiser que seu script aguarde que process_a termine antes de sair).

Você pode até fazer isso como um one-liner, sem a necessidade de um script (como sugerido por @BaardKopperud):

process_a & sleep x ; process_b
    
por 01.12.2017 / 16:28
9

Você pode usar o operador de controle em segundo plano (&) para executar um processo em segundo plano e no sleep comando para aguardar antes de executar um segundo processo, ou seja, :

#!/usr/bin/env bash
# script.sh

command1 &
sleep x
command2

Aqui está um exemplo de dois comandos que imprimem algumas mensagens com registro de data e hora:

#!/usr/bin/env bash

# Execute a process in the background
echo "$(date) - Running first process in the background..."
for i in {1..1000}; do
    echo "$(date) - I am running in the background";
    sleep 1;
done &> background-process-output.txt &

# Wait for 5 seconds
echo "$(date) - Sleeping..."
sleep 5 

# Execute a second process in the foreground
echo "$(date) - Running second process in the foreground..."
for i in {1..1000}; do
    echo "$(date) - I am running in the foreground";
    sleep 1;
done

Execute-o para verificar se ele exibe o comportamento desejado:

user@host:~$ bash script.sh

Fri Dec  1 13:41:10 CST 2017 - Running first process in the background...
Fri Dec  1 13:41:10 CST 2017 - Sleeping...
Fri Dec  1 13:41:15 CST 2017 - Running second process in the foreground...
Fri Dec  1 13:41:15 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:16 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:17 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:18 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:19 CST 2017 - I am running in the foreground
Fri Dec  1 13:41:20 CST 2017 - I am running in the foreground
...
...
...
    
por 01.12.2017 / 16:39
5

Eu gosto da resposta do @ dr01, mas ele não verifica o código de saída e você não sabe se teve sucesso ou não.

Aqui está uma solução que verifica os códigos de saída.

#!/bin/bash

# run processes
process_a &
PID1=$!
sleep x
process_b &
PID2=$!
exitcode=0

# check the exitcode for process A
wait $PID1    
if (($? != 0)); then
    echo "ERROR: process_a exited with non-zero exitcode" >&2
    exitcode=$((exitcode+1))
fi

# check the exitcode for process B
wait $PID2
if (($? != 0)); then
    echo "ERROR: process_b exited with non-zero exitcode" >&2
    exitcode=$((exitcode+1))
fi
exit ${exitcode}

geralmente eu armazeno os PIDs em uma matriz bash e, em seguida, a verificação pid é um loop for.

    
por 01.12.2017 / 19:51