Redirection

  • Overwrite
    • {command} < {file} : sends input to stdin from file
    • {command} > {file} : overwrite output of stdout to file
  • Append
    • {command} << {delimiter} : (here-document) reads input until it gets delimiter which marks ending of input
      • Syntax
        user:~$ {command} << {delimiter}
        here-document
        delimiter
      • Example
        user:~$ cat << stop
        > Hi World
        > How are you
        > stop
        Hi World
        How are you
        user:~$
    • {command} >> {file} : append output of stdout to file
  • Merge
    • p >& q : Merges output from stream p with stream q
    • p <& q : Merges input from stream p with stream q
  • {command1} | {command2} : (pipe) sends stdout of one command to stdin of another command
  • Whenever you execute a program/command at the terminal, 3 files are always open viz., standard input, standard output, standard error

standard file descriptors (fd) and redirection:

  • 0: stdin
 # reads stdin data from infile
{command} 0<infile
  • 1: stdout
# writes stdout to outfile
{command} 1>outfile
  • 2: stderr
# appends stderr to logfile
# >> is append, > is overwrite
{command} 2>>logfile

redirecting stderr (2) to stdout (1)

{command} 2>&1

write stdout nowhere

{command} > /dev/null
{command} 1>/dev/null

write stdout and stderr nowhere

{command} > /dev/null 2>&1

write stdout and stderr to file

{command} > file 2>&1

tee command

  • splits output to save it to a file while still viewing it live
  • intercepts an existing data pipeline (like a T-shaped pipe)
  • use cases
    • sudo echo "data" > /etc/config fails because sudo happens after right side executed
    • echo "data" | sudo tee /etc/config
# save and see the logs simultaneously
./script.sh | tee logs.txt
 
# save list of binaries to ls.txt and prints binaries containing word "zip"
ls /usr/bin | tee ls.txt | grep zip
 
# bypassing permissions limit
# You cannot use standard redirection (`>`) to write to protected files
# because shell evaluates redirection before running sudo
sudo echo "data" > /etc/config # fails
echo "data" | sudo tee /etc/config # works

Terminal

  • stdout and stderr point to Terminal screen
  • stdin is taken from keyboard
  • stdout is buffered
    • it saves text in memory and dumps all in when newline appears
  • stderr is unbuffered by default
    • every single character sent to stderr immediately without buffering
    • This ensures that if a program suddenly crashes mid-execution, the error message explaining why it crashed is safely printed out rather than being trapped in volatile memory
# redirect stderr to log file
command 2> error_log.txt
 
# redirect stdout to results file
# this prevents error being redirected
command > results.txt
 
# silence all errors
command > /dev/null

Running multiple commands

> command1; commmand2; command3
 
# print contents of /usr
> cd /usr; ls; cd -
  • grouping multiple commands
> {command1; command2; command3} > output.txt
 
# print contents of /usr and save final output to ls-usr.txt
> {cd /usr; ls; cd -} > ls-usr.txt