При использовании nohup для запуска команды в фоновом режиме часть содержимого отображается в терминале.
cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error
Я хочу сохранить это содержимое в файл.
В Linux (и других операционных системах) есть два основных потока вывода, стандартный вывод (stdout) и стандартная ошибка (stderr). Сообщения об ошибках, как и те, которые вы показываете, выводятся на стандартную ошибку. Классический оператор перенаправления (command > file
) перенаправляет только стандартный вывод, поэтому стандартная ошибка по-прежнему отображается на терминале. Для перенаправления stderr также есть несколько вариантов:
Перенаправить stdout в один файл и stderr в другой файл:
команда > из 2>error
Перенаправьте stdout в файл (>out
), а затем перенаправьте stderr в stdout (2>&1
):
команда >out 2>&1
Перенаправьте оба в файл (это поддерживается не всеми оболочками, например, bash
и zsh
, но sh
и ksh
не поддерживаются):
команда &> наружу
Более подробную информацию о различных операторах управления и перенаправления смотрите здесь .
Первое, что следует отметить, это то, что есть несколько способов в зависимости от вашей цели и оболочки, поэтому это требует небольшого понимания множества аспектов. Кроме того, некоторые команды, такие как time
и strace
, по умолчанию записывают вывод в stderr и могут предоставлять или не предоставлять метод перенаправления, специфичный для этой команды
. Основная теория перенаправления - это что процесс, порожденный оболочкой (при условии, что это внешняя команда, а не встроенная оболочка) создается с помощью системных вызовов fork ()
и execve ()
, а до этого происходит еще один системный вызов dup2 ()
выполняет необходимые перенаправления перед execve ()
бывает. В этом смысле перенаправления наследуются от родительской оболочки. m &> n
и m> n.txt
информируют оболочку о том, как выполнять open ()
и dup2 ()
syscall ( см. также Как работает перенаправление ввода , В чем разница между перенаправлением и конвейером и Что означает & в точности в перенаправлении вывода )
Наиболее типично, через 2>
в Bourne-подобных оболочках , например dash
(с символической ссылкой на / bin / sh
]) и bash
; первая - это оболочка по умолчанию, совместимая с POSIX, а вторая - то, что большинство пользователей используют для интерактивного сеанса. Они различаются по синтаксису и функциям, но, к счастью, перенаправление потока ошибок работает одинаково (кроме нестандартного &>
). В случае csh и его производных перенаправление stderr там не совсем работает.
Давайте вернемся к части 2>
. Обратите внимание на два ключевых момента: >
означает оператор перенаправления, при котором мы открываем файл, а целое число 2
означает дескриптор файла stderr; фактически именно так стандарт POSIX для языка оболочки определяет перенаправление в разделе 2.7 :
[n]redir-op word
Для простого перенаправления >
целое число 1
подразумевается для stdout
, т.е. echo Hello World> / dev / null
- это то же самое, что echo Hello World 1> / dev / null
. Обратите внимание, что целочисленный оператор или оператор перенаправления не могут быть заключены в кавычки, иначе оболочка не распознает их как таковые и вместо этого рассматривает их как буквальную строку текста. Что касается интервала, важно, чтобы целое число было рядом с оператором перенаправления, но файл может быть либо рядом с оператором перенаправления, либо нет, то есть команда 2> / dev / null
и команда 2> / dev / null
будет работать нормально.
Несколько упрощенный синтаксис для типичной команды в оболочке будет выглядеть так:
command [arg1] [arg2] 2> /dev/null
Уловка здесь в том, что перенаправление может появляться где угодно. То есть действительны как 2> команда [arg1]
, так и команда 2> [arg1]
. Обратите внимание, что для оболочки bash
существует &>
способ перенаправить потоки stdout и stderr одновременно, но опять же - он специфичен для bash, и если вы стремитесь к переносимости скриптов это может не сработать. См. Также Ubuntu Wiki и В чем разница между &> и 2> & 1 .
Примечание: Оператор перенаправления >
обрезает файл и перезаписывает его, если файл существует. 2 >>
может использоваться для добавления stderr
в файл.
Если вы заметили, >
предназначен для одной единственной команды. Для сценариев мы можем перенаправить поток stderr всего сценария извне, как в myscript.sh 2> / dev / null
, или мы можем использовать встроенный exec . Встроенный exec имеет возможность перенаправить поток для всего сеанса оболочки, так сказать, интерактивно или через скрипт. Что-то вроде
#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file
В этом примере файл журнала должен показывать stat: cannot stat '/ etc / non_existing_file': Нет такого файла или каталога
.
Еще один способ - через функции. Как отметил в своем ответе kopciuszek , мы можем написать объявление функции с уже прикрепленным перенаправлением, то есть
some_function(){
command1
command2
} 2> my_log_file.txt
Команды, такие как time
и strace
по умолчанию записывает свой вывод в stderr. В случае команды time
единственной жизнеспособной альтернативой является перенаправление вывода всей команды, то есть
time echo foo 2>&1 > file.txt
. В качестве альтернативы синхронный список или подоболочка могут быть перенаправлены, если вы хотите разделить вывод (как показано в связанное сообщение ):
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
Другие команды, такие как strace
или dialog
, предоставляют средства для перенаправления stderr. strace
имеет параметр -o
, который позволяет указать имя файла, в которое должен быть записан вывод. Также существует опция для записи текстового файла для каждого подпроцесса, который видит strace
. Команда dialog
записывает текстовый интерфейс пользователя в stdout, но выводит в stderr, поэтому, чтобы сохранить свой вывод в переменную (потому что var = $ (...)
, а конвейеры получают только stderr) нам нужно поменять местами дескрипторы файлов
result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
, но, кроме того, есть флаг - output-fd
, который мы также можем использовать. Также существует метод именованных каналов. Я рекомендую прочитать связанный пост о команде dialog
для подробного описания происходящего.