Redsandro
Redsandro

Reputation: 11356

What does minus mean in "exec 3>&-" and how do I use it?

I often have trouble figuring out certain language constructs because they won't register when googling or duckduckgoing them. With a bit of experimenting, it's often simple to figure it out, but I don't get this one.

I often see stuff like 2>&1 or 3>&- in bash scripts. I know this is some kind of redirection. 1 is stdout and 2 is stderror. 3 is probably custom. But what is the minus?

Also, I have a script whose output I want to log, but also want to see on screen. I use exec > >(tee $LOGFILE); exec 2>&1 for that. It works. But sometimes when I bashtrap this script, I cannot type at the prompt anymore. Output is hidden after Ctrl+C. Can I use a custom channel and the minus sign to fix this, or is it unrelated?

Upvotes: 15

Views: 16068

Answers (2)

Sylvain Defresne
Sylvain Defresne

Reputation: 44463

The 3>&- close the file descriptor number 3 (it probably has been opened before with 3>filename).

The 2>&1 redirect the output of file descriptor 2 (stderr) to the same destination as file descriptor 1 (stdout). This dies call dup2() syscall.

For more information about redirecting file descriptor please consult the bash manpages (`man bash). They are dense but great.

For your script, I would do it like that:

#!/bin/bash
if [[ -z $recursive_call ]]; then
  recursive_call=1
  export recursive_call
  "$0" "$@" | tee filename
  exit
fi
# rest of the script goes there

It lose the exit code from the script though. There is a way in bash to get it I guess but I can't remember it now.

Upvotes: 4

banuj
banuj

Reputation: 3230

  1. 2>&1 means that stderr is redirected to stdout
  2. 3>&- means that file descriptor 3, opened for writing(same as stdout), is closed.

You can see more examples of redirection here

  1. As for questions number 3, I think this is a good link.

Upvotes: 14

Related Questions