Gravar a saída do programa no arquivo de log contendo o PID em seu nome

2

Como posso iniciar um programa e gravar sua saída em um arquivo de log, onde o arquivo de log contém o PID em seu nome? Eu tentei

program_a > log_$! 

que não funciona desde $! é o PID do último programa e 'program_a' não terminou quando o arquivo de log é criado.

    
por greole 19.03.2014 / 10:19

4 respostas

2

Se você está falando sobre um roteiro, acho que é isso que você está procurando ...

#!/bin/bash

exec 1>test_$$.txt 
echo "Hello \$\$ == $$" 

ps

que deu essa saída

$ cat test_20000.txt 
Hello $$ == 20000
  PID TTY           TIME CMD
18651 ttys000    0:00.06 -bash
20000 ttys000    0:00.00 /bin/bash ./execredir.sh

Espero que ajude.

    
por 19.03.2014 / 10:51
1

Você não pode fazer isso a partir do shell, porque a linha de comando é criada antes que o programa seja chamado. Você tem basicamente duas opções:

1) Crie o nome do arquivo e escreva nele a partir do programa (fácil se for um shell script)

2) Crie um pipe nomeado, faça o plano de fundo do processo e, em seguida, redirecione o pipe para um arquivo. Como

mkfifo "tmp.log"  
program_a > "tmp.log" &
cat "tmp.log" > "log_$!"
    
por 19.03.2014 / 10:24
1

Isso não responde à pergunta diretamente, mas eu questiono por que preciso para ter um arquivo com o pid no nome. Se for simplesmente um nome de arquivo exclusivo que você está procurando, existem maneiras mais robustas de fazer isso. A maioria dos Unices tem um comando mktemp (infelizmente isso não é POSIX). Usando o GNU mktemp , você poderia fazer:

tmp_file=$(mktemp --tmpdir=. log_XXXXXXXXXX)
program_a >"$tmp_file"

Se você precisar acessar os arquivos em uma data posterior, talvez seja útil incluir a data / hora no nome do arquivo:

log_file=$(mktemp --tmpdir=. log_"$(date +%F_%T)".XXX)
program_a >"$log_file"

Se você estiver procurando garantir que apenas uma instância de um processo específico esteja em execução, no Linux você pode usar flock :

(
  flock -n 9 || { echo "program_a already running"; exit 1; }
  program_a
) 9>/var/lock/program_a

Caso contrário, se você quiser que outro programa leia a saída de program_a enquanto ainda está em execução, usar um arquivo é certamente um método de última instância. É muito melhor usar um pipe ou um pipe nomeado de acordo com a resposta da orion .

    
por 19.03.2014 / 12:03
1

Você não pode conhecer o PID até que o processo tenha iniciado. Então você precisa primeiro iniciar o processo, criar o arquivo de log e executar o programa que deseja executar ( exec substitui o shell de chamada pelo programa dado, não bifurca um novo processo).

sh -c 'exec program_a >log_$$'

$! é o PID do último programa iniciado em segundo plano e não pode ajudá-lo aqui.

Como alternativa, você pode criar o arquivo de log com um nome temporário, iniciar o programa e renomear o arquivo de log, mas é desnecessariamente mais complicado.

    
por 19.03.2014 / 23:33