3
#!/bin/bash
#...
exec >> logfile
#cmd

I guest it's save output. Could you expand it with the same example? Thank you very much!

I often use this command to list txt files:

find / -type f -exec grep -l "bash" {} \;

but I can't very understand too.


How can there be such good people in the world.very very moved!

3 Answers3

4

Yes, it sends any further output to the file named logfile. In other words, it redirects standard output (also known as stdout) to the file logfile.

Example

Let's start with this script:

$ cat >script.sh
#!/bin/bash
echo First
exec >>logfile
echo Second

If we run the script, we see output from the first but not the second echo statements:

$ bash script.sh
First

The output from the second echo statement went to the file logfile:

$ cat logfile
Second
$ 

If we had used exec >logfile, then the logfile would be overwritten each time the script was run. Because we used >> instead of >, however, the output will be appended to logfile. For example, if we run it once again:

$ bash script.sh
First
$ cat logfile
Second
Second

Documentation

This is documented in man bash:

exec [-cl] [-a name] [command [arguments]]
If command is specified, it replaces the shell. No new process is created. The arguments become the arguments to command. If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is what login(1) does. The -c option causes command to be executed with an empty environment. If -a is supplied, the shell passes name as the zeroth argument to the executed command. If command cannot be executed for some reason, a non-interactive shell exits, unless the execfail shell option is enabled. In that case, it returns failure. An interactive shell returns failure if the file cannot be executed. If command is not specified, any redirections take effect in the current shell, and the return status is 0. If there is a redirection error, the return status is 1. [Emphasis added.]

In your case, no command argument is specified. So, the exec command performs redirections which, in this case, means any further stdout is sent to file logfile.

find command and -exec

The find command has a -exec option. For example:

find / -type f -exec grep -l "bash" {} \;

Other than the similarity in name, the -exec here has absolutely nothing to do with the shell command exec.

The construct -exec grep -l "bash" {} \; tells find to execute the command grep -l "bash" on any files that it finds. This is unrelated to the shell command exec >>logfile which executes nothing but has the effect of redirecting output.

John1024
  • 109,961
  • 14
  • 137
  • 171
1

Everything you output to stdout will not go to stdout but to the logfile. See example below:

#!/bin/bash
# reassign-stdout.sh

LOGFILE=logfile.txt

exec 6>&1           # Link file descriptor #6 with stdout.
                    # Saves stdout.

exec > $LOGFILE     # stdout replaced with file "logfile.txt".

# ----------------------------------------------------------- #
# All output from commands in this block sent to file $LOGFILE.

echo -n "Logfile: "
date
echo "-------------------------------------"
echo

echo "Output of \"ls -al\" command"
echo
ls -al
echo; echo
echo "Output of \"df\" command"
echo
df

# ----------------------------------------------------------- #

exec 1>&6 6>&-      # Restore stdout and close file descriptor #6.

echo
echo "== stdout now restored to default == "
echo
ls -al
echo

exit 0
Peter van der Does
  • 14,018
  • 4
  • 38
  • 42
0

This redirects standard output produced by your script and any other programs it subsequently calls into the logfile. So if your script runs in terminal after it executes

exec >> logfile

you'll see no output in your terminal window but you'll find it inside the logfile. logfile will be created if it doesn't exist or appended every time you run your script.

oᴉɹǝɥɔ
  • 1,796
  • 1
  • 18
  • 31