Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I stored the following program in new.c

int main() 
{ 
    a;
    return 0; 
}

It returns an error message. I want to send this message to a file. So I used the following command

gcc new.c > temp.txt

But still I was getting the output on the terminal. I am using Ubuntu 13.04. How can I make it work?

share|improve this question
4  
"Why doesn't this work?" is a title that doesn't in any way distinguish this from half of the other questions asked here. Titles should be distinctive and specific to the question. I've tried to edit something decent in myself; please do this when initially asking in the future. –  Charles Duffy Jun 22 '13 at 13:27
    
(related note on tagging: "terminal" is the program [or, decades ago, the hardware] that provides the display you see your shell in; questions about redirection are about the shell itself, not the program you use to interact with that shell). –  Charles Duffy Jun 22 '13 at 13:30
    
@Charles Duffy Okay, Thank you –  Alex Jun 22 '13 at 14:14
add comment

migrated from stackoverflow.com Jun 22 '13 at 20:27

This question came from our site for professional and enthusiast programmers.

3 Answers

up vote 11 down vote accepted

When you compile a program with gcc, there are different kinds of output: to stdout and stderr. Normally, the > will direct stdout stream to a file (for example, the result of a printf("hello world\n"); is sent to stdout). However, the stderrcontinues to be sent to the screen, since it's assumed to be "something exceptional that you need to be told about".

There is a way to redirect stderr to a file - you do this with the following (not very intuitive) command:

gcc new.c &> myFile

where &> is "bash shorthand" for "redirect everything". As was pointed out by @CharlesDuffy, the POSIX compliant form is

gcc new.c > myFile 2>&1

This means "compile 'new.c' and send stdout to myFile. And send stderr (2) to the same place as stdout (&1 = "the same place as stdout").

You will find more details on different redirects at http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html and http://mywiki.wooledge.org/BashFAQ/055

By the way, if you want to send something from within your program specifically to stderr, you can do so with the following

fprintf(stderr, "hello world - this is urgent.\n");

If you include that in a program, run the program and send the "normal" output to a file, this will still appear on the console. So if you compile the above into the executable urgent, then type

./urgent > /dev/null

at the console, your output will appear on screen.

share|improve this answer
2  
mywiki.wooledge.org/BashFAQ/055 is probably a better introduction to redirection. Also, one really should introduce the POSIX-compliant form (>myFile 2>&1) as well as the bash extension (&>). –  Charles Duffy Jun 22 '13 at 13:34
    
@CharlesDuffy - both very good points. I will include them in my answer for completeness. –  Floris Jun 22 '13 at 13:38
add comment

Because > redirects only stdout, and errors are written to stderr, you need to use one of the following instead:

gcc new.c &> temp.txt ## redirect both stdout and stderr using bash or zsh only

...or...

gcc new.c >temp.txt 2>&1 ## redirect both stdout and stderr in any POSIX shell

&> is a BASH extension which redirects both stdout and stderr to a file; otherwise, the easiest approach is to first redirect stdout (>temp.txt), and then make stderr (FD 2) a copy of the already-redirected file handle on stdout (FD 1), like so: 2>&1.

share|improve this answer
add comment

As the others have said, linux provides two different output streams:

stdout, or "standard output" is where all regular output goes.
              You can reference it using file descriptor 1.

stderr, or "standard error" is a separate stream for out-of-band information.
              You can reference it using file descriptor 2.

Why two different output streams? Consider a pipeline of imaginary commands:

 decrypt $MY_FILE | grep "secret" | sort > secrets.txt

Now imagine the decrypt command fails and generates an error message. If it sent that message to stdout, it would sent into the pipe, and unless it had the word "secret" you'd never see it. So you'd end up with an empty output file, with no idea what went wrong.

However, since the pipe only captures stdout, the decrypt command can send its errors to stderr, where they'll be displayed on the console.

You can redirect stdout and stderr, either together or independently:

# Send errors to "errors.txt" and output to "secrets.txt"
# The following two lines are equivalent, as ">" means "1>"
decrypt $MY_FILE 2> errors.txt > secrets.txt
decrypt $MY_FILE 2> errors.txt 1> secrets.txt

You can redirect the errors to stdout and process them as if they were normal output:

# The operation "2>&1" means "redirect file descriptor 2 to file
# descriptor 1. So this sends all output from stderr to stdout.
# Note that the order of redirection is important.
decrypt $MY_FILE > errors.txt 2>&1 

# This may be confusing.  It will store the normal output in a file
# and send error messages to stdout, where they'll be captured by 
# the pipe and then sorted.
decrypt $MY_FILE 2>&1 > output.txt | sort

You can also use a "shorthand" notation to redirect both stdout and stderr to the same file:

decrypt $MY_FILE &> output.txt

And, finally, the > operator will first truncate its output file before writing to it. If, instead, you want to append data to an existing file, use the >> operator:

decrypt $MY_FILE 2>> more_errors.txt >> more_secrets.txt
decrypt $MY_FILE >> more_output.txt 2>&1
share|improve this answer
    
+1 for a very complete and clear description! –  Floris Jun 22 '13 at 14:11
1  
Two quibbles: (1) Use of unquoted parameter expansions ($FOO) is a common source of bugs, and demonstrating it in examples is not so great. (2) Use of all-uppercase variable names is the primary reason for namespace conflicts between environment and built-in variables (uppercase by convention) and local variables (lowercase by convention). (3) Encouraging people to repeatedly use >> (which reopens the file every time it's used in a command) rather than opening a file once and leaving the file descriptor open for use by multiple commands results in inefficient code. –  Charles Duffy Jun 22 '13 at 14:41
    
...on the last point, compare to: exec 4>secrets; echo "this is a secret" >&4; echo "this is another secret" >&4 –  Charles Duffy Jun 22 '13 at 14:41
    
+1 Thanks for keeping me honest, @CharlesDuffy. All good points. I intentionally omitted exec for simplicity, though in practice it's generally a better strategy. –  Adam Liss Jun 22 '13 at 16:59
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.