Cómo guardar la salida del comando (por ejemplo, diff) en una variable


21

Quiero probar si hay algún resultado del diff(prueba si los archivos son iguales), si no hay ninguno echo "Passed $x" else echo "Failed $x". Se me ocurrió algún paso intermedio (guarde la salida de diff en un archivo y luego lea el archivo)

diff "./helloworld$x.out" "./output/helloworld$x.out" > tmp.txt;
output="`cat tmp.txt`";

if [ "$output" = "" ];
  then
    echo "Passed $x";
  else
    echo "Failed $x";
  fi;

¿Estoy seguro de que el código se puede mejorar? La pregunta principal es: ¿es posible guardar la salida diffdirectamente en una variable?

Respuestas:


18

Esto funciona:

if diff "./helloworld$x.out" "./output/helloworld$x.out"> / dev / null; luego
    echo "Pasó $ x";
más
    echo "Falló $ x";
fi

Si usa una variable en lugar de echopodría soltar la elseramificación: configure la variable en falso antes de ify guarde 2 líneas de código.

Si realmente quiere poner el resultado en un uso variable:

some_var="$(diff "./helloworld$x.out" "./output/helloworld$x.out")"

Incluyendo mi prueba para ver si realmente funciona:

rinzwind @ discworld: ~ $ touch 1
rinzwind @ discworld: ~ $ touch 2
rinzwind @ discworld: ~ $ más prueba
if diff 1 2> / dev / null; luego
    echo "Pasó $ x";
más
    echo "Falló $ x";
fi
rinzwind @ discworld: ~ $ ./test
Pasado 

rinzwind @ discworld: ~ $ vi 2
rinzwind @ discworld: ~ $ más 2
2
rinzwind @ discworld: ~ $ ./test
Ha fallado 

Por >/dev/nullparte: >/dev/null 2>&1enviará resultados >/dev/nully 2>&1 enviará errores estándar al mismo archivo ( &1significa 'usar el primer parámetro') delante de este comando (por lo que también usa /dev/null).

nota al margen: sdiffmostrará una lista de lado a lado diff:

sdiff 1 2 
1 1
2 2
3 3
4 4
5 5
7 7
                                  > 8
9 9
10 10

Gracias, funciona, pero no entiendo lo que ... > /dev/nullhace en este contexto. La salida de diff irá a goto / dev / null pero ¿no es eso nada?
Jiew Meng

1
El diff mostrará todas las diferencias entre los archivos en su pantalla y> / dev / null se asegura de que el resultado del comando se redirija al olvido. El if todavía se ejecuta en función de la salida.
Rinzwind

1
La instrucción if verifica el código de salida del comando diff. 0 significa que no se encontraron diferencias, mientras que 1 significa que hubo una o más diferencias.
Knut Eldhuset

17

diff incluso puede suprimir la salida por completo, excepto el mensaje "Archivos / bin / bash y / bin / sh diferente" utilizando el código a continuación.

file1="./helloworld$x.out"
file2="./output/helloworld$x.out"

if diff -q "$file1" "$file2"; then
    echo "Passed $x"
else
    echo "Failed $x"
fi

Si incluso desea ocultar ese mensaje, debe agregar > /dev/nulldespués del comando diff para ocultar la salida de diff:

if diff -q "$file1" "$file2" >/dev/null; then

/dev/null es un archivo especial que actúa como un agujero negro, si lo escribe, desaparecerá, si está leyendo, no recibirá nada.

Tenga en cuenta que bash no necesita ;terminar líneas.

En cuanto a la pregunta original, para guardar la salida de un programa en una variable:

file1="./helloworld$x.out"
file2="./output/helloworld$x.out"
output="$(diff -q "$file1" "$file2")"

# the quotes are mandatory, this checks whether $output is empty or not
if [ -n "$output" ]; then
    echo "Passed $x"
else
    echo "Failed $x"
fi

Formas alternativas de verificar si una variable está vacía:

[ "$output" = "" ]
[ "$output" == "" ]
[[ "$output" == "" ]]
[[ $output == "" ]]

Si está utilizando Bash, se recomiendan los dos últimos comandos para la comparación de cadenas. De lo contrario, el primero y [ -n "$output" ]se recomienda.


6

a) La salida del comando1 puede capturarse con

output=$(diff "helloworld$x.out" "output/helloworld$x.out") 

o con backticks, pero se desaconsejan, porque no puedes anidarlos y puede ser difícil distinguirlos de los apóstrofos, dependiendo de la fuente:

 output=`cmd1`

b) En lugar de escribir en un archivo, y luego leer ese archivo, (o tomar la salida y luego hacer eco) usaría una tubería directamente:

 cmd1 > file
 cat file | cmd2 

 output=$(cmd1)
 echo "${output}" | cmd2 

=>

 cmd1 | cmd2 

pero en su ejemplo, no está interesado en el resultado, sino en el resultado del programa: ¿funcionó?

 diff "helloworld$x.out" "output/helloworld$x.out" && echo "success" || echo "failure" 

Para leer sobre el uso de && y || busque "acceso directo AND y acceso directo OR".

Para mantener la salida limpia, puede redirigir la salida de 'diff' a ninguna parte:

 diff "helloworld$x.out" "output/helloworld$x.out" >/dev/null && echo "success" || echo "failure" 

Para obtener el éxito y evaluarlo más tarde, almacena el resultado del último comando en una variable con $ ?:

diff "helloworld$x.out" "output/helloworld$x.out" >/dev/null
result=$?
# do something else
case $result in 
   0) echo success ;;
   *) echo failure ;;
esac

3

Si desea saber si dos archivos son iguales o diferentes (pero no importa cuál sea la diferencia en realidad), cmpes más adecuado.

if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.