Como posso usar o valor de um canal no programa de teste?


10
wc -l | test -eq 1

Isso não funciona. Eu quero comparar o resultado de wc com o valor de 1. Como posso fazer isso?

Respostas:


8

Não responde à sua pergunta sobre tubos, mas você pode reorganizar:

test $(ls -l | wc -l) -eq 1 && echo "worked"

E há algumas soluções em SO , sendo esta a mais agradável:

ls -l | wc -l | { read wc; test $wc -eq 7 && echo "woohoo"; }

4

Se você estiver usando o Bash, provavelmente desejará pesquisar a variável PIPESTATUS. Conforme observado no guia de referência do Bash , o PIPESTATUS é

Uma variável de matriz (consulte Matrizes) contendo uma lista de valores de status de saída dos processos no pipeline de primeiro plano executado mais recentemente (que pode conter apenas um único comando).

Podemos descobrir quais eram os códigos de saída desse pipeline com o PIPESTATUS:

dmesg | grep -iw 'nnse' | wc -l

Se você agora consultar a variável da matriz, obterá os status de saída referentes aos comandos usados ​​no pipeline:

echo ${PIPESTATUS[@]}
0 1 0

(Em uma matriz indexada, os códigos de saída acima são representados por 0 1 e 2 na matriz, pois as matrizes sempre começam em 0 no Bash.)

Aqui vemos o segundo comando retornado 1, e o restante 0; no entanto, wc -lretorna 0 se houver zero correspondências, o que não é um erro. A falha é representada com um valor diferente de zero, e há outros valores de erro, como 127, que não foi encontrado no comando, e ainda mais códigos que podem ser específicos para o programa em questão.

Se você deseja ver qual era o código de saída de um comando específico no pipeline, basta acessar esse valor. O comando grep foi o segundo comando no pipeline acima, mas como as matrizes começam em 0, precisamos da entrada um.

Portanto, para descobrir o código de saída do comando grep, execute o pipeline acima novamente (pois o conteúdo do PIPESTATUS estará esgotado se você tiver executado echo ${PIPESTATUS[@]}) e execute o comando abaixo, que retornará 1 (o código de saída):

echo ${PIPESTATUS[1]}
1

Em um script, verifique se o pipeline concluiu a execução antes de procurar o conteúdo da variável de matriz PIPESTATUS.

Para um exemplo de uso interessante da variável de matriz PIPESTATUS, consulte esta resposta sobre a combinação do agrupamento de comandos Bash e status do pipe . Você pode testar a variável da matriz da maneira sugerida por Gilles nos comentários, embora seja necessário primeiro executar o pipeline novamente:

dmesg | grep -iw 'nnse' | wc -l
[ ${PIPESTATUS[1]} -eq 1 ] && do_something_here

Este é apenas um fragmento, pois não sei que tipo de script você pretende, mas espero que o PIPESTATUS seja útil para você. Existem muitas variáveis ​​de array do Bash, como o PIPESTATUS, que podem ser extremamente úteis; consulte o guia de referência do Bash para obter a lista completa e os outros sites do Stackexchange para exemplos de uso.


1

Isso não cobre todos os testcasos, mas se você pode usar uma expressão regular e grepa cadeia de caracteres canalizada, é bastante simples porque grepé testparecido com o fato de ter uma saída diferente de zero quando nenhuma correspondência for encontrada

cat file | wc -l | grep -qE '^\s*1\s*$'

Expressões regulares estendidas permitem cobrir muitos casos com esta técnica. Para risadinhas, um caso de teste:

for i in 1 11 '' foo; do 
  if echo $i | grep -qE '^\s*1\s*$'; then 
    echo "'$i' matched"
  else
    echo "'$i' didn't match."
  fi
done

saídas:

'1' matched
'11' didn't match.
'' didn't match.
'foo' didn't match.

1

A maneira mais simples é provavelmente usar xargs :

wc -l | xargs -I % test % -eq 1
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.