I want to redirect both stdout and stderr of a process to a single file. How do I do that in Bash?
相关问题
- How to get the return code of a shell script in lu
- Stop .htaccess redirect with query string
- JQ: Select when attribute value exists in a bash a
- UrlEncodeUnicode and browser navigation errors
- Invoking Mirth Connect CLI with Powershell script
相关文章
- 使用2台跳板机的情况下如何使用scp传文件
- How to get jQuery.ajax response status?
- In IntelliJ IDEA, how can I create a key binding t
- send redirect and setting cookie, using laravel 5
- Check if directory exists on remote machine with s
- shell中反引号 `` 赋值变量问题
- How get the time in milliseconds in FreeBSD?
- Reverse four length of letters with sed in unix
1>file.log
instructs the shell to send STDOUT to the filefile.log
, and2>&1
tells it to redirect STDERR (file descriptor 2) to STDOUT (file descriptor 1).Note: The order matters as liw.fi pointed out,
2>&1 1>file.log
doesn't work.You can redirect stderr to stdout and the stdout into a file:
See http://tldp.org/LDP/abs/html/io-redirection.html
This format is preferred than the most popular &> format that only work in bash. In Bourne shell it could be interpreted as running the command in background. Also the format is more readable 2 (is STDERR) redirected to 1 (STDOUT).
EDIT: changed the order as pointed out in the comments
Short answer:
Command >filename 2>&1
orCommand &>filename
Explanation:
Consider the following code which prints the word "stdout" to stdout and the word "stderror" to stderror.
Note that the '&' operator tells bash that 2 is a file descriptor (which points to the stderr) and not a file name. If we left out the '&', this command would print
stdout
to stdout, and create a file named "2" and writestderror
there.By experimenting with the code above, you can see for yourself exactly how redirection operators work. For instance, by changing which file which of the two descriptors
1,2
, is redirected to/dev/null
the following two lines of code delete everything from the stdout, and everything from stderror respectively (printing what remains).Now, we can explain why the solution why the following code produces no output:
To truly understand this, I highly recommend you read this webpage on file descriptor tables. Assuming you have done that reading, we can proceed. Note that Bash processes left to right; thus Bash sees
>/dev/null
first (which is the same as1>/dev/null
), and sets the file descriptor 1 to point to /dev/null instead of the stdout. Having done this, Bash then moves rightwards and sees2>&1
. This sets the file descriptor 2 to point to the same file as file descriptor 1 (and not to file descriptor 1 itself!!!! (see this resource on pointers for more info)) . Since file descriptor 1 points to /dev/null, and file descriptor 2 points to the same file as file descriptor 1, file descriptor 2 now also points to /dev/null. Thus both file descriptors point to /dev/null, and this is why no output is rendered.To test if you really understand the concept, try to guess the output when we switch the redirection order:
The reasoning here is that evaluating from left to right, Bash sees 2>&1, and thus sets the file descriptor 2 to point to the same place as file descriptor 1, ie stdout. It then sets file descriptor 1 (remember that >/dev/null = 1>/dev/null) to point to >/dev/null, thus deleting everything which would usually be send to to the standard out. Thus all we are left with was that which was not send to stdout in the subshell (the code in the parentheses)- i.e. "stderror". The interesting thing to note there is that even though 1 is just a pointer to the stdout, redirecting pointer 2 to 1 via
2>&1
does NOT form a chain of pointers 2 -> 1 -> stdout. If it did, as a result of redirecting 1 to /dev/null, the code2>&1 >/dev/null
would give the pointer chain 2 -> 1 -> /dev/null, and thus the code would generate nothing, in contrast to what we saw above.Finally, I'd note that there is a simpler way to do this:
From section 3.6.4 here, we see that we can use the operator
&>
to redirect both stdout and stderr. Thus, to redirect both the stderr and stdout output of any command to\dev\null
(which deletes the output), we simply type$ command &> /dev/null
or in case of my example:Key takeaways:
2>&1 >/dev/null
is !=>/dev/null 2>&1
. One generates output and the other does not!Finally have a look at these great resources:
Bash Documentation on Redirection, An Explanation of File Descriptor Tables, Introduction to Pointers
The following functions can be used to automate the process of toggling outputs beetwen stdout/stderr and a logfile.
Example of usage inside script:
It is related: Writing stdOut & stderr to syslog.
It almost work, but not from xinted ;(
Take a look here. Should be:
(redirects both
stdout
andstderr
to filename).