Вопрос Как мне отличить вывод двух команд?


Я предположил, что самый простой способ сравнить содержимое двух подобных каталогов - это что-то вроде

diff `ls old` `ls new`

Но я понимаю, почему это не работает; diff передается большой длинный список файлов в командной строке, а не два потока, как я надеялся. Как передать два выхода на diff напрямую?


133
2017-12-15 22:01


происхождения


Связанный: Как я могу сравнить вывод двух команд unix, чтобы найти разницу?, Diff вывод из двух программ без временных файлов - kenorb


ответы:


Замена команд `…` заменяет вывод команды в командной строке, поэтому diff видит список файлов в обоих каталогах как аргументы. Что вы хотите для diff чтобы увидеть два имени файла в командной строке и содержимое этих файлов будет списком каталогов. Это то что замена процесса делает.

diff <(ls old) <(ls new)

Аргументы в diff будет выглядеть /dev/fd/3 а также /dev/fd/4: это файловые дескрипторы, соответствующие двум каналам, созданным bash. когда diff открывает эти файлы, он будет подключен к считываемой стороне каждого канала. Сторона записи каждой трубы подключается к ls команда.


194
2017-12-15 22:06



echo <(echo) <(echo) никогда не думал, что это может быть так интересно: D - Aquarius Power
Замена процесса не поддерживается всеми оболочками, но переадресация каналов - это аккуратное обходное решение, - Irfan434
Просто отметим, что разбор ls не рекомендуется unix.stackexchange.com/questions/128985/why-not-parse-ls - Katu
@Katu Проблема с ls заключается в том, что он искажает имена файлов. Анализ его вывода является хрупким (он не работает с «странными» именами файлов). Для сравнения двух списков каталогов это нормально, пока вывод однозначен. При использовании произвольных имен файлов для этого потребуется такая опция, как --quoting-style=escape, - Gilles


Рыбий жир

В рыбной раковине вы должны psub, Вот пример сопоставления конфигурации heroku и dokku с Вне всякого сравнения:

bcompare (ssh me@myapp.pl dokku config myapp | sort | psub) (heroku config -a myapp | sort | psub)

2
2018-04-12 07:34



Другой графический инструмент meld который является открытым исходным кодом и доступен в репозиториях Ubuntu и EPEL. meldmerge.org - phiphi


Для zsh, используя =(command) автоматически создает временный файл и заменяет =(command) с путём самого файла. С помощью Command Substitution, $(command) заменяется на вывод команды.

Таким образом, существует три варианта:

  1. Замена команды: $(...) 
  2. Замена процесса: <(...)
  3. zsh-Flavored Замена процесса: =(...)

zsh, 3-го, очень полезно и может использоваться так, чтобы сравнить вывод двух команд с помощью инструмента diff, например Beyond Compare:

bcomp  =(ulimit -Sa | sort) =(ulimit -Ha | sort)

Для Beyond Compare обратите внимание, что вы должны использовать bcomp для вышеизложенного (вместо bcompare) поскольку bcomp запускает сравнение и ждет для его завершения. Если вы используете bcompare, который запускает сравнение и сразу же выходит из-за того, что временные файлы, созданные для хранения вывода команд, исчезают.

Подробнее здесь: http://zsh.sourceforge.net/Intro/intro_7.html

Также обратите внимание на это:

Обратите внимание, что оболочка создает временный файл и удаляет его, когда команда завершена.

и следующее, которое представляет собой разницу между двумя типами замещения процесса, поддерживаемыми zsh (i.e # 2 и # 3):

Если вы читаете man-страницу zsh, вы можете заметить, что <(...) - это еще одна форма замещения процесса, которая похожа на = (...). Между ними существует важное различие. В случае <(...) оболочка создает именованный канал (FIFO) вместо файла. Это лучше, так как он не заполняет файловую систему; но он не работает во всех случаях. Фактически, если бы мы заменили = (...) на <(...) в приведенных выше примерах, все они перестали работать, кроме fgrep -f <(...). Вы не можете отредактировать канал или открыть его как почтовую папку; Однако fgrep не имеет проблем с чтением списка слов из трубы. Вы можете задаться вопросом, почему diff <(foo) bar не работает, поскольку foo | diff-bar работает; это потому, что diff создает временный файл, если он замечает, что один из его аргументов -, а затем копирует свой стандартный ввод во временный файл.

Справка: https://unix.stackexchange.com/questions/393349/difference-between-subshells-and-process-substitution


2
2018-06-29 08:59



$(...) это не замена процесса, это команда замена. <(...) является замещением процесса. Вот почему цитируемый отрывок не упоминает $(...) вообще. - muru