Ответы:
Используйте <(command)
для передачи вывода одной команды другой программе, как если бы это было имя файла. Bash направляет вывод программы в канал и передает имя файла подобно /dev/fd/63
внешней команде.
diff <(./a) <(./b)
Точно так же вы можете использовать, >(command)
если вы хотите передать что-то в команду.
На справочной странице Bash это называется «Замена процесса».
-bash: syntax error near unexpected token ('
. Я попробовал еще раз без скобок и получил -bash: java: No such file or directory
. Не работает ли команда с параметрами?
alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\'
. (Тогда для, например: diffcmd "ls" "ls -a").
fseek
, zsh предлагает то же самое, что и =(./a)
для него, <(./a)
но использует временный файл под капотом, который zsh удалит для вас.)
Добавляя к обоим ответам, если вы хотите увидеть параллельное сравнение, используйте vimdiff
:
vimdiff <(./a) <(./b)
Что-то вроде этого:
vimdiff
создает красивые, умные и интерактивные представления сравнения различий. Похоже, поставляется с vim
пакетом на большинстве систем.
vimdiff
также показывает не только строку, которая отличается, но и конкретный фрагмент текста, который отличается.
Одним из вариантов будет использование именованных каналов (FIFO) :
mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo
... но решение Джона Кугельмана намного чище.
rm a_fifo b_fifo
.
Для всех, кто интересуется, это, как вы выполняете процесс подстановки при использовании оболочки Fish :
Bash:
diff <(./a) <(./b)
Рыбы:
diff (./a | psub) (./b | psub)
К сожалению, реализация в рыбе в настоящее время недостаточна ; рыба будет зависать или использовать временный файл на диске. Вы также не можете использовать psub для вывода из вашей команды.
Добавив немного больше к уже хорошим ответам (помогло мне!):
Команда docker
выводит свою справку STD_ERR
(т.е. файловый дескриптор 2)
Я хотел увидеть, если docker attach
и docker attach --help
дал тот же вывод
$ docker attach
$ docker attach --help
Просто набрав эти две команды, я сделал следующее:
$ diff <(!-2 2>&1) <(!! 2>&1)
!! то же самое, что! -1, что означает запуск команды 1 перед этой - последней командой
! -2 означает запустить команду два до этого
2> & 1 означает отправку вывода file_descriptor 2 (STD_ERR) в то же место, что и вывод file_descriptor 1 (STD_OUT)
Надеюсь, что это было полезно.
Для zsh использование =(command)
автоматически создает временный файл и заменяет =(command)
путь к самому файлу. При нормальной $(command)
замене процесса заменяется выводом команды.
Эта функция zsh очень полезна и может использоваться для сравнения выходных данных двух команд с использованием инструмента сравнения, например Beyond Compare:
bcomp =(ulimit -Sa | sort) =(ulimit -Ha | sort)
Для Beyond Compare обратите внимание, что вы должны использовать bcomp
вышеперечисленное (вместо bcompare
), поскольку bcomp
запускает сравнение и ожидает его завершения. Если вы используетеbcompare
, это запускает сравнение и сразу же завершает работу, из-за чего временные файлы, созданные для хранения вывода команд, исчезают.
Узнайте больше здесь: http://zsh.sourceforge.net/Intro/intro_7.html
Также обратите внимание на это:
Обратите внимание, что оболочка создает временный файл и удаляет его после завершения команды.
и следующее, в котором разница между $(...)
и =(...)
:
Если вы прочитаете справочную страницу zsh, вы можете заметить, что <(...) - это другая форма подстановки процесса, аналогичная = (...). Между ними есть важное различие. В случае <(...) оболочка создает именованный канал (FIFO) вместо файла. Это лучше, так как не заполняет файловую систему; но это работает не во всех случаях. Фактически, если бы мы заменили = (...) на <(...) в приведенных выше примерах, все они перестали бы работать, кроме fgrep -f <(...). Вы не можете редактировать канал или открывать его как почтовую папку; Однако у fgrep нет проблем с чтением списка слов из канала. Вы можете спросить, почему не работает diff <(foo), так как foo | diff - барные работы; это связано с тем, что diff создает временный файл, если он замечает, что одним из его аргументов является -, а затем копирует свой стандартный ввод во временный файл.