Come salvare l'output dal comando (es. Diff) in una variabile


21

Voglio testare se c'è qualche output dal diff(test se i file sono uguali), se nessuno echo "Passed $x" else echo "Failed $x". Mi è venuto in mente un passaggio intermedio (salvare l'output da diff in un file quindi leggere dal file)

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;

Sono sicuro che il codice può essere migliorato? La domanda principale è: è possibile salvare l'output diffdirettamente da una variabile?

Risposte:


18

Questo funziona:

if diff "./helloworld$x.out" "./output/helloworld$x.out"> / dev / null; poi
    echo "Passato $ x";
altro
    echo "$ x non riuscito";
fi

Se si utilizza una variabile anziché echoè possibile eliminare la elsebranche: impostare la variabile su false prima di ife salvare 2 righe di codice.

Se vuoi effettivamente mettere il risultato in una variabile usa:

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

Incluso il mio test per vedere se funziona davvero:

rinzwind @ discworld: ~ $ touch 1
rinzwind @ discworld: ~ $ touch 2
rinzwind @ discworld: ~ $ test in più
if diff 1 2> / dev / null; poi
    echo "Passato $ x";
altro
    echo "$ x non riuscito";
fi
rinzwind @ discworld: ~ $ ./test
Passato 

rinzwind @ discworld: ~ $ vi 2
rinzwind @ discworld: ~ $ di più 2
2
rinzwind @ discworld: ~ $ ./test
mancato 

Da >/dev/nullparte: >/dev/null 2>&1invierà l'output >/dev/nulle 2>&1 invierà gli errori standard allo stesso file ( &1significa "usa il primo parametro") davanti a questo comando (quindi usa anche /dev/null).

nota a margine: sdiff mostrerà un diffelenco affiancato :

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

Grazie funziona, ma non capisco cosa ... > /dev/nullfa in questo contesto. L'output di diff andrà / dev / null ma non è niente?
Jiew Meng,

1
Il diff genererà tutte le differenze tra i file sullo schermo e> / dev / null assicurerà che l'output del comando sia reindirizzato all'oblio. L'if è ancora eseguito in base all'output.
Rinzwind,

1
L'istruzione if controlla il codice di uscita del comando diff. 0 indica che non sono state rilevate differenze, mentre 1 indica che vi sono state una o più differenze.
Knut Eldhuset,

17

diff può persino sopprimere completamente l'output tranne il messaggio "File / bin / bash e / bin / sh differ" usando il codice qui sotto.

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

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

Se vuoi persino nascondere quel messaggio, devi aggiungere > /dev/nulldopo il comando diff per nascondere l'output di diff:

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

/dev/null è un file speciale che funge da buco nero, se ci scrivi, sparirà, se stai leggendo da esso, non otterrai nulla in cambio.

Nota che bash non ha bisogno ;di terminare le linee.

Per quanto riguarda la domanda originale, per salvare l'output di un programma in una variabile:

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

Modi alternativi per verificare se una variabile è vuota:

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

Se stai usando Bash, gli ultimi due comandi sono consigliati per il confronto delle stringhe. Altrimenti, il primo ed [ -n "$output" ]è raccomandato.


6

a) L'output di command1 può essere intercettato

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

o con i backtick, ma quelli sono scoraggiati, perché non puoi nidificarli e potrebbero essere difficili da distinguere dagli apostrofi, a seconda del carattere:

 output=`cmd1`

b) Invece di scrivere su un file e quindi leggere quel file (o afferrare l'output e quindi riecheggiarlo) useresti direttamente una pipe:

 cmd1 > file
 cat file | cmd2 

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

=>

 cmd1 | cmd2 

ma nel tuo esempio, non sei interessato all'output, ma al risultato del programma - ha funzionato?

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

Leggere sull'uso di && e || cercare "scorciatoia AND e scorciatoia OR".

Per mantenere pulito l'output, puoi reindirizzare l'output di 'diff' verso il nulla:

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

Per ottenere il successo e valutarlo in un secondo momento, memorizzi il risultato dell'ultimo comando in una variabile 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

Se vuoi sapere se due file sono uguali o diversi (ma non importa quale sia effettivamente la differenza), cmpè più adatto.

if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.