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

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

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

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?

Respuesta1

Esto funciona:

if diff "./helloworld$x.out" "./output/helloworld$x.out" >/dev/null; entonces
    echo "Pasó $x";
demás
    echo "Error $x";
fi

Si usa una variable en lugar de echoella, puede eliminar la elserama: establezca la variable en falso antes de ify guarde 2 líneas de código.

Si realmente desea poner el resultado en una variable, use:

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

Incluyendo mi prueba para ver si realmente funciona:

rinzwind@discworld:~$ toque 1
rinzwind@discworld:~$ toque 2
rinzwind@discworld:~$ más prueba
si diferencia 1 2 >/dev/null; entonces
    echo "Pasó $x";
demás
    echo "Error $x";
fi
rinzwind@discworld:~$ ./prueba
Aprobado

rinzwind@discworld:~$ vi 2
rinzwind@discworld:~$ más 2
2
rinzwind@discworld:~$ ./prueba
Fallido

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á difflistados uno al lado del otro:

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

Respuesta2

diffincluso puede suprimir la salida por completo, excepto el mensaje "Los archivos /bin/bash y /bin/sh difieren" usando el siguiente código.

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 agregarlo > /dev/nulldespués del comando diff para ocultar la salida de diff:

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

/dev/nulles un archivo especial que actúa como un agujero negro; si escribes en él, desaparecerá; si lees, no recibirás nada a cambio.

Tenga en cuenta que bash no necesita ;finalizar 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 comprobar si una variable está vacía:

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

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

Respuesta3

a) La salida del comando1 se puede capturar con

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

o con comillas invertidas, pero no se recomiendan porque no se pueden anidar y pueden ser difíciles de distinguir de los apóstrofos, según la fuente:

 output=`cmd1`

b) En lugar de escribir en un archivo y luego leerlo (o tomar el resultado y luego repetirlo), usaría una tubería directamente:

 cmd1 > file
 cat file | cmd2 

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

=>

 cmd1 | cmd2 

pero en su ejemplo, no le interesa el resultado, sino 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 "atajo Y y atajo O".

Para mantener limpia la salida, puedes 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

Respuesta4

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

if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi

información relacionada