перенаправление stdout bash в цикле for - PullRequest
1 голос
/ 01 октября 2019

Возможный дубликат

Здравствуйте,

Я борюсь с перенаправлением вывода в цикле bash for. У меня есть несколько похожих скриптов bash, каждый из которых запускается в отдельном входном файле. Сценарии называются инструментом с несколькими аргументами.

Сценарии bash выглядят следующим образом:

my_tool --input input_file --arg1 arg1_name --arg2 arg2_name > output_dir/result_X.dat

X - строка, уникальная для каждого сценария.

Я запускаю их все в цикле for:

for script in scripts_dir/*.sh
do
    bash $script
done

Тем не менее, стандартный вывод каждого прогона по-прежнему отображается на терминале. Указанные выходные файлы созданы, но пусты. Как я могу решить это? Я нашел другие вопросы о stackoverflow, где ответом является перенаправление полного цикла в одном большом выходном файле, но я бы хотел этого избежать.

Если я заменим > output_dir/result_X.dat на > /dev/null: стандартвыходы отображаются на терминале

Если я заменим > output_dir/result_X.dat на `2> / dev / null: ничего не отобразится.

Заранее спасибо.

1 Ответ

2 голосов
/ 01 октября 2019

Когда вы запускаете my_tool, обычно в инструменте доступно 3 дескриптора файла:

  • STDIN
  • STDOUT
  • STDERR

STDIN используется для ввода, и, следовательно, не имеет значения для этого вопроса. STDOUT используется для стандартного вывода. Это дескриптор файла 1. Если вы выполните

ls 1> /dev/null

, STDOUT ls записывается в /dev/null. Если вы не добавите 1, как в ls > /dev/null, предполагается, что вы имеете в виду STDOUT.

STDERR используется в качестве стандартного вывода сообщений об ошибках в самом широком смысле этого слова. Число STDERR равно 2.

Если вместо my_command вместо *1023* использовать ls, листинг будет помещен в file. ls /non_existing_dir_ > file поместит STDOUT ls в file. Но на STDOUT нет вывода, и поскольку STDERR не перенаправляется, он будет отправлен на терминал.

Итак, в заключение,

ls . /non_existing_dir 2>stderr >stdout

поместит список каталогов . в файл stdout и ошибку для несуществующего каталога в stderr.

С помощью 2>&1 вы перенаправляете вывод filedescriptor2 (STDERR) в файловый дескриптор 1 (SDTOUT).

Чтобы немного усложнить ситуацию, вы можете добавить другие номера файловых дескрипторов. Например:

exec 3>file

поместит вывод файлового дескриптора 3 (который только что создан) в file. И

ls 1>&3

затем перенаправит вывод файлового дескриптора 1 в файловый дескриптор 3, фактически поместив вывод ls в file.

...