“Tocando” na saída padrão?

2

Isso provavelmente parece uma pergunta estranha, mas digamos que eu tenha um script cuja saída esteja sendo gravada em um arquivo como este:

myscript.sh >> /path/to/some/file

É possível "tocar" o padrão de modo que o tempo de modificação do arquivo de saída possa ser atualizado sem realmente escrever nada?

Obviamente, se o caminho estava sendo passado diretamente para o script, eu poderia facilmente fazer isso com o comando touch , mas esse não é o caso aqui, ao invés disso estou redirecionando o padrão para um arquivo.

Existe uma maneira inteligente de tocar o arquivo de destino ao usar o redirecionamento de E / S, ou eu preciso manipular o caminho de saída internamente ou dentro de algum tipo de script de wrapper?

    
por Haravikk 03.11.2017 / 11:45

2 respostas

3

Pelo menos no Linux, /dev/stdout é um link simbólico para /proc/self/fd/1 , que é um link simbólico para o arquivo - então touch /dev/stdout funciona:

user@host:~$ ( echo hi; stat -c '%y' /tmp/foo >&2; for i in 0 1 2; do sleep 2; touch /dev/stdout; stat -c '%y' /tmp/foo >&2; done ) >> /tmp/foo
2017-11-03 07:02:59.595622835 -0400
2017-11-03 07:03:01.599680859 -0400
2017-11-03 07:03:03.603738883 -0400
2017-11-03 07:03:05.611797023 -0400

No Linux, isso é bem-sucedido ou não faz nada silenciosamente quando stdout não é um arquivo (por exemplo, um canal anônimo, por exemplo, ./myscript.sh | less , na verdade tem um mtime e o mtime de um soquete é sempre 0). Se o stdout não estiver aberto (o que é possível, embora seja raro), ele produzirá um diagnóstico ("nenhum arquivo ou diretório" na minha máquina). O mesmo se stdout for para um arquivo não gravável.

Não é de todo portátil, mas provavelmente produzirá um diagnóstico e não fará nada (pelo menos como não-raiz, que não deveria poder escrever em /dev ).

Dependendo do seu objetivo real, provavelmente existe uma maneira melhor. Por exemplo, talvez você devesse passar o nome do arquivo para o script, então é trivial usar touch diretamente nele. Ou se você está fazendo isso para dizer "ainda está vivo!" talvez você queira um arquivo separado para isso (ou use um supervisor de processo e / ou um arquivo pid).

    
por 03.11.2017 / 12:07
2

Você precisaria invocar a chamada do sistema futimes() / futimens() .

Com perl , você pode invocá-lo com:

perl -e 'utime undef, undef, *STDOUT'
    
por 03.11.2017 / 12:44