Jump to content

(bash) What does 1>&2 do?


Guest BooYah
 Share

Recommended Posts

This script, which is obviously not mine, appears to do the same thing whether the 1>&2 is there or not. I'm curious what purpose it serves.

 

#!/bin/bash



# cmp_dir - program to compare two directories



# Check for required arguments

if [ $# -ne 2 ]; then

   echo "usage: $0 directory_1 directory_2" 1>&2

   exit 1

fi



# Make sure both arguments are directories

if [ ! -d $1 ]; then

   echo "$1 is not a directory!" 1>&2

   exit 1

fi



if [ ! -d $2 ]; then

   echo "$2 is not a directory!" 1>&2

   exit 1

fi



# Process each file in directory_1, comparing it to directory_2

missing=0

for filename in $1/*; do

   fn=$(basename "$filename")

   if [ -f "$filename" ]; then

       if [ ! -f "$2/$fn" ]; then

           echo "$fn is missing from $2"

           missing=$((missing + 1))

       fi

   fi

done

echo "$missing files missing"

 

A bash how_to says:

This will cause the stderr output of a program to be written to the same filedescriptor than(sic) stdout

 

It also says the same thing for 2>&1. Which confuses me even more.

Link to comment
Share on other sites

look at this link very good explanation

 

http://www.stat.vt.edu/UNIX_BOOKS/upt/ch45_21.htm

 

1>&2

 

1 = standard output

2 = standard error

 

send standard output to standard error

 

which makes sense as they are error msgs in the shell script eg)

# Make sure both arguments are directories

if [ ! -d $1 ]; then

   echo "$1 is not a directory!" 1>&2

   exit 1

fi  

 

if not a directory send "$1 is not a directory!" to standard error and exit

the echo command in bash normally goes to standard output so need the 1>&2 to send it to standard error.

 

btw i really no nothing about shell scripting, so go read up on it for yourself

Link to comment
Share on other sites

2> means standard error output

 

example:

we haver all seen > /dev/null ... which means don't show any output, dump it.

but what about errors?

errors still show up ... how can you get rid of errors aswell?

> /dev/null 2>&1

this means dump everything to /dev/null and if an error occurs dump it to the same place the standard output is going to.

 

understand?

1>&2 means dump everything to standard error output, which in normal cases means the screen

Link to comment
Share on other sites

Thanks for explaining that. I understand what it does, now, but I still don't understand why it's in this script. The script has it's own error messages that get sent to the screen via echo, regardles, whether the 1>&2 is there or not, when the if condtion is true. Right?

Link to comment
Share on other sites

OK. So, as was already said, 1 is standard output, for sending normal messages, and 2 is standard error, for sending error messages (BTW, 0 is standard input, but is usually not written).

Let's take 'cat' as an example. If you don't give cat a file to read, it will read standard input instead. Whatever it reads, cat outputs to the standard output (logical). So if you write this command

cat <inputfile 1>outputfile 2>errorfile

, cat does not have any parameters, so it will read standard input, in this case: inputfile (< is for standard input redirection). Then cat will output everything to standard output, which is redirected to outputfile. Any errors, if they occur, will be sent to standard error, which is redirected to errorfile. If all goes well, errorfile is an empty file, and outputfile ends up being a copy of inputfile (at least if cat does not perform any kind of filtering or layout).

 

As you can see, standard input and output are two completely different things. Now, what happens when you execute a command without redirecting anything? Simple: input is the terminal window (keyboard), and output, as well as error, are both sent to the same terminal window.

cat somefile

will send the content of somefile to standard output, which is then displayed into the terminal window. And if somefile does not exist, an error message will be sent to standard error, which will then be displayed into the terminal.

 

Now let's imagine that somefile is a list of errors generated by some other tool. You want cat to display the list of errors, but cat was created to send the file content to standard output, not standard error! The solution is to make the shell redirect cat's standard output to its standard error:

cat somefile 1>&2

So 1 (output) is redirected to 2 (error); 2 itself is not redirected because we want the file to be displayed, but we could very well have redirected it to a file.

 

You might wonder what is the point of having both output and error, if both are displayed the same... The fact is that even though they look the same to us, they don't look the same to the computer. Try that:

find /proc -name "*" -print | tee referencefile | wc -l

This will give you the number of output lines. the 'tee' command mainly outputs what was output by the previous command. So tee is not a filter, no information is lost; tee is just there to also store the standard output to referencefile.

As a normal user (not root), you're bound to have at least some errors with this command. You'll see that the number you'll get is not the number of lines of error that you saw. But this number should be the same as the result of this command:

cat referencefile | wc -l

, and if you look at this file, you'll see there are no errors in it. This is because the "pipe" command (the | symbol) only lets the standard output go through, not standard error.

 

This all means that the system is able to distinguish output from errors, even though they both look the same to us. That is sometimes very usefull. Imagine you want to find all files in /home, the name of which contains 'file' (eg: myfile.txt, .profile, ...). You'll run this command:

find /home -name "*" -print | grep "file" >listfound.txt

(actually, there's of course a much better way). You don't want grep to also catch the lines like "file not found", or "no such file or directory"... well, that's OK, because such errors won't even go through the | pipe, so grep won't know of them.

 

Yves.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...