41

I have a shell script with lots of echo in it. I would like to redirect the output to a logfile. I know there is the command call cmd > logfile.txt, or to do it in the file echo 'xy' > logfile.txt, but is it possible to simply set the filename in the script which then automatically writes all echo's to this file?

wasp256
  • 5,943
  • 12
  • 72
  • 119

6 Answers6

58

You can add this line on top of your script:

#!/bin/bash
# redirect stdout/stderr to a file
exec >logfile.txt 2>&1

OR else to redirect only stdout use:

exec > logfile.txt
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 7
    I want to write log in file and also want it to appear on console. Can you please guide what should I use for it. – Sandeep Singh Oct 14 '15 at 07:00
  • 1
    I tried with this `exec > myLog.log 2>&1 | tee myLog.log` Its showing on console but not writing on file . I tried with `command | tee file.log` but this is also showing only on console. – Sandeep Singh Oct 14 '15 at 07:15
  • Its writing only system date in file – Sandeep Singh Oct 14 '15 at 07:19
  • Well that was all the output of command we used. ok better not to extend chat session on an unrelated question. – anubhava Oct 14 '15 at 07:22
  • Will this one overwrites the log file every time the script is executed? – Gilroy Jan 08 '19 at 07:32
  • Use `>>` instead of `>` – anubhava Jan 08 '20 at 13:56
  • 1
    The Bashism `&>` is quite gratuitous here; the portable notation `>logfile.txt 2>&1` is more explicit but IMHO more readable as well as more portable (and easy then to change to `>>` whereas `&>>` was only introduced relatively recently, and isn't available on platforms which still only offer Bash 3, such as macOS). – tripleee May 02 '21 at 10:21
  • Beware that neither tee nor redirect survives log file rotation. – Erik Martino Sep 19 '22 at 11:55
  • Change `>` to `>>` for ability to rotate/truncate log files. – anubhava Sep 19 '22 at 13:37
25

I tried to manage using the below command. This will write the output in log file as well as print on console.

#!/bin/bash

# Log Location on Server.
LOG_LOCATION=/home/user/scripts/logs
exec > >(tee -i $LOG_LOCATION/MylogFile.log)
exec 2>&1

echo "Log Location should be: [ $LOG_LOCATION ]"

Please note: This is bash code so if you run it using sh it will throw a syntax error.

AP-
  • 57
  • 2
  • 6
Sandeep Singh
  • 7,790
  • 4
  • 43
  • 68
  • So how do I append rather than overwrite? Or can that not be done because we are writing to screen also? (I've tried modifying the line to "exec >> >(tee.." but it still overwrites) – Mark Smith Aug 27 '20 at 11:05
  • 2
    @MarkSmith please use with `-a` option: `exec > >(tee -a $log)` – Sandeep Singh Aug 27 '20 at 13:24
  • Of course! I kind of knew about the -a option with tee, but completely forgot. Thank you – Mark Smith Aug 27 '20 at 13:39
  • Above works perfectly; but curious could anymore explain how/why this work? – Kelly Trinh Apr 25 '21 at 04:55
  • @Kelly The notation `>(cmd)` essentially creates a parallel process which runs `cmd` for the duration of the command which contains this process substitution, with its output redirected to standard input of `cmd`. The command `exec` is a special case here; its sole purpose is to create a process substitution until the end of the script, or the next `exec` which redirects the same file descriptor(s) to a different destination. – tripleee May 02 '21 at 10:24
14

You can easily redirect different parts of your shell script to a file (or several files) using sub-shells:

{
  command1
  command2
  command3
  command4
} > file1
{
  command5
  command6
  command7
  command8
} > file2
txipi
  • 141
  • 3
5
LOG_LOCATION="/path/to/logs"    
exec >> $LOG_LOCATION/mylogfile.log 2>&1
Elayaraja Dev
  • 208
  • 3
  • 6
4
#!/bin/sh
# http://www.tldp.org/LDP/abs/html/io-redirection.html
echo "Hello World"
exec > script.log 2>&1
echo "Start logging out from here to a file"
bad command
echo "End logging out from here to a file"
exec > /dev/tty 2>&1 #redirects out to controlling terminal
echo "Logged in the terminal"

Output:

> ./above_script.sh                                                                
Hello World
Not logged in the file
> cat script.log
Start logging out from here to a file
./logging_sample.sh: line 6: bad: command not found
End logging out from here to a file

Read more here: http://www.tldp.org/LDP/abs/html/io-redirection.html

  • The ABS is a rather dubious reference; it would probably be better to link to the official Bash reference manual, or to POSIX. – tripleee May 02 '21 at 10:27
2

To get output on console and log output in a file:

script.sh

#!/bin/bash
(
  #Command 1
  #Command 2
  #Command 3
  ...
) 2>&1 | tee /path/to/save/console_output.log
Ahsan Horani
  • 239
  • 2
  • 13