dotfiles/notes/shell/fifo.md
2023-12-23 20:13:52 -07:00

1.7 KiB

Shell pipes and fifo

Most bash "blocks" accept a redirection parameter at the end of their declaration. This can replace where the output and errors are going

fn () {
  echo "error" >&3
} 3>&2 2>file
# Prints "error" to the standard error. The real stderr is stored in ./file
  • Functions, as above
  • Sub-shells: (echo "one"; echo "two") > file
  • Loops: while (1); do echo "loop"; done > file

Remember that redirection syntax looks like [fd][< | >][&fd | file_path], where fd is the index in the process' file descriptors. This works for < as well. |& is identical to using 2>&1 |

The order of IO redirection matters. Redirection will go to wherever the redirected destination currently goes. Redeclaring a redirection doesn't work

            ┌3 writes to stdout
            │    ┌stdout writes to stderr
            │    │    ┌stderr writes to where 3 writes, so stdout
            │    │    │
echo "one" 3>&1 1>&2 2>&3

To do this for the entire shell or script, use exec

exec 4>&1          # Holds onto reference to stdout
exec 1>/dev/null   # Silences stdout and loses track of it
exec 1>&4 4>&1     # Restore stdout through reference in 4 and close 4
# Everything back to normal

mkfifo creates a named pipe, which can be easier to interact with between scripts. Make sure it's being held open at use

mkfifo fifo
cat fifo >ofif &   # Holds open fifo pipe and copies anything in there to ofif
exec 3>fifo        # fd 3 reffers to pipe fifo
echo "double" >&3  # Writes to fifo. >fifo would close the pipe right after
exec 3>&-          # Manually close the open pipe

The example above works similar to tee in logging everything in the pipe