Як зберегти вихід з команди (наприклад, diff) у змінну


21

Я хочу перевірити, чи є вихід з diff(тест, якщо файли однакові), якщо вони відсутні echo "Passed $x" else echo "Failed $x". Я придумав деякий проміжний крок (збережіть висновок з diff у файл, а потім прочитайте з файлу)

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;

Я впевнений, що код можна вдосконалити? Головне питання: чи можна зберегти вихід diffбезпосередньо з змінної?

Відповіді:


18

Це працює:

якщо відрізняється "./helloworld$x.out" "./output/helloworld$x.out"> / dev / null; потім
    ехо "Пройдено $ x";
ще
    ехо "Не вдалося $ x";
фі

Якщо ви використовуєте змінну замість echoвас, ви можете скинути elseрозгалуження: встановіть змінну значення false перед ifі збережіть 2 рядки коду.

Якщо ви хочете фактично поставити результат у змінне використання:

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

Включаючи мій тест, щоб перевірити, чи справді він працює:

rinzwind @ discworld: ~ $ touch 1
rinzwind @ discworld: ~ $ touch 2
rinzwind @ discworld: ~ $ ще тест
if diff 1 2> / dev / null; потім
    ехо "Пройдено $ x";
ще
    ехо "Не вдалося $ x";
фі
rinzwind @ discworld: ~ $ ./test
Пройшов 

rinzwind @ discworld: ~ $ vi 2
rinzwind @ discworld: ~ $ більше 2
2
rinzwind @ discworld: ~ $ ./test
Не вдалося 

З >/dev/nullбоку: >/dev/null 2>&1надішле висновок >/dev/nullі 2>&1 відправить стандартні помилки в той самий файл ( &1означає «використовувати перший параметр») перед цією командою (тому він також використовує /dev/null).

sidenote: sdiffпоказуватиме бічні diffсписки:

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

Спасибі це працює, але я не розумію, що ... > /dev/nullробиться в цьому контексті. Вихід diff буде goto / dev / null, але хіба нічого?
Jiew Meng

1
Розмір видасть усі відмінності між файлами на екрані та> / dev / null гарантує, що вихід команди буде перенаправлений на забуття. If все ще виконується на основі результату.
Rinzwind

1
Оператор if перевіряє код виходу команди diff. 0 означає, що ніяких відмінностей не знайдено, тоді як 1 означає, що була одна чи більше відмінностей.
Кнут Елдхусет

17

diff навіть може повністю придушити вихід, за винятком повідомлення "Файли / бін / bash та / bin / sh відрізняються", використовуючи наведений нижче код.

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

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

Якщо ви навіть хочете приховати це повідомлення, вам слід додати > /dev/nullпісля команди diff, щоб приховати вихід diff:

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

/dev/null це спеціальний файл, який виконує функцію чорного отвору, якщо ви напишете до нього, він не зникне, якщо читати з нього, ви нічого не отримаєте.

Зауважте, що bash не потрібно ;закінчувати рядки.

Що стосується початкового запитання, щоб зберегти вихід програми в змінній:

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

Альтернативні способи перевірити чи порожня змінна:

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

Якщо ви використовуєте Bash, останні дві команди рекомендуються для порівняння рядків. В іншому випадку перший і [ -n "$output" ]рекомендується.


6

a) Вихід команди1 може бути вичерпаний

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

або із задніми посиланнями, але вони відбиваються, тому що ви не можете їх вкладати, і їх може бути важко відрізнити від апострофів, залежно від шрифту:

 output=`cmd1`

b) Замість того, щоб записати у файл, а потім прочитати цей файл (або захопити висновок, а потім повторити його), ви б використали трубу безпосередньо:

 cmd1 > file
 cat file | cmd2 

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

=>

 cmd1 | cmd2 

але у вашому прикладі вас цікавить не результат, а результат програми - це спрацювало?

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

Прочитати про використання && та || пошук "ярлика І та ярлика АБО".

Щоб зберегти вихід чистим, ви можете перенаправити вихід 'diff' нікуди:

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

Щоб схопити успіх і оцінити його пізніше, ви зберігаєте результат останньої команди у змінній з $ ?:

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

3

Якщо ви хочете знати, чи два файли однакові чи відрізняються (але байдуже, у чому різниця насправді), cmpпідходить більше.

if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.