¿Cómo puedo usar el valor de una tubería en el programa de prueba?

10
wc -l | test -eq 1

Esto no funciona Quiero comparar el resultado de wc con el valor de 1. ¿Cómo puedo hacer eso?

tr3quart1sta
fuente

Respuestas:

9

No responde su pregunta sobre tuberías, pero puede reorganizar:

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

Y hay algunas soluciones en SO , siendo esta la mejor:

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

Si está utilizando Bash, probablemente desee investigar la variable PIPESTATUS. Como se señala en la guía de referencia de Bash , PIPESTATUS es

Una variable de matriz (ver Matrices) que contiene una lista de valores de estado de salida de los procesos en la canalización de primer plano ejecutada más recientemente (que puede contener solo un comando).

Podemos averiguar cuáles fueron los códigos de salida para esta tubería con PIPESTATUS:

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

Si ahora consulta la variable de matriz, obtiene los estados de salida que se refieren a los comandos utilizados en la tubería:

echo ${PIPESTATUS[@]}
0 1 0

(En una matriz indexada, los códigos de salida anteriores están representados por 0 1 y 2 en la matriz ya que las matrices siempre comienzan en 0 en Bash).

Aquí vemos que el segundo comando devolvió 1, y el resto 0; sin embargo, wc -ldevuelve 0 si hay cero coincidencias, lo cual no es un error. La falla se representa con un valor distinto de cero, y hay otros valores de error como 127 que no se encuentra el comando, y aún más códigos que pueden ser específicos para el programa en cuestión.

Si desea ver cuál era el código de salida de un comando en particular en la tubería, puede acceder a ese valor. El comando grep fue el segundo comando en la tubería anterior, pero como las matrices comienzan desde 0, necesitamos la entrada uno.

Entonces, para averiguar el código de salida del comando grep, ejecute la tubería anterior nuevamente (ya que el contenido de PIPESTATUS se habrá agotado si ha ejecutado echo ${PIPESTATUS[@]}) y luego ejecute el siguiente comando, que devolverá 1 (el código de salida):

echo ${PIPESTATUS[1]}
1

En un script, asegúrese de que la canalización haya terminado de ejecutarse antes de buscar el contenido de la variable de matriz PIPESTATUS.

Para ver un ejemplo de uso interesante de la variable de matriz PIPESTATUS, consulte esta respuesta con respecto a la combinación de la agrupación de comandos Bash y el estado de la tubería . Puede probar la variable de matriz de la manera sugerida por Gilles en los comentarios, aunque primero deberá ejecutar la tubería nuevamente:

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

Esto es solo un fragmento, ya que no sé qué tipo de script está intentando, pero espero que conocer PIPESTATUS pueda serle útil. Hay muchas variables de matriz Bash como PIPESTATUS que pueden ser extremadamente útiles; consulte la guía de referencia de Bash para ver la lista completa y los otros sitios de Stackexchange para ver ejemplos de su uso.

Comunidad
fuente
2

La forma más simple es probablemente usar xargs :

wc -l | xargs -I % test % -eq 1
John Doe
fuente
1

Esto no cubre todos los testcasos, pero si puede usar una expresión regular y grepla cadena canalizada, es bastante sencillo porque grepes testsimilar a que tiene una salida distinta de cero cuando no se encuentra ninguna coincidencia

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

Las expresiones regulares extendidas le permiten cubrir muchos casos con esta técnica. Para las risas, un caso de prueba:

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

salidas:

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