This is fairly nerdy, but it does come in handy from time-to-time.
There are two kinds of output commands can use:
- Standard Output (abbreviated 'stdout')
- Standard Error (abbreviated 'stderr')
Most of the time it doesn't really matter, but it can be handy to know.
It might help to look at a practical example. Here’s a command:
find / -print
Which will show a list of all the files/folders on your hard drive, but it will also show errors when it encounters files/folders which cannot be accessed.
Now, suppose you wanted to make a list of all the files/folders on your computer, you could use this:
find / -print > index.txt
And the file 'index.txt' would end up showing you a list of all the files/folders.
However, you would also see all of the errors. They wouldn't end up in the file, but they would end up on the screen.
But what if you wanted to put the names of all of the files/folders into one file, and all of the errors into another? You can do that by telling the computer to ignore all of the errors by redirecting standard error, like this:
find / -print > index.txt 2>index-errors.txt
Here the number '2' refers to 'standard error' as I mentioned above.
Why '2'? I have no idea. I assume there's some historical reason, but all you need to know for this is that '1' is 'standard output' and '2' is 'standard error'.
So another way of writing that line would be this:
find / -print 1>index.txt 2>index-errors.txt
You don't need to include the '1' because it's the default, but it will work if you do.
So, now that you know what '1' and '2' are, it's probably almost obvious that 2>&1
means "redirect any output that you would have sent to 'standard error' to 'standard output'.
(You couldn't just use 2>1
because that would say “Redirect standard error output to a file named '1' “.)
If you wanted to create a file that showed both the files/folders and the errors, you would use:
find / -print 2>&1 > full-index.txt
Now, I have to admit that sometimes it seems to work better if you enclose the first command in parenthesis, like this:
( find / -print 2>&1 ) > full-index.txt
I'm not entirely sure why that is, but it's just another piece of data.
Now, you might ask yourself, "Why does 'ffmpeg' use 'standard error' instead of 'standard output' when you use-af volumedetect
?"
I have absolutely no idea.
How did I know?
Well… a lot of years of experience has taught me that if you try to try to get the output of a command and it doesn't work, try redirecting standard error.
How did I test my theory?
I tried to assign the output of the ffmpeg
command to a variable like this:
RESULT=$(ffmpeg -af volumedetect /path/to/file.ext)
That should have resulted in no output, but instead I saw all of the output from the command, and when I tried
echo "$RESULT"
It showed nothing.
That was when I tried this instead:
RESULT=$(ffmpeg -af volumedetect /path/to/file.ext 2>&1)
That worked as expected.
So there's a longer answer than anyone wanted.
P.s. Oh… just one more thing… you may have seen commands which end with
2>/dev/null
Such as
find / -print 2>/dev/null
In case you’ve ever wondered why, that command says “disregard all error messages and do not show them”. In that case, “/dev/null” is a like a “file” which immediately deletes anything you try to save to it.
I do hope someone found this at least somewhat useful or interesting.