Временно перенаправить STDOUT в другой файловый дескриптор, но все равно на экран
Я делаю сценарий, который выполняет некоторые команды внутри, и эти команды показывают некоторые выходные данные на STDOUT
(а также STDERR
как хорошо, но это не проблема). Мне нужно, чтобы мой скрипт генерировал файл.tar.gz для STDOUT
поэтому вывод некоторых команд, выполняемых в скрипте, также STDOUT
и это заканчивается неверным файлом.tar.gz в выходных данных.
Итак, короче говоря, можно вывести первые команды на экран (как я все еще хочу увидеть вывод), но не через STDOUT
? Также я хотел бы сохранить STDERR
нетронутым, поэтому там появляются только сообщения об ошибках.
Простой пример того, что я имею в виду. Это будет мой сценарий:
#!/bin/bash
# the output of these commands shouldn't go to STDOUT, but still appear on screen
some_cmd foo bar
other_cmd baz
#the following command creates a tar.gz of the "whatever" folder,
#and outputs the result to STDOUT
tar zc whatever/
Я пытался возиться с exec
и дескрипторы файлов, но я все еще не могу заставить его работать:
#!/bin/bash
# save STDOUT to #3
exec 3>&1
# the output of these commands should go to #3 and screen, but not STDOUT
some_cmd foo bar
other_cmd baz
# restore STDOUT
exec 1>&3
# the output of this command should be the only one that goes to STDOUT
tar zc whatever/
Я думаю, мне не хватает закрытия STDOUT
после первого запуска и снова открыть его или что-то, но я не могу найти правильный способ сделать это (сейчас результат такой же, как если бы я не добавил exec
s
3 ответа
Стандартный вывод - это экран. Нет разделения между стандартным выводом и "экраном".
В этом случае я бы просто перенаправил stdout на stderr временно с 1>&2
в недрах. Это приведет к тому, что вывод команд будет показан на экране, но не будет в потоке вывода программ.
#!/bin/bash
# the output of these commands shouldn't go to STDOUT, but still appear on screen
# Start a subshell
(
1>&2 # Redirect stdout to stderr
some_cmd foo bar
other_cmd baz
)
# At the end of the subshell, the file descriptors are
# as they usually are (no redirection) as the subshell has exited.
#the following command creates a tar.gz of the "whatever" folder,
#and outputs the result to STDOUT
tar zc whatever/
Есть ли причина, по которой вам нужно направить вывод этого скрипта во что-то еще? Обычно вы просто записываете tar в файл, используя -f
пометить или выполнить перенаправление только для команды tar: tar zc whatever > filename.tar.gz
(если вы не поместили его на устройство, такое как лента, или не использовали его в качестве копии).
Не было бы намного проще, если бы вы использовали -f
переключиться на команду tar, чтобы сказать tar записывать в файл?
tar zcf whatever.tar.gz whatever/
Если это не делает то, что вы хотите, вам придется перенаправить каждую команду, которая может писать в STDOUT.
some_cmd foo bar 1>&2
Я думаю, что вы ищете какое-то мультиплексирование.
Это простой пример того, как добавить метку времени к каждой строке стандартного вывода: http://www.podciborski.co.uk/programming/perl/add-a-timestamp-to-every-stdout-line/
Вы можете использовать какой-то специальный тег вместо метки времени, чтобы отметить строки журнала. Чем вам придется удалить эти строки на другом конце. Таким образом, использование будет таким:
ssh user@remoteserver the_script.sh | create_tar.sh filename
create_tar.sh должен быть скриптом, который печатает строки с тегом log и перенаправляет другие строки в файл.