Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've always done

   (cmd 2>&1) > file
to redirect stderr and stdout to a file. I always thought the parenthesis were necessary, but according to this I can just do

   cmd > file 2>&1
It seems very unintuitive, though. Does anyone know the rationale behind ordering of redirects?

(That said, I'm going to use 'cmd &> file' that I just learned from now on)



cmd is going to output to STDOUT and STDERR, which are file descriptors 1 and 2. In a basic shell command execution, those route out to the console.

Reading from left to right:

  cmd
Run command cmd. File descriptors: {1: /dev/console, 2:/dev/console}

  > file
Open a file descriptor for "file" and copy it into our first file descriptor (stdout). File descriptors: {1: fopen('file'), 2: /dev/console }

  2>&1
Copy the file descriptor stored in 1 (stdout) into 2 (stderr). File descriptors: {1: fopen('file'), 2: fopen('file')}


In the first case, you're actually executing two shells.

    (cmd 2>&1)
runs in its own subshell, and copies stderr to stdout.

    >file
is interpreted in the parent shell, and copies stdout to 'file'.

In the second instance, you run a single shell, first copying stdout to 'file', then copying stderr to the (redirected) stdout, that is, 'file'.


> Does anyone know the rationale behind ordering of redirects?

I can't give you an exact rationale, but my old shell scripting books from the 90's use the cmd > file 2>&1 notation. My personal belief is that it was for situations when you would do something like this:

cmd > output.txt 2> errors.txt


It's read as "cmd, stdout to file, stderr to the same place as stdout".




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: