sintaxe bash - comando wrapping dentro de sudo :: tail logs até string encontrada com timeout usando Terraform

4

Objetivo: usar sudo executar um cmd de uma linha para completar um log até que uma string seja encontrada e sair do 0. Se a string não for encontrada em um determinado tempo limite, saia de qualquer coisa, exceto 0.

Tentativa de solução 1: Originalmente, eu não tinha tempo limite como requisito e, assim, após algumas pesquisas, consegui usar:

sudo sh -c '( tail -n1 -f /path/to/nameOfLog.log & ) | grep -q "Started .*Application"'

No entanto, agora tenho tempo limite como um requisito. Não consegui descobrir como obter o tempo limite para trabalhar com esse comando até encontrar a resposta do Ondra Žižka . Então meu novo cmd se tornou:

Solução da tentativa 2:

timeout 5 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)

Mas isso obviamente não está usando permissões sudo, que é a questão atual que eu preciso resolver. Abaixo estão algumas variações que eu tentei que falharam

Tente 1: (adicione o sudo na frente do cmd)

sudo timeout 5 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)

Saída:

grep: /dev/fd/63: No such file or directory

Tente 2: (tente envolver cmd em subshell)

sudo sh -c 'timeout 5 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)'

Saída:

sh: 1: Syntax error: "(" unexpected

Alguém pode me mostrar e explicar o problema e como corrigi-lo para que eu possa executar este comando usando o sudo? Além disso, eu realmente preciso reestruturar o cmd de Attempted Solution 1 para que ele funcione com o tempo limite também?

    
por mdo123 19.10.2016 / 22:20

2 respostas

0

Encontrou a resposta de Alexander Batischev para usar sudo su -c .

Solução (OLD):

sudo su -c 'timeout 200 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)'

ATUALIZAÇÃO:

Com base na resposta da ilkkachu , fiz mais alguns testes e encontrei uma nova solução.

  1. Primeiro, em resposta à resposta do ilkkachu sobre sudo su ser redundante. Se eu remover sudo do comando, serei solicitado a inserir uma senha.

  2. Segundo, em resposta à resposta do ilkkachu sobre um subshell não ser útil. Isso é verdade. No entanto, o comando sem o subshell só retorna se o log estiver sendo gravado ativamente por algum motivo. Caso contrário, trava. Ao usar o subshell, o cmd retorna mesmo se o log não estiver sendo gravado ativamente. Então eu prefiro o comando subshell, mas sh não suporta subshells.

    Além disso, observei ao testar em um log ativo que o uso de bash vs. sh tem tempo diferente. Por algum motivo, sh leva um segundo a mais para responder, em seguida, bash .

    Por esses dois motivos (usando subshell e atraso em sh over bash ), decidi que sh não é a solução adequada.

  3. Em terceiro lugar, em resposta à resposta do ilkkachu sobre o desnecessário & para tail . Isso está correto, eu removi e não teve impacto.

Resumo:

sudo su vs. su

//prompts for password w/out sudo
su -c 'timeout 200 grep -q "Started .*Application" <(tail -n100 -f /path/to/nameOfLog.log &)''

//works
sudo su -c 'timeout 200 grep -q "Started .*Application" <(tail -n100 -f  /path/to/nameOfLog.log  &)'

usando sh -c

//either works (sudo or not using sudo)
//but both won't work unless log is actively being written to for some reason    

sudo sh -c 'tail -n100 -f /path/to/nameOfLog.log | grep -q "Started .*Application"'

sh -c 'tail -n100 -f /path/to/nameOfLog.log | grep -q "Started .*Application"'

usando o bash

//either works (sudo or not using sudo)

sudo bash -c 'timeout 5 grep -q "Started .*Application" <(tail -n100 -f /path/to/nameOfLog.log &)'

bash -c 'timeout 5 grep -q "Started .*Application" <(tail -n100 -f /path/to/nameOfLog.log &)'

NOVA Solução:

Percebi que deixei de fora um detalhe importante . O que é que isso estava sendo executado por meio de um provisionador de execução remota do terraform . O Terraform cria um script .sh local em / tmp / no servidor para quaisquer comandos in-line . O comunicador / ssh / communicator.go define #!/bin/sh no parte superior dos scripts, o que significa que eles estão usando sh . Então, como estou usando um subshell, preciso usar o bash. O uso de sudo não é necessário e foi meu mal entendido. No entanto, você ainda pode usar o sudo. Então a resposta com a qual eu fui é um dos comandos usando o bash listados no Resumo acima.

P.S. meus servidores de destino, neste caso, estavam executando 14.04.1-Ubuntu . A execução de ls -l /bin/sh mostra /bin/sh -> dash , portanto, na verdade, não estou usando sh , mas traço. Portanto, parece que dash tem os mesmos contratempos de sh .

    
por 19.10.2016 / 23:16
0

1) Não tenho certeza se o subshell (ou background) é útil aqui:

sudo sh -c '( tail -n1 -f /path/to/nameOfLog.log & ) | grep -q "Started .*Application"'

não deveria um pipe simples?

sudo sh -c 'tail -n1 -f /path/to/nameOfLog.log | grep -q "Started .*Application"'

2) Seu "teste 1":

sudo timeout 5 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)

expande o redirecionamento de entrada <() na linha de comando que executa o sudo , não dentro de sudo . O identificador de arquivos aberto não é passado de sudo para grep , portanto, grep não pode abrir o arquivo /dev/fd/63 pseudo.

A mesma coisa sobre o backgrounding do tail aqui, não deve ser necessário.

3) E, como phk comentou , o seu" try 2 ":

sudo sh -c 'timeout 5 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)'

... executa explicitamente sh e não bash ou qualquer outro shell com mais recursos. Padrão simples sh não suporta <() e nem dash que é usado como sh no Debian e no Ubuntu.

Quando você executa su , ele executa o shell de login de root , que provavelmente é bash no Ubuntu. Mas o uso de sudo e su é redundante, ambos são feitos para elevar privilégios e, depois de sudo , você já está executando privilégios elevados , portanto, não há necessidade de su . Em vez disso, se você deseja executar um shell dentro de sudo , basta dizer explicitamente qual:

sudo bash -c 'timeout 5 grep -q "Started .*Application" <(tail -n1 -f /path/to/nameOfLog.log &)'
    
por 20.10.2016 / 11:33