Skip to content
Advertisement

Wrapper script that write logs of arguments, stdin and stdout

I want to create a wrapper script which writes logs of arguments, stdin and stdout. I have written the following script wrapper.sh, which works almost fine.

#! /bin/bash

wrapped_command="/path/to/command" # Set the path to the command which we want to wrap

log_dir="/tmp/stdio-log"
mkdir -p $log_dir

args_logfile=$log_dir/args
stdin_logfile=$log_dir/stdin
stdout_logfile=$log_dir/stdout
stderr_logfile=$log_dir/stderr

echo "$@" > "$args_logfile"

tee -a "$stdin_logfile" |
    "$wrapped_command" "$@" > >(tee -a "$stdout_logfile") 2> >(tee -a "$stderr_logfile" >&2)

I expect that ./wrapper.sh arg1 arg2 gives the same result as /path/to/command arg1 arg2 with logs in /tmp/stdio-log/. But it gives a slightly different result in Example 2 below.

Example 1: a command that accepts standard inputs

#! /bin/bash

while read line
do
    echo "input: $line"
done

The above wrapper script works as expected with this example.

Example 2: a command that does not accept standard inputs

#! /bin/bash
echo "Example command"

With this example, I got the following different behavior:

  1. /path/to/command exits immediately.
  2. ./wrapper.sh does not exit immediately. I must type <Return> once to finish wrapper.sh.

Question

How can I fix the wrapper script (or rewrite with different methods) so that it works as expected with both examples simultaneously?

Advertisement

Answer

The in the foreground invoked tee -a "$stdin_logfile" waits for input.

How can I fix the wrapper script …?

It works as you expect if stdin is handled just like stdout with Process Substitution.

"$wrapped_command" "$@" < <(tee -a "$stdin_logfile")
                        > >(tee -a "$stdout_logfile") 2> >(tee -a "$stderr_logfile" >&2)
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement