Команда sed
выполняется асинхронно из остальной части оболочки; его выход переходит в стандартную ошибку, как только он обрабатывает свой вход из команд в подстановке команд. Однако стандартный вывод этих команд записывается в $var
и не отображается до тех пор, пока не запустится команда echo
.
Даже если вы не захватывали вывод, есть шанс стандартная ошибка и стандартный вывод из этих команд не будет появляться, как вы ожидаете, потому что sed
команды, которая в конечном счете производит сообщения об ошибках не может быть запланированное ОС, когда вы ожидаете, что это будет, задерживая появление сообщений об ошибках.
Когда вы запускаете команду обычным способом с терминала, стандартная ошибка этой команды и стандартная выходная точка указывают на тот же файл: сам терминал. Таким образом, запись в файл поддерживает порядок, в котором они происходят в программе. Как только вы подключаете один или другой к другому процессу, вы теряете контроль над тем, как эти два сплайсируются вместе, если когда-либо. В вашем случае вы перенаправляете стандартную ошибку на sed
, которая записывает измененные строки обратно в стандартный вывод. Но у вас нет контроля над тем, когда ОС запускает sed
для запуска и когда ваша оболочка работает, поэтому вы не можете контролировать порядок написания строк.
Это помогает перенаправить стандартную ошибку отдельно для каждой команды:
tag_error() { sed 's/^/ERROR= /'; }
hostname 2> >(tag_error)
{ ifconfig | wc -l ; } 2> >(tag_error)
# etc
, но это еще не гарантия того, что пишет из той же программы, упорядочены, как если бы они были все записи в тот же файл.
(ruakh has covered, как совместить это с захватом стандартный вывод, так что я не буду беспокоить, добавив его сейчас. Посмотрите на его ответ.)
поэтому вопрос остается нерешенным, как сделать это? – avg598
Вы не можете; маркеров нет, чтобы указать, какие строки идут от 'sed', а строки в' $ var' соответствуют каждой отдельной команде в подстановке команд. Относительный вывод объединяется только в «обычный» случай, потому что stdout каждого процесса и stderr - это тот же самый дескриптор файла. – chepner
Все, что я хотел сделать, это отметить строки, которые нужно идентифицировать из stdout и которые находятся в stderr и в то же время сохраняют порядок. Есть ли другой способ сделать это? – avg598