Registra em vários arquivos enquanto processa em segundo plano (nohoup)

4

Eu tenho um script bash que registra dois arquivos de log em paralelo.

echo "$(date) | [STATE] Activating IP forwarding" >> $logsPath$logFileName
echo $(date +"%Y-%m-%d %H:%M")","$previousState >> $logsPath$usageStatsFileName
echo $(date +"%Y-%m-%d %H:%M")","$currentState >> $logsPath$usageStatsFileName

Funciona bem se eu executar o script em primeiro plano, mas quando eu enviar para o background nada é registrado nesses arquivos.

nohup nice ./rfid_reader.sh&

Você pode me dar alguma dica, o que devo fazer para poder executar o script em segundo plano e ainda ter os logs mencionados em dois arquivos?

    
por Michal W 24.03.2014 / 23:51

3 respostas

2

NOTA IMPORTANTE:

Isto é quase certamente irrelevante para esta questão. Estou deixando aqui, já que pode ajudar alguém, mas, pelo menos com a minha versão de nohup no Debian, os redirecionamentos internos não são afetados, nohup irá capturar apenas o stderr e stdout do script.

Por padrão, nohup imprimirá todas as saídas para nohup.out . Ele normalmente informa isso, mas você não pode vê-lo porque você está correndo em segundo plano. Por exemplo, tente:

$ nohup echo "foo"
nohup: ignoring input and appending output to ‘nohup.out’

Para evitar isso, você precisa redirecionar explicitamente a saída do programa:

$ nohup echo "foo" > bar
nohup: ignoring input and redirecting stderr to stdout

Então, você precisa executar seu script e redirecionar sua saída. O erro padrão e os fluxos de saída padrão serão redirecionados para o mesmo arquivo:

nohup nice ./rfid_reader.sh > output_file &

Este é realmente um padrão razoável para o nohup, já que o objetivo é permitir que você feche sua sessão de terminal e deixe-a rodando em segundo plano, de modo que tê-la impressa no terminal iria anular sua finalidade.

    
por 25.03.2014 / 00:44
1

Você realmente não precisa de nohup . Na verdade, eu pessoalmente nunca encontrei um uso para isso.

( ./rfidreader.sh 1>&2 & ) 2>&- &

Isso vai separar o seu processo do terminal, ele continuará fazendo o que for necessário e evitando quebrar coisas.

Script de demonstração

cat <<-\DEMO >|${s=/tmp/script} 
printf 'tty is %s\nparent pid is %s\npid is pid=%s\n' \
     "$(tty)" "$PPID" "$$"
exec 1>&2 ; nums=$(seq 0 9)
rm ${files=$(printf "/tmp/file%s\n" $nums)}
for n in $nums ; do { for f in $files ; do
    echo "Line $n" >>"$f" ; done
sleep 1 ; } ; done
#END
DEMO

Execute a demonstração

s=/tmp/script ;chmod +x $s ;info="$(($s &)2>&- &)"
echo "$info" ; pid="${info##*=}" ; echo
while ps -p $pid >/dev/null ; do sleep 3 ; done
for f in /tmp/file[0-9] ; do
    printf 'path : %s\tline count : %s\n' \
        $f $(<$f wc -l)
done

Saída:

tty is not a tty
parent pid is 1
pid is 12123

path : /tmp/file0    line count : 10
path : /tmp/file1    line count : 10
path : /tmp/file2    line count : 10
path : /tmp/file3    line count : 10
path : /tmp/file4    line count : 10
path : /tmp/file5    line count : 10
path : /tmp/file6    line count : 10
path : /tmp/file7    line count : 10
path : /tmp/file8    line count : 10
path : /tmp/file9    line count : 10

O acima demonstra. Ele cria e executa um script chamado /tmp/script , chmod 's como executável, e o executa no &background de um &backgrounded ( subshell ) .

O script rms /tmp/file0-9 10 arquivos e echoes uma linha a cada segundo em todos os 10 deles. Eu capturei alguns $info do processo de renome e o apresente via $(command substitution). While ps ainda relata o $pid que eu capturei, eu sei ele ainda roda, então eu sleep. Quando ele é concluído, as linhas em todos os 10 arquivos são contadas com wc.

Depois de invocar um processo dessa maneira, você pode fechar livremente o processo original do pai e ele continuará no transporte - ele é efetivamente renegado.

Vale a pena mencionar que, na verdade, o processo é chamado inicialmente em $(command substitution) e printfs me em $info Eu quero que eu possa efetivamente controlá-lo. Mas, assim que a saída do terminal é descartada com exec 1>&2 (que é fechado no mesmo subshell com 2>&- ), o processo escapa e eu tenho que esperar por ele na outra ponta. O melhor dos dois mundos, especialmente se você usá-lo para manipular os canos de entrada, contanto que você possa envolver todos os redirecionamentos e líderes de processo.

Tudo o resto é apenas para demonstração aqui. Tudo o que você precisa para executar este é o script principal e:

info="$(($script_path &)2>&- &)"    

NOTA: Isso só imprime no terminal exatamente o que eu queria demonstrar. Como observado pelo $PPID, , este processo é rejeitado pelo terminal e é um filho direto de $PID 1.

    
por 26.03.2014 / 00:37
0

Obrigado a todos vocês pelas respostas. Eu aprendi muito com eles. Problema resolvido. Nohoup não perturba o registro em arquivos externos. A origem do meu problema estava provavelmente no desempenho do sistema, pois estou trabalhando com o linux embutido. Não sabendo o que fazer Eu reiniciei o sistema e comecei o script em segundo plano mais uma vez. Agora funciona.

A questão é resolvida de alguma forma, mas a questão é por que a reinicialização foi necessária.

    
por 25.03.2014 / 22:06