So speichern Sie die Ausgabe eines Befehls (z. B. diff) in einer Variablen

So speichern Sie die Ausgabe eines Befehls (z. B. diff) in einer Variablen

Ich möchte testen, ob es eine Ausgabe gibt diff(Test, ob die Dateien gleich sind), wenn nicht echo "Passed $x" else echo "Failed $x". Ich habe mir einen Zwischenschritt ausgedacht (die Ausgabe von Diff in einer Datei speichern und dann aus der Datei lesen).

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;

Ich bin sicher, dass der Code verbessert werden kann. Die Hauptfrage ist: Ist es möglich, die Ausgabe direkt diffin einer Variablen zu speichern?

Antwort1

Das funktioniert:

wenn diff "./helloworld$x.out" "./output/helloworld$x.out" >/dev/null; dann
    echo "$x bestanden";
anders
    echo "$x fehlgeschlagen";
fi

Wenn Sie stattdessen eine Variable verwenden, echokönnen Sie den Zweig löschen else: Setzen Sie die Variable vor dem auf „false“ ifund sparen Sie 2 Codezeilen.

Wenn Sie das Ergebnis tatsächlich in eine Variable einfügen möchten, verwenden Sie:

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

Einschließlich meines Tests, um zu sehen, ob es tatsächlich funktioniert:

rinzwind@discworld:~$ berühren 1
rinzwind@discworld:~$ Berührung 2
rinzwind@discworld:~$ mehr Test
wenn diff 1 2 >/dev/null; dann
    echo "$x bestanden";
anders
    echo "$x fehlgeschlagen";
fi
rinzwind@discworld:~$ ./test
Bestanden

rinzwind@discworld:~$ vi 2
rinzwind@discworld:~$ mehr 2
2
rinzwind@discworld:~$ ./test
Fehlgeschlagen

Auf der >/dev/nullSeite: >/dev/null 2>&1sendet die Ausgabe an >/dev/nullund 2>&1 sendet Standardfehler an dieselbe Datei ( &1bedeutet „ersten Parameter verwenden“) vor diesem Befehl (es verwendet also auch /dev/null).

Randbemerkung: sdiffEs wird eine Auflistung nebeneinander angezeigt diff:

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

Antwort2

diffkann mit dem folgenden Code die Ausgabe mit Ausnahme der Meldung „Die Dateien /bin/bash und /bin/sh unterscheiden sich“ sogar vollständig unterdrücken.

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

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

Wenn Sie diese Nachricht sogar verbergen möchten, müssen Sie > /dev/nullnach dem Diff-Befehl Folgendes anhängen, um die Ausgabe zu verbergen diff:

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

/dev/nullist eine spezielle Datei, die wie ein schwarzes Loch funktioniert. Wenn Sie darin schreiben, ist die Datei verschwunden, wenn Sie daraus lesen, erhalten Sie nichts zurück.

Beachten Sie, dass Bash Zeilen nicht ;beenden muss.

Zur ursprünglichen Frage: So speichern Sie die Ausgabe eines Programms in einer Variablen:

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

Alternative Möglichkeiten zum Überprüfen, ob eine Variable leer ist:

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

Wenn Sie Bash verwenden, werden die letzten beiden Befehle für den Zeichenfolgenvergleich empfohlen. Andernfalls [ -n "$output" ]werden der erste und empfohlen.

Antwort3

a) Die Ausgabe von command1 kann abgefangen werden mit

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

oder mit Backticks, aber davon wird abgeraten, weil sie nicht verschachtelt werden können und, je nach Schriftart, schwer von Apostrophen zu unterscheiden sein könnten:

 output=`cmd1`

b) Anstatt in eine Datei zu schreiben und diese Datei dann zu lesen (oder die Ausgabe zu erfassen und sie dann wiederzugeben), würden Sie direkt eine Pipe verwenden:

 cmd1 > file
 cat file | cmd2 

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

=>

 cmd1 | cmd2 

aber in Ihrem Beispiel interessiert Sie nicht die Ausgabe, sondern das Ergebnis des Programms – hat es funktioniert?

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

Um mehr über die Verwendung von && und || zu erfahren, suchen Sie nach „Tastenkürzel AND und Tastenkürzel OR“.

Um die Ausgabe sauber zu halten, können Sie die Ausgabe von „diff“ ins Nirgendwo umleiten:

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

Um den Erfolg zu erfassen und später auszuwerten, speichert man das Ergebnis des letzten Befehls in einer Variable mit $?:

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

Antwort4

Wenn Sie wissen möchten, ob zwei Dateien gleich oder unterschiedlich sind (aber nicht wissen möchten, worin der Unterschied tatsächlich besteht), cmpist dies besser geeignet.

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

verwandte Informationen