When a script runs, commands in it may output some text to stdout/stderr. Bash itself may also output some text.
But if a few scripts are running at the same time, it is hard to identify where does an error come from.
So is it possible to insert a prefix to all output of the script? Something like:
#!/bin/bash prefix 'PREFIX' &2 echo "wrong!" >&2
Then:
$ ./script.sh PREFIXwrong!
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can redirect stderr/stdout to a process substitution that adds the prefix of choice. For example, this script:
#! /bin/bash exec > >(trap "" INT TERM; sed 's/^/foo: /') exec 2> >(trap "" INT TERM; sed 's/^/foo: (stderr) /' >&2) echo foo echo bar >&2 date
Produces this output:
foo: foo foo: (stderr) bar foo: Fri Apr 27 20:04:34 IST 2018
The first two lines redirect stdout and stderr respectively to sed commands that add foo: and foo: (stderr) to the input.
The calls to the shell built-in command trap make sure that the subshell does not exit when terminating the script with Ctrl+C or by sending the SIGTERM signal using kill $pid. This ensures that your shell won’t forcefully terminate your script because the stdout file descriptor disappears when sed exits because it received the termination signal as well. Effectively you can still use exit traps in your main script and sed will still be running to process any output generated while running your exit traps. The subshell should still exit after your main script ends so sed process won’t be left running forever.
Method 2
You could pipe the output through some way of replacing lines:
some long running stuff | sed -e 's/^/Some said: /;'
Also check 24337
Or just direct separate outputs to separate files/screen(1) tabs/tabs in your terminal/…
Method 3
One option in bash is to do this by redirecting to process substitutions, something like this:
./script.sh > >(sed 's/^/script: /') 2> >(sed 's/^/script (err): /' >&2)
This has the problem that output may be out of order (as Charles Duffy mentioned in a comment). It’s also really annoyingly unweildy. But you could make a wrapper function for it:
prefixwith() {
local prefix="$1"
shift
"<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="082c48">[email protected]</a>" > >(sed "s/^/$prefix: /") 2> >(sed "s/^/$prefix (err): /" >&2)
}
prefixwith "From script" ./script.sh
Or make it even simpler by having it use the command name as a prefix:
prefixoutput() {
local prefix="From ${1##*/}"
"<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6f4b2f">[email protected]</a>" > >(sed "s/^/$prefix: /") 2> >(sed "s/^/$prefix (err): /" >&2)
}
prefixoutput ./script.sh
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0