Como combinar & e &&?

4

Este é o tipo de pergunta que é muito difícil de pesquisar!

Eu tenho um script de shell que é assim:

#!/bin/bash
./script.fcgi --socket /tmp/fcgi-socket &
sleep 2
chmod a+w /tmp/fcgi-socket

script.fcgi é um programa de longa execução (um daemon?) e eu preciso acrescentar o & para que seja executado em segundo plano. Além do fato de que estou cansado, preciso dormir porque senão o script não tem tempo de configurar o socket antes que eu possa chmod-lo.

Eu queria ter um verso como este:

./script.fcgi --socket /tmp/fcgi-socket & && chmod a+w /tmp/fcgi-socket 

mas eu acho que não é possível. E eu não sei como obter o script para definir o soquete com as permissões de gravação adequadas (isso seria para outra pergunta). Mas eu estava curioso: estou faltando alguma coisa sobre a combinação de & e & & ou realmente não é possível fazer o que eu tenho em mente?

    
por augustin 09.01.2015 / 05:41

5 respostas

3

Supondo que eu entenda o que você quer fazer e seu processo não está propenso a bifurcar, eu faria algo como:

/long/running/process with args &
LRP_PID=$!
sleep 2
if jobs %% #It's alive!
then 
    chmod a+w ...
fi

(ou kill -0 $LRP_PID em vez de jobs 1 .)

    
por 09.01.2015 / 10:58
1

Sim, claro que é possível: esta é a sintaxe

 (/absolute/path/to/script/script.fcgi --socket /tmp/fcgi-socket &) && (sleep 2; chmod a+w /tmp/fcgi-socket)

Mas tenha em mente o comentário do Mikel, que está correto.

EDITAR:

em vista do comentário do @ muru abaixo, deixe-me explicar. O OP não deseja executar os 2º e 3º comandos após a conclusão bem sucedida do primeiro: ele afirma explicitamente que é um comando de longa duração. O OP quer executar o terceiro comando após o sucesso do start do primeiro comando. O one-liner acima faz exatamente isso.

EDIT2:

No prompt do @ muru, o seguinte one-liner irá verificar se há erros no início dos comandos iniciais:

 (/absolute/path/to/script/script.fcgi --socket /tmp/fcgi-socket  2> /path/to/errors.txt &) && (sleep 2; if ! [ -s /path/to/errors.txt]; then chmod a+w /tmp/fcgi-socket; fi)
    
por 09.01.2015 / 07:52
0

Se você não fizer logout do terminal, poderá executá-lo desta forma:

./script.fcgi --socket /tmp/fcgi-socket && chmod a+w /tmp/fcgi-socket &

Se você for fazer logoff, é melhor iniciar o script em um multiplexador de terminal como screen ou tmux .

Eu não estou muito familiarizado com tmux , mas é assim que você pode fazer isso com screen :

Inicie uma tela usando o comando screen . No novo shell 'screen', inicie:

./script.fcgi --socket /tmp/fcgi-socket && chmod a+w /tmp/fcgi-socket

Acertar enter

Desanexe a tela pressionando ctrl + a seguido por ctrl + d

Você pode se conectar de volta à tela depois de voltar usando:

screen -r

A execução deste script na tela executará o script em segundo plano. Você poderá se conectar novamente ao shell quando voltar a anexá-lo à tela.

    
por 09.01.2015 / 06:18
0

Você pode colocar um processo (ou vários processos) em segundo plano com & e, posteriormente, no seu script, você pode esperar que todos sejam concluídos, usando o comando bash builtin wait . Aqui está a sinopse de man bash :

   wait [-n] [n ...]
          Wait for each specified child process and return its termination
          status.  Each n may be a process ID or a job specification; if a
          job spec is given, all processes  in  that  job's  pipeline  are
          waited  for.  If n is not given, all currently active child pro‐
          cesses are waited for, and the return status is zero.  If the -n
          option  is  supplied,  wait  waits  for any job to terminate and
          returns its exit status.  If n specifies a non-existent  process
          or  job, the return status is 127.  Otherwise, the return status
          is the exit status of the last process or job waited for.

Verificar o status de retorno de wait para um trabalho específico pode fornecer a verificação "se bem-sucedido" que && faz, como neste script de teste:

#!/bin/bash
sleep 3 &
s3pid=$!
true &
trpid=$!
false &
fapid=$!

echo "Expecting success next, since true returns 0"
wait $trpid && echo "wait process true success" || echo "wait process true FAIL"
echo "Expecting FAIL next, since false returns 1"
wait $fapid && echo "wait process false success" || echo "wait process false FAIL"
echo "Expecting success next, since wait alone always returns 0"
wait && echo "wait for all success" || echo "wait for all FAIL"

Mas para apenas um comando, usar && sozinho seria o mesmo ... E, no caso do solicitante, se você estiver executando um programa do tipo "never stop", ele não terminará & você realmente não quer && ou wait

    
por 09.01.2015 / 07:06
0

Parece-me que muitas pessoas estão pensando demais nisso. É o suficiente para dizer

./script.fcgi --socket /tmp/fcgi-socket & sleep 2; chmod a+w /tmp/fcgi-socket

porque, sintaticamente , & age como ; . (Sim, claro, eu sei que eles são semanticamente diferentes.)

    
por 10.01.2015 / 21:20