Tenho que executar quatro if
instruções separadas (e suas consequências) em uma saída de comando continuamente enquanto ela é atualizada (fazendo quatro coisas diferentes com base em quatro strings diferentes que podem estar na saída). Aqui estão algumas limitações:
- Ele deve funcionar com as ÚLTIMAS DUAS linhas, pois o comando que estou usando sempre coloca uma quebra de linha no final.
- Ele deve ser executado sem nunca encerrar o comando original.
- Tentei canalizar a saída para um arquivo usando
entr
, mas não funcionou, pois entr só detecta quando o arquivo está fechado e meu método de canalizar para o arquivo não faz isso? Ou algo assim, eu realmente não entendo.
Minhas opções, eu acho, são as seguintes:
- Salve continuamente as duas últimas linhas de saída em uma variável e execute as instruções if em um processo paralelo separado sempre que a variável mudar.
- Execute todas as instruções if em série como uma única linha, canalizando a saída padrão do comando original sem modificações por todas elas. (Pesquisas superficiais sugerem que executar uma instrução if diretamente no stdin pode não ser possível.)
- Canalize o mesmo stdout diretamente para quatro comandos separados ao mesmo tempo.
- Encontre uma maneira de canalizar um comando para um arquivo que feche o arquivo a cada atualização.
- Canalize a saída do comando para um arquivo e execute a maior parte do script em Python em vez de Bash.
Se alguém souber um método para fazer qualquer um desses, agradeço muito a ajuda. Observe que estou fora do meu alcance aqui e provavelmente precisarei de mais explicações do que o normal. Obrigado :)
Uma abordagem mais simples é escrever um script que tenha a saída padrão do comando canalizada para ele. O script lê linha por linha em um
while read
loop, e o conteúdo de cada linha é correspondido em umacase
instrução, em vez de uma série deif
instruções. Como você deve lidar com a linha vazia no final do grupo de linhas? Depois de lê-la, simplesmente ignore-a e aguarde a próxima linha. Aqui está um exemplo:As instruções Case realizam correspondências de strings simples na variável fornecida e executam o comando que corresponde ao primeiro correspondente.
O tipo de correspondência é semelhante a um glob de arquivo. No exemplo, linhas que começam com "um", "dois", "três" ou "quatro" fazem com que o script execute um comando diferente. O
""
corresponde a uma string vazia (o resultado da leitura de uma linha vazia comread
), e o*
corresponde a qualquer outra coisa ainda não especificada na instrução case.Não há nenhuma ação especificada para os casos vazio e desconhecido, então o script não faz nada com eles. O loop retornará ao topo e aguardará a próxima linha passar pelo pipe.
Isso pode ser simplista demais para a correspondência de linhas que você procura ou para as ações que deseja realizar com as quatro cordas que está detectando. Mas talvez seja um começo.
Você passaria a saída do comando para este script em um pipeline simples:
Ao reler a pergunta, vejo a possibilidade de minha resposta anterior não cobrir bem. Você precisa detectar quatro strings, e minha outra resposta funciona melhor quando uma das strings aparece em uma linha na saída do comando. Mas se duas, três ou todas as quatro pudessem aparecer na mesma linha, e você precisasse executar uma ação para cada string, a
case
instrução pode não funcionar bem.Aqui está o mesmo
while read
loop comif/then
testes:Meu exemplo usa a sintaxe de teste com colchetes duplos (
[[
and]]
) porque acredito que as vantagens superam as desvantagens. Para manter o exemplo simples, os testes usam a correspondência de padrões de string interna do Bash em vez degrep
orawk
(mas isso é algo que você pode fazer).O
while read
loop lê uma linha cada vez que o script atinge o topo do loop. Não há tempo limite, então, se o comando que está sendo enviado para este script pausar, este script aguarda.O primeiro processamento do loop
[[ -z ${input_line} ]] && continue
testa se $input_line está vazio e, em caso afirmativo, invocacontinue
, que ignora o restante do loop e retorna ao início. Ele usa uma sintaxe compacta para acoplar ocontinue
comando ao teste.O próximo teste usa a mesma sintaxe de acoplamento compacto, mas invoca um grupo de comandos entre chaves em vez do comando único do teste anterior.
Os dois testes a seguir mostram cláusulas muito convencionais
if/then
, que também podem executar um único comando ou vários comandos, como qualquer outroif/then
.Com exceção das linhas vazias, cada linha é testada por todos os testes fornecidos, de modo que todos podem detectar sua string específica caso ela apareça na linha. Quando várias strings aparecem na mesma linha, cada uma delas será detectada e a ação correspondente será tomada.
Por fim, todos os comandos no final do loop serão invocados para cada linha (exceto linhas vazias). Talvez seja apropriado que este loop envie as linhas para um arquivo. Ou, se não houver nenhum comando desse tipo, as outras linhas serão ignoradas.