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

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

Я хочу проверить, есть ли какой-либо вывод из 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напрямую в переменную?

решение1

Это работает:

если diff "./helloworld$x.out" "./output/helloworld$x.out" >/dev/null; тогда
    echo "Пройдено $x";
еще
    echo "Ошибка $x";
фи

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

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

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

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

rinzwind@discworld:~$ коснуться 1
rinzwind@discworld:~$ касание 2
rinzwind@discworld:~$ еще тест
если разница 1 2 >/dev/null; тогда
    echo "Пройдено $x";
еще
    echo "Ошибка $x";
фи
rinzwind@discworld:~$ ./тест
Прошедший

rinzwind@discworld:~$ vi 2
rinzwind@discworld:~$ еще 2
2
rinzwind@discworld:~$ ./тест
Неуспешный

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

примечание: sdiffпокажет списки рядом diff:

сдифф 1 2
1 1
2 2
3 3
4 4
5 5
7 7
                                  > 8
9 9
10 10

решение2

diffможно даже полностью подавить вывод, за исключением сообщения «Файлы /bin/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 == "" ]]

[ -n "$output" ]Если вы используете Bash, для сравнения строк рекомендуются последние две команды. В противном случае рекомендуется первая и .

решение3

а) Вывод команды command1 можно перехватить с помощью

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

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

 output=`cmd1`

б) Вместо записи в файл, а затем чтения этого файла (или захвата вывода и его последующего отображения) вы бы использовали канал напрямую:

 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

решение4

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

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

Связанный контент