Как различить файл и вывод команды?

32

Обычно вы пишете:

diff file1 file2

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

diff file1 <(cat file2 | sort)

Хорошо, это работает, когда я ввожу это вручную в приглашении оболочки, но когда я помещаю точно такую ​​же строку в сценарий оболочки, а затем запускаю сценарий, я получаю ошибку

Итак, вопрос - как это сделать правильно?

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

greenoldman
источник

Ответы:

39

Я подозреваю, что ваш скрипт и ваша оболочка разные. Возможно, у вас есть #!/bin/shверхняя часть вашего скрипта в качестве переводчика, но вы используете его bashкак личную оболочку. Вы можете узнать, какую оболочку вы запускаете в терминале, запустив echo $SHELL.

Более простой способ сделать это, который должен работать в большинстве оболочек, - это использовать перенаправление канала вместо оператора чтения файла, который вы даете. Символ «-» является стандартной номенклатурой для чтения STDIN и часто может использоваться в качестве замены имени файла в списке аргументов:

cat file2 | sort | diff file1 -

Или чтобы избежать бесполезного использования кошки :

sort < file2 | diff file1 -
Калеб
источник
Ах, вы хороши, действительно, я не проверял, ш это Баш или нет. Большое спасибо за решение.
Гринольдман
Это файл сравнения с stdout. Теперь, как изменить стандартный вывод с помощью файла? Я имею в виду противоположное направление. это -Rв случае использованияgit diff --no-index
Накилон
@Nakilon Вы бы просто изменить порядок аргументов: diff - file1.
Калеб
Круто. Это не сработало git diff.
Накилон
@Nakilon Конечно нет, с чего бы это? git diffэто совершенно другой зверь, который работает со ссылками на объекты глобуса в своем внутреннем индексе, а не на файлы; diffработает в файловой системе. -Синтаксис просто оболочки синтаксического сахара для /dev/stdin, файла , представляющего поток STDIN. Следовательно, почему diffможно использовать его как замену имени файла. Между тем git diffне ищет файлы, он ищет объекты, поэтому вы должны передать ему то, что он распознает. Не используйте его для сравнения файлов друг с другом, используйте diffдля этого.
Калеб
-4

Сфера стандартного ввода - это сам скрипт, поэтому просто поместите свой код в блок, например:

{
  diff file1 <(sort file2)
}

Таким образом, область действия STDIN находится внутри блока.

Я пытался, и это работает.

tmow
источник
Это не функция, это блок, и это не имеет никакого значения.
Жиль "ТАК - перестань быть злым"
@ Gilles Спасибо за исправление. Кстати, я попробовал себя, и это работает. А вы?
tmow
3
Блок не влияет на достоверность <(…)конструкции. Ваш скрипт будет работать или не работать в зависимости от того, запускаете ли вы его в поддерживаемой оболочке <(…)или нет (ksh93 / bash / zsh против Bourne / ash / kshk88). Ответ Калеба прибивает все это.
Жиль "ТАК - перестань быть злым"
1
@ Жиль хорошо, спасибо за объяснение.
tmow