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:
/path/to/commandexits immediately../wrapper.shdoes not exit immediately. I must type<Return>once to finishwrapper.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)