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

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

diff `ls old` `ls new`

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

170
задан 16 December 2012 в 02:01

4 ответа

Рыбья ракушка

В Рыбной ракушке вы должны попасть в псаб . Вот пример сравнения конфигурации heroku и dokku с Beyond Compare :

bcompare (ssh me@myapp.pl dokku config myapp | sort | psub) (heroku config -a myapp | sort | psub)
0
ответ дан 16 December 2012 в 02:01

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

diff <(ls old) <(ls new)

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

0
ответ дан 16 December 2012 в 02:01

Для zsh использование =(command) автоматически создает временный файл и заменяет =(command) на путь к самому файлу. При подстановке команд $(command) заменяется выходом команды .

Итак, есть три варианта:

  1. Подстановка команд: $(...)
  2. Подстановка процессов: <(...)
  3. Подстановка процессов со вкусом zsh: =(...)

Подстановка процессов с добавлением zsh, # 3, очень полезна и может использоваться, например, для сравнения результатов двух команд с использованием инструмента сравнения, например, Beyond Compare:

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

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

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

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

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

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

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

Ссылка: https://unix.stackexchange.com/questions/393349/difference-between-subshells-and-process-substitution

0
ответ дан 16 December 2012 в 02:01

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

diff <(ls old) <(ls new)

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

я нахожу, что 99% времени испытываю соответствующие команды прежде, чем работать различный. Следовательно, команды, которые я хочу к разности, находятся тут же в моей истории..., почему бы не использовать их?

я использую Команду Фиксации (ФК) удар, встроенный для выполнения последних двух команд:

$ echo A
A
$ echo B
B
$ diff --color <( $(fc -ln -1 -1) ) <( $(fc -ln -2 -2 ) )
1c1
< B
---
> A

флаги ФК:

-n: Никакое число. Это подавляет числа команды при списке.

-l: Список: команды перечислены на стандартном выводе.

-1 -1 относятся к запуску и установке конца в истории, в этом случае от последней команды до последней команды, которая приводит просто к последней команде.

Наконец мы переносим это в $() для выполнения команды в подоболочке.

, Очевидно, это - что-то вроде боли для ввода так, мы можем создать псевдоним:

alias dl='diff --color <( $(fc -ln -1 -1) ) <( $(fc -ln -2 -2 ) )'

Или мы можем создать функцию:

dl() {
    if [[ -z "$1" ]]; then
        first="1"
    else
        first="$1"
    fi
    if [[ -z "$2" ]]; then
        last="2"
    else
        last="$2"
    fi
    # shellcheck disable=SC2091
    diff --color <( $(fc -ln "-$first" "-$first") ) <( $(fc -ln "-$last" "-$last") )
}

, который поддерживает определение строк истории для использования. После использования обоих я нахожу, что псевдоним является версией, которую я предпочитаю.

0
ответ дан 16 October 2019 в 13:08

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

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