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/command
exits immediately../wrapper.sh
does 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)