Вывод перенаправления от всех команд до файла, не просто в последний раз

Для GNU gzip 1.6 или выше, FreeBSD и производные или последние версии NetBSD, см. ответ don_cristi.

С любой версией можно использовать перенаправления оболочки в качестве в:

gzip < file > file.gz

При отсутствии предоставления аргумента, gzip читает его стандартный вход, сжимает его и пишет сжатую версию в его стандартный вывод. В качестве награды, при использовании перенаправлений оболочки, Вы не должны волноваться о названных файлах "--help" или "-" (что последний, все еще являющийся проблемой для gzip -c --).

Другое преимущество gzip -c file > file.gz это если file не может быть открыт, команда перестанет работать, не создавая пустое file.gz (или перезапись существующего file.gz) и без выполнения gzip вообще.

Значительная разница по сравнению с gzip -k хотя то, что не будет никакой попытки копирования fileметаданные (владение, полномочия, время изменения, название несжатого файла) к file.gz.

Также, если file.gz уже существовал, это тихо переопределит его, если Вы не повернулись noclobber опция на в Вашей оболочке (с set -o noclobber например, в оболочках POSIX).

11
28.11.2013, 01:03
3 ответа

Проблемой здесь не является проблема с перенаправлением Linux; скорее это - фундаментальное неверное толкование того, как конвейер работает. Перенаправление здесь не работает, потому что только сокращенный на самом деле печатает к stdout. stdout для команды эха, был передан по каналу к stdin сокращения (который не используется в этом случае, так как файл указан).

echo "header line" > output_file && cut -c 1-5 input_file >> output_file

то, что Вы хотите, и весьма изящный вообще (я заменил Ваш ; с && так, чтобы команда сокращения только выполнилась, если заголовок будет успешно записан; этим путем это не выполнится, если у Вас не будет полномочий создать или записать в output_file).

Вы могли также сделать все это в подоболочке, например.

(echo "header line"; cut -c 1-5 input_file) > output_file

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

Если Вы хотите, чтобы сокращение передало stdin до stdout, Вы могли бы попробовать:

echo "header line" | cut -c 1-5 - input_file

(Тире является общим ярлыком для stdin),

Однако это также выполнит операцию сокращения на stdin (приводящий к строке заголовка "заголовка"). Трудно сказать, является ли это тем, что Вы хотите или не от вопроса.

11
27.01.2020, 19:57

Только для закругления ответов существует должностное лицо.

exec > output_file
echo "header line"
cut -c 1-5 input_file
4
27.01.2020, 19:57
  • 1
    +1: в сценариях очень распространено использовать это (меньше на командной строке, поскольку вещи начинают получать запутывающий ^^), –  Olivier Dulac 27.11.2013, 19:38
  • 2
    Кто-то мог уточнить это решение? Я вижу то, что это делает, но я не понимаю 'должностное лицо' в этом контексте. Кроме того, это похоже на что-то, что необходимо выключить снова, если остальной части сценария нужен нормальный stdout. –  Joe 30.11.2013, 10:53
  • 3
    при использовании должностного лица в сценарии без команды можно сделать перенаправление ввода-вывода на должностном лице, которое влияет на текущую оболочку и всех будущих детей. –  hildred 30.11.2013, 10:57
  • 4
    Спасибо. Я не видел это прежде. Я думаю, что это будет очень полезно. –  Joe 03.12.2013, 23:20

То, что Вы ищете:

{ echo "header line"; cut -c 1-5 input_file; } > output_file
  • Этот синтаксис не имеет никаких побочных эффектов, поскольку команды выполняются в текущей оболочке, не подоболочке
  • Существует четкое определение границ команд, которые переходят к output_file
  • Это масштабируется хорошо, поскольку можно переписать его тот путь:

{
  echo "header line"
  cut -c 1-5 input_file
  ... # insert new commands here
} > output_file

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

} > output_file 2>&1

Благодаря Olivier Dulac для напоминания той подсказке.

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

{
  echo "header line"
  echo "this line doesn't go to output_file" > /dev/tty
  cut -c 1-5 input_file
} > output_file
13
27.01.2020, 19:57
  • 1
    +1: это более ясно и ясно определяет то, что перенаправляется где. Перенаправить все (включая сообщение об ошибке): { .... } > some_file 2>&1 ("ударит" some_file. чтобы не ударить, но добавить к нему вместо этого, просто изменитесь > в a >>: { ... } >> some_file 2>&1) –  Olivier Dulac 27.11.2013, 19:35

Теги

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