How to redirect output to a file and stdout
In bash, calling foo would display any output from that command on the stdout.
Calling foo > output would redirect any output from that command to the file specified (in this case ‘output’).
Is there a way to redirect output to a file and have it display on stdout?
10 Answers 10
The command you want is named tee :
For example, if you only care about stdout:
If you want to include stderr, do:
2>&1 redirects channel 2 (stderr/standard error) into channel 1 (stdout/standard output), such that both is written as stdout. It is also directed to the given output file as of the tee command.
2>&1 dumps the stderr and stdout streams. tee outfile takes the stream it gets and writes it to the screen and to the file «outfile».
This is probably what most people are looking for. The likely situation is some program or script is working hard for a long time and producing a lot of output. The user wants to check it periodically for progress, but also wants the output written to a file.
The problem (especially when mixing stdout and stderr streams) is that there is reliance on the streams being flushed by the program. If, for example, all the writes to stdout are not flushed, but all the writes to stderr are flushed, then they’ll end up out of chronological order in the output file and on the screen.
It’s also bad if the program only outputs 1 or 2 lines every few minutes to report progress. In such a case, if the output was not flushed by the program, the user wouldn’t even see any output on the screen for hours, because none of it would get pushed through the pipe for hours.
How to redirect and append both standard output and standard error to a file with Bash
To redirect standard output to a truncated file in Bash, I know to use:
To redirect standard output in Bash, appending to a file, I know to use:
To redirect both standard output and standard error to a truncated file, I know to use:
How do I redirect both standard output and standard error appending to a file? cmd &>> file.txt did not work for me.
8 Answers 8
Bash executes the redirects from left to right as follows:
There are two ways to do this, depending on your Bash version.
The classic and portable (Bash pre-4) way is:
A nonportable way, starting with Bash 4 is
(analog to &> outfile )
For good coding style, you should
If your script already starts with #!/bin/sh (no matter if intended or not), then the Bash 4 solution, and in general any Bash-specific code, is not the way to go.
Also remember that Bash 4 &>> is just shorter syntax — it does not introduce any new functionality or anything like that.
In Bash you can also explicitly specify your redirects to different files:
Appending would be:
In Bash 4 (as well as Z shell ( zsh ) 4.3.11):
This should work fine:
It will store all logs in file.txt as well as dump them in the terminal.
Your usage of &> x.file does work in Bash 4. Sorry for that: (
Here comes some additional tips.
0 stands for standard input, 1 stands for standard output, 2 stands for standard error. 3
9 is spare for any other temporary usage.
Any file descriptor can be redirected to other file descriptor or file by using operator > or >> (append).
Usage: >
If using older versions of Bash where &>> isn’t available, you also can do:
Also, the parentheses remove any ambiguity of order, especially if you want to pipe standard output and standard error to another command instead.
To avoid starting a subshell, you instead could use curly braces instead of parentheses to create a group command:
(Note that a semicolon (or newline) is required to terminate the group command.)
bash : Self redirect of Script’s output to a file
Lets take a use case. Imagine you are developing a script that will bring up some applications when a system reboots. When it is run from command line it works fine but when it is run during system startup, it misbehaves. How do you troubleshoot? First response is to use “-x” to print how the script is triggering. But what we want is that when our startup script runs, all of its output (both stdout and stderr) stored in a file that we could use for troubleshooting later. For redirecting output of a startup script we have to use a wrapper script to trigger it and use redirection operator to store its output which is simply a workaround. Or, use the magic word “exec“.
Using “exec 1>stdout.log 2>stderr.log” does the magic. Here stdout.log and stderr.log are example filenames that can be changed to one’s liking. I prefer redirecting all output to only one file. Do not use the same filename with both 1 and 2, output will jumble up depending on how shell is buffering and flushing the data to the file. Use this variant instead “exec 1>stdout.log 2>&1“. This will guarantee that all the output will be stored in the order it was produced.
Now lets go back to a working example to fix our init.d OR rc.d problem. Following is a sample script. Because /tmp/passwd does not exist (usually), the ls command shall fail sending output to stderr. Execution of each line as displayed by “-x” would also go to stderr (try using “exec >mylog.log 2>myerr.log” and see its behavior).
When run it will output following.
Per manpage of bash (from the Redirection section)
Note that the exec builtin command can make redirections take effect in the current shell.
Bash-скрипты, часть 4: ввод и вывод
В прошлый раз, в третьей части этой серии материалов по bash-скриптам, мы говорили о параметрах командной строки и ключах. Наша сегодняшняя тема — ввод, вывод, и всё, что с этим связано.
Вы уже знакомы с двумя методами работы с тем, что выводят сценарии командной строки:
Стандартные дескрипторы файлов
Всё в Linux — это файлы, в том числе — ввод и вывод. Операционная система идентифицирует файлы с использованием дескрипторов.
Каждому процессу позволено иметь до девяти открытых дескрипторов файлов. Оболочка bash резервирует первые три дескриптора с идентификаторами 0, 1 и 2. Вот что они означают.
STDIN
STDOUT
Итак, у нас есть некий файл с данными, к которому мы можем добавить другие данные с помощью этой команды:
Перенаправление вывода команды в файл
После выполнения этой команды мы увидим сообщения об ошибках на экране.
Попытка обращения к несуществующему файлу
При попытке обращения к несуществующему файлу генерируется ошибка, но оболочка не перенаправила сообщения об ошибках в файл, выведя их на экран. Но мы-то хотели, чтобы сообщения об ошибках попали в файл. Что делать? Ответ прост — воспользоваться третьим стандартным дескриптором.
STDERR
Итак, предположим, что надо перенаправить сообщения об ошибках, скажем, в лог-файл, или куда-нибудь ещё, вместо того, чтобы выводить их на экран.
▍Перенаправление потока ошибок
Как вы уже знаете, дескриптор файла STDERR — 2. Мы можем перенаправить ошибки, разместив этот дескриптор перед командой перенаправления:
Перенаправление сообщения об ошибке в файл
▍Перенаправление потоков ошибок и вывода
При написании сценариев командной строки может возникнуть ситуация, когда нужно организовать и перенаправление сообщений об ошибках, и перенаправление стандартного вывода. Для того, чтобы этого добиться, нужно использовать команды перенаправления для соответствующих дескрипторов с указанием файлов, куда должны попадать ошибки и стандартный вывод:
Перенаправление ошибок и стандартного вывода
Перенаправление STDERR и STDOUT в один и тот же файл
Перенаправление вывода в скриптах
Существует два метода перенаправления вывода в сценариях командной строки:
▍Временное перенаправление вывода
Если запустить скрипт, обе строки попадут на экран, так как, как вы уже знаете, по умолчанию ошибки выводятся туда же, куда и обычные данные.
Запустим скрипт так, чтобы вывод STDERR попадал в файл.
Как видно, теперь обычный вывод делается в консоль, а сообщения об ошибках попадают в файл.
Сообщения об ошибках записываются в файл
▍Постоянное перенаправление вывода
Если в скрипте нужно перенаправлять много выводимых на экран данных, добавлять соответствующую команду к каждому вызову echo неудобно. Вместо этого можно задать перенаправление вывода в определённый дескриптор на время выполнения скрипта, воспользовавшись командой exec :
Перенаправление всего вывода в файл
Команду exec можно использовать не только в начале скрипта, но и в других местах:
Вот что получится после запуска скрипта и просмотра файлов, в которые мы перенаправляли вывод.
Перенаправление вывода в разные файлы
Освоив это, вы сможете перенаправлять вывод туда, куда нужно. Теперь поговорим о перенаправлении ввода.
Перенаправление ввода в скриптах
Для перенаправления ввода можно воспользоваться той же методикой, которую мы применяли для перенаправления вывода. Например, команда exec позволяет сделать источником данных для STDIN какой-нибудь файл:
Вот что появится на экране после запуска скрипта.
Некоторые администраторы Linux используют этот подход для чтения и последующей обработки лог-файлов.
Создание собственного перенаправления вывода
Перенаправляя ввод и вывод в сценариях, вы не ограничены тремя стандартными дескрипторами файлов. Как уже говорилось, можно иметь до девяти открытых дескрипторов. Остальные шесть, с номерами от 3 до 8, можно использовать для перенаправления ввода или вывода. Любой из них можно назначить файлу и использовать в коде скрипта.
Назначить дескриптор для вывода данных можно, используя команду exec :
Перенаправление вывода, используя собственный дескриптор
Создание дескрипторов файлов для ввода данных
Перенаправить ввод в скрипте можно точно так же, как и вывод. Сохраните STDIN в другом дескрипторе, прежде чем перенаправлять ввод данных.
После окончания чтения файла можно восстановить STDIN и пользоваться им как обычно:
Закрытие дескрипторов файлов
После исполнения скрипта мы получим сообщение об ошибке.
Попытка обращения к закрытому дескриптору файла
Всё дело в том, что мы попытались обратиться к несуществующему дескриптору.
Будьте внимательны, закрывая дескрипторы файлов в сценариях. Если вы отправляли данные в файл, потом закрыли дескриптор, потом — открыли снова, оболочка заменит существующий файл новым. То есть всё то, что было записано в этот файл ранее, будет утеряно.
Получение сведений об открытых дескрипторах
У этой команды есть множество ключей, рассмотрим самые важные.
Вывод сведений об открытых дескрипторах
Посмотрим на вызов команды lsof из скрипта, в котором открыты, в дополнение к стандартным, другие дескрипторы:
Вот что получится, если этот скрипт запустить.
Просмотр дескрипторов файлов, открытых скриптом
Скрипт открыл два дескриптора для вывода ( 3 и 6 ) и один — для ввода ( 7 ). Тут же показаны и пути к файлам, использованных для настройки дескрипторов.
Подавление вывода
Вот, например, как подавить вывод сообщений об ошибках:
Тот же подход используется, если, например, надо очистить файл, не удаляя его:
Итоги
Сегодня вы узнали о том, как в сценариях командной строки работают ввод и вывод. Теперь вы умеете обращаться с дескрипторами файлов, создавать, просматривать и закрывать их, знаете о перенаправлении потоков ввода, вывода и ошибок. Всё это очень важно в деле разработки bash-скриптов.
В следующий раз поговорим о сигналах Linux, о том, как обрабатывать их в сценариях, о запуске заданий по расписанию и о фоновых задачах.
Уважаемые читатели! В этом материале даны основы работы с потоками ввода, вывода и ошибок. Уверены, среди вас есть профессионалы, которые могут рассказать обо всём этом то, что приходит лишь с опытом. Если так — передаём слово вам.
Bash redirect all output to file
Before a command is executed, its input and output may be redirected using a special notation interpreted by the shell. Redirection allows commands’ file handles to be duplicated, opened, closed, made to refer to different files, and can change the files the command reads from and writes to. Redirection may also be used to modify file handles in the current shell execution environment. The following redirection operators may precede or appear anywhere within a simple command or may follow a command. Redirections are processed in the order they appear, from left to right.
Each redirection that may be preceded by a file descriptor number may instead be preceded by a word of the form < varname >. In this case, for each redirection operator except >&- and varname >. If >&- or varname >, the value of varname defines the file descriptor to close. If < varname >is supplied, the redirection persists beyond the scope of the command, allowing the shell programmer to manage the file descriptor’s lifetime manually.
In the following descriptions, if the file descriptor number is omitted, and the first character of the redirection operator is ‘ ’, the redirection refers to the standard input (file descriptor 0). If the first character of the redirection operator is ‘ > ’, the redirection refers to the standard output (file descriptor 1).
The word following the redirection operator in the following descriptions, unless otherwise noted, is subjected to brace expansion, tilde expansion, parameter expansion, command substitution, arithmetic expansion, quote removal, filename expansion, and word splitting. If it expands to more than one word, Bash reports an error.
Note that the order of redirections is significant. For example, the command
Bash handles several filenames specially when they are used in redirections, as described in the following table. If the operating system on which Bash is running provides these special files, bash will use them; otherwise it will emulate them internally with the behavior described below.
If fd is a valid integer, file descriptor fd is duplicated.
File descriptor 0 is duplicated.
File descriptor 1 is duplicated.
File descriptor 2 is duplicated.
If host is a valid hostname or Internet address, and port is an integer port number or service name, Bash attempts to open the corresponding TCP socket.
If host is a valid hostname or Internet address, and port is an integer port number or service name, Bash attempts to open the corresponding UDP socket.
A failure to open or create a file causes the redirection to fail.
Redirections using file descriptors greater than 9 should be used with care, as they may conflict with file descriptors the shell uses internally.
3.6.1 Redirecting Input
The general format for redirecting input is:
3.6.2 Redirecting Output
The general format for redirecting output is:
If the redirection operator is ‘ > ’, and the noclobber option to the set builtin has been enabled, the redirection will fail if the file whose name results from the expansion of word exists and is a regular file. If the redirection operator is ‘ >| ’, or the redirection operator is ‘ > ’ and the noclobber option is not enabled, the redirection is attempted even if the file named by word exists.
3.6.3 Appending Redirected Output
The general format for appending output is:
3.6.4 Redirecting Standard Output and Standard Error
There are two formats for redirecting standard output and standard error:
Of the two forms, the first is preferred. This is semantically equivalent to
3.6.5 Appending Standard Output and Standard Error
The format for appending standard output and standard error is:
This is semantically equivalent to
(see Duplicating File Descriptors below).
3.6.6 Here Documents
This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input (or file descriptor n if n is specified) for a command.
The format of here-documents is:
3.6.7 Here Strings
A variant of here documents, the format is:
The word undergoes tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal. Filename expansion and word splitting are not performed. The result is supplied as a single string, with a newline appended, to the command on its standard input (or file descriptor n if n is specified).
3.6.8 Duplicating File Descriptors
The redirection operator
3.6.9 Moving File Descriptors
The redirection operator
Similarly, the redirection operator
3.6.10 Opening File Descriptors for Reading and Writing
The redirection operator



