Estou tentando escrever um shell script que esperará que um arquivo apareça no /tmp
diretório chamado sleep.txt
e, uma vez encontrado, o programa cessará, caso contrário, quero que o programa esteja no estado de suspensão (suspenso) até que o arquivo seja localizado . Agora, estou assumindo que usarei um comando de teste. Então, algo como
(if [ -f "/tmp/sleep.txt" ];
then stop
else sleep.)
Sou novato em escrever scripts de shell e qualquer ajuda é muito apreciada!
shell-script
files
Mo Gainz
fonte
fonte
$MAILPATH
.Respostas:
No Linux, você pode usar o subsistema inotify kernel para aguardar com eficiência a aparência de um arquivo em um diretório:
(assumindo Bash para o
<()
sintaxe de redirecionamento de saída)A vantagem dessa abordagem em comparação com a pesquisa por intervalo de tempo fixo, como em
é que o kernel dorme mais. Com uma especificação de evento inotify,
create,open
o script é agendado para execução quando um arquivo abaixo/tmp
é criado ou aberto. Com a pesquisa de intervalo de tempo fixo, você desperdiça ciclos de CPU para cada incremento de tempo.Incluí o
open
evento para registrar tambémtouch /tmp/sleep.txt
quando o arquivo já existe.fonte
inotifywait -e create,open --format '%f' --quiet /tmp/sleep.txt --monitor > /dev/null ; # continues once /tmp/sleep.txt is created/opened
?inotifywait
é em si um loop while e gera uma linha toda vez que o arquivo é aberto / criado. Então você precisa que o loop while seja interrompido quando for alterado.sleep.txt
em algum momento. Portanto, nenhuma condição de corrida. A pergunta não contém nada que indique um cenário que você tem em mente.Basta colocar seu teste no
while
loop:fonte
sleep
é o número de segundos para aguardar em cada iteração - você pode alterar isso dependendo de suas necessidades.Existem alguns problemas com algumas das
inotifywait
abordagens baseadas em dados fornecidas até agora:sleep.txt
arquivo que foi criado primeiro como um nome temporário e depois renomeado parasleep.txt
. É preciso combinar osmoved_to
eventos além decreate
sleep.txt
foi criado. E se umfoo\nsleep.txt\nbar
arquivo foi criado, por exemplo?inotifywait
ter sido iniciado e instalado o relógio? Entãoinotifywait
esperaria eternamente por um arquivo que já está aqui. Você precisa garantir que o arquivo ainda não esteja lá após a instalação do relógio.inotifywait
execução (pelo menos até que outro arquivo seja criado) após a localização do arquivo.Para resolvê-los, você pode fazer:
Observe que estamos observando a criação de
sleep.txt
no diretório atual.
(faça o mesmocd /tmp || exit
no seu exemplo). O diretório atual nunca muda; portanto, quando essa linha de tubulação retorna com êxito, ela estásleep.txt
no diretório atual que foi criado.Claro, você pode substituir
.
com/tmp
acima, mas enquantoinotifywait
estiver em execução,/tmp
poderia ter sido renomeado várias vezes (improvável para/tmp
, mas algo a considerar no caso geral) ou um novo sistema de arquivos montado sobre ele, por isso, quando o gasoduto retorna, ele não pode seja um/tmp/sleep.txt
que foi criado, mas um em/new-name-for-the-original-tmp/sleep.txt
vez disso. Um novo/tmp
diretório também poderia ter sido criado no intervalo e esse não seria monitorado; portanto, um diretóriosleep.txt
criado não seria detectado.fonte
A resposta aceita realmente funciona (graças ao maxschlepzig), mas deixa o monitoramento inotifywait em segundo plano até que o script saia. A única resposta que corresponde exatamente seus requisitos (ou seja, aguardar o sleep.txt aparecer em / tmp) parece ser de Stephane, se o diretório a ser monitorado pelo inotifywait for alterado de ponto (.) Para '/ tmp'.
No entanto, se você estiver disposto a usar SOMENTE um diretório temporário para colocar seu sinalizador sleep.txt e puder apostar que ninguém mais colocará nenhum arquivo nesse diretório, basta pedir à inotifywait que observe este diretório para criar criações de arquivos:
1º passo: crie o diretório que você irá monitorar:
2º passo: verifique se o diretório está realmente lá
3º passo: aguarde até que QUALQUER arquivo apareça dentro
$directoryToPutSleepFile
O arquivo que você
$directoryToPutSleepFile
inserirá pode ter o nome sleep.txt awake.txt, qualquer que seja. O momento em que qualquer arquivo é criado dentro do$directoryToPutSleepFile
seu script continuará além dainotifywait
declaração.fonte
sleep.txt
criação entre duas invocações de espera inotifywait.sleep.txt
seja criado. Tente, por exemplotouch /tmp/foo /tmp/sleep.txt
, uma instância deinotifywait
reportaráfoo
e sairá e, quando a próxima inotifywait for iniciada, o sleep.txt já estará lá por muito tempo, portanto a inotifywait não detectará sua criação.em geral, é bastante difícil tornar confiável qualquer coisa, exceto o loop de teste / sono simples. O principal problema é que o teste será executado com a criação do arquivo - a menos que o teste seja repetido, o evento de criação poderá ser perdido. Essa é de longe a sua melhor aposta na maioria dos casos em que você usaria o Shell para começar:
Se você achar que isso é insuficiente devido a problemas de desempenho, usar o Shell provavelmente não é uma boa idéia em primeiro lugar.
fonte
Com base na resposta aceita de maxschlepzig (e em uma idéia da resposta aceita em /superuser/270529/monitoring-a-file-until-a-string-is-found ), proponho o seguinte aprimorado ( na minha opinião) resposta que também pode funcionar com tempo limite:
Caso o arquivo não seja criado / aberto dentro do tempo limite especificado, o status de saída será 124 (conforme a documentação do tempo limite (página de manual)). Caso seja criado / aberto, o status de saída é 0 (êxito).
Sim, o inotifywait é executado em um sub-shell dessa maneira e esse sub-shell só será executado quando o tempo limite ocorrer ou quando o script principal sair (o que ocorrer primeiro).
fonte