Как сохранить вывод от команды (например, разность) в переменную

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

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 непосредственно в переменную?

24
задан 13 August 2011 в 06:07

4 ответа

- это работает:

if diff "./helloworld$x.out" "./output/helloworld$x.out" >/dev/null; then
    echo "Passed $x";
else
    echo "Failed $x";
fi

Если вы используете переменную вместо echo, вы можете сбросить ветвь или : установите переменную в false перед if и сохраните 2 строки кода.

Если вы хотите использовать результат в переменной:

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

Включая мой тест, чтобы проверить, работает ли он на самом деле:

rinzwind@discworld:~$ touch 1
rinzwind@discworld:~$ touch 2
rinzwind@discworld:~$ more test
if diff 1 2 >/dev/null; then
    echo "Passed $x";
else
    echo "Failed $x";
fi
rinzwind@discworld:~$ ./test
Passed 

rinzwind@discworld:~$ vi 2
rinzwind@discworld:~$ more 2
2
rinzwind@discworld:~$ ./test
Failed 

В части >/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
19
ответ дан 23 November 2019 в 01:40

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" 

Чтобы прочитать об использовании && и || ищите "shortcut AND and shortcut OR".

Чтобы сохранить вывод чистым, вы можете перенаправить вывод '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
6
ответ дан 23 November 2019 в 01:40

diff может даже полностью подавить вывод, за исключением сообщения "Files /bin/bash and /bin/sh different", используя код ниже.

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" ].

17
ответ дан 23 November 2019 в 01:40

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

if cmp -s file1 file2; then echo "Equal"; else echo "Not equal"; fi
3
ответ дан 23 November 2019 в 01:40

Другие вопросы по тегам:

Похожие вопросы: