Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

How to capture output from certain Unix commands UNIX
I was recently trying to do some simple shell scripting with the command httpd -t, which runs a syntax check on the Apache configuration files. If everything is OK, it returns Syntax OK, otherwise, it will try to tell you what's wrong with the files. I wanted to grab the output of the syntax check and display it in my script, but wasn't having any luck -- any attempt to redirect the output, or assign it to a variable, resulted in nothing (empty variable, empty file, etc.). Unix wizards can stop reading this hint now, for I'm sure you know what the problem is...

After much Googling, I discovered that some Unix commands create their output by writing to standard error (STDERR) instead of standard output (the Terminal window, typically). As a result, operations that capture standard output won't work for these types of messages, even though the message itself is displayed in the Terminal window. I found the solution in the Wikipedia entry for stderr: append 2>&1 to the end of the command (note that this is for sh-style shells, including bash, the OS X default shell). This redirects standard error to the same destination as standard output, meaning the data can then be captured as you wish. To put the output of httpd -t onto the clipboard, for instance, you could use this:
$ httpd -t 2>&1 | pbcopy
$ pbpaste
Syntax OK
Or if you wished to assign the output to a variable for use in a script:
CONFIGTEST=`httpd -t 2>&1`
I'm sure there are a number of other commands that output via standard error -- one for certain is ssh -V, which returns the version information for ssh.
    •    
  • Currently 2.25 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (8 votes cast)
 
[20,490 views]  

How to capture output from certain Unix commands | 13 comments | Create New Account
Click here to return to the 'How to capture output from certain Unix commands' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
How to capture output from certain Unix commands
Authored by: fracai on May 01, '08 07:58:52AM

If you'd like to output both the standard error and output to one file you can also use "&>" as in

ssh -V &> output

The above would merge both stderr and stdout to the output file.

---
i am jack's amusing sig file



[ Reply to This | # ]
portability
Authored by: perturb on May 02, '08 04:48:47AM

Pedantic note: this is available in recent shells like bash, but not in older Unix sh/ksh shells (including the POSIX standard shell.)



[ Reply to This | # ]
How to capture output from certain Unix commands
Authored by: gregraven on May 01, '08 08:01:41AM

For others who, like me, do not have an "http" command available to them, you can use "apachectl -t" to check the syntax of your Apache conf files.

---
--
Greg Raven
Apple Valley, CA



[ Reply to This | # ]
How to capture output from certain Unix commands
Authored by: robg on May 01, '08 08:38:32AM

Greg:

Sorry, there was a typo in the hint (which I've now fixed). It should be:

httpd -t

(the "d" was missing)

-rob.



[ Reply to This | # ]
How to capture output from certain Unix commands
Authored by: fds on May 01, '08 08:17:08AM

The stdout/stderr distinction even exists in DOS and Windows. :)



[ Reply to This | # ]
How to capture output from certain Unix commands
Authored by: darkxsun on May 01, '08 08:47:22AM

time does the same.



[ Reply to This | # ]
How to capture output from certain Unix commands
Authored by: kaolson on May 01, '08 08:53:02AM

The unix "script" command is useful for capturing, logs to a file iirc.



[ Reply to This | # ]
How to capture output from certain Unix commands
Authored by: mjb on May 01, '08 02:25:52PM
In case anyone's interested, the string 2>&1 isn't just gibberish.. the numbers (1 and 2) are representative of the file handle ids for STDOUT (1) and STDERR (2). The > is for redirection, and the & is an 'escape'.

So, the outcome is "2 is redirected to 1, where 1 is a file handle, not a file". That's where the 'escape' comes in - it tells the shell that you want to redirect to a file handle, not a real file called "1". Basically STDERR is merged into STDOUT, so that any piping (|) or redirection (>) contains STDERR output too:

/path/to/somecommand -args > /tmp/output.txt 2>&1
(The redirection of STDERR to STDOUT and STDOUT to a file can be in either order, they're parsed by your shell then acted on simultaneously)

Note that due to buffering of the different data streams, the output can end up being 'out of sync' with each other, although this is rare.

[ Reply to This | # ]

How to capture output from certain Unix commands
Authored by: mjb on May 01, '08 02:31:59PM
Whoops, I lie. the order of redirections do indeed act in a different way, but the outcome is the same (and while I'm at it, the '&' isn't really an escape, just a convenient way of describing it).

For more information, have a look at the bash manpage (run 'man bash' in Terminal.app), and look at the section on Redirection (to skip to it, enter the following string in the man page reader: /^REDIRECTION and press enter.

[ Reply to This | # ]

How to capture output from certain Unix commands
Authored by: TonyT on May 01, '08 06:33:32PM

A related use, if you do not want to see the error message at all, re-direct to null (i.e., if using find recursively and you don't want to see Permission denied messages: find / -iname 'nyc*' 2> /dev/null)



[ Reply to This | # ]
How to capture output from certain Unix commands
Authored by: pedz on May 23, '08 12:20:24PM

There is also /dev/tty -- this is a device that points to the controlling terminal. Some scripts and programs use this when they want to get back to a real user when input and output has been redirected.



[ Reply to This | # ]
How to implement drag-drop from unix
Authored by: rahulbenegal on Jul 22, '08 04:59:35AM

Is there a way of passing the output to an application, just as drag-drop would do ?

One option was the "open" command, but in some apps "open" does not behave like a drag drop would.

Thanks.



[ Reply to This | # ]
How to implement drag-drop from unix
Authored by: mario_grgic on Sep 03, '08 03:07:19PM

Yes of course there is. The standard UNIX way is command substitution. For example:

find . -name "*.java"

finds all java files in the current directory. So what if you want to open these files in vi? Well do command substitution

vi $(find . -name "*.java")

This first runs the command in $(...) and then passes the output of that as arguments to vi, which in turn opens the files found for editing (all of them at once).

Of course, sometimes it is better to just pipe output of one command to another with |



[ Reply to This | # ]