what is the difference between `>> /dev/stderr` (with the white space) and `>&2`?

>& n is shell syntax to directly duplicate a file descriptor. File descriptor 2 is stderr; that's how that one works. You can duplicate other file descriptors as well, not just stderr. You can't use append mode here because duplicating a file descriptor never truncates (even if your stderr is a file) and >& is one token, that's why you can't put a space inside it—but >& 2 works.

>> name is a different permitted syntax, where name is a file name (and the token is >>). In this case, you're using the file name /dev/stderr, which by OS-specific handling (on Linux, it's a symlink to /proc/self/fd/2) also means standard error. Append and truncate mode both wind up doing the same thing when stderr is a terminal because that can't be truncated. If your standard error is a file, however, it will be truncated:

anthony@Zia:~$ bash -c 'echo hi >/dev/stderr; echo bye >/dev/stderr' 2>/tmp/foo
anthony@Zia:~$ cat /tmp/foo
bye

If you're seeing an error with /dev/stderr over ssh, it's possible the server admin has applied some security measure preventing that symlink from working. (E.g., you can't access /proc or /dev). While I'd expect either to cause all kinds of weird breakage, using the duplicate file descriptor syntax is a perfectly reasonable (and likely slightly more efficient) approach. Personally I prefer it.


The failure cases occur because the bash syntax for using & in redirections specifies a single >, and requires that it exists directly adjacent to the & sign:

[n]>&word


Use '>' to redirect (truncates if exists) or '>>' (appends if exists).

Use '>&' to duplicate a stream, for instance, if you want standard output AND standard error in the same file, you redirect to file '> output.log' and also error with '2>&'

myjob.sh > output.log 2>&