Check if there is an stdout redirection in bash script
You can check if stdout is a terminal. When stdout is redirected or piped it will not be a terminal. You can use the test command with the -t
option to get this information:
if [ -t 1 ] ; then
# stdout is a terminal
else
# stdout isn't a terminal
fi
From man test
:
-t FD file descriptor FD is opened on a terminal
Test stdout and stderr redirection in bash script
You should be able to use the -t
test switch to tell if the output streams are tty
s or not:
if [ -t 1 ] ; then
echo stdout is a terminal
else
echo stdout is not a terminal
fi
Use -t 0
for stdin
.
Use -t 2
for stderr
.
Redirecting stdout and stderr to variable within bash script
If you want to redirect for the entirety of your code, instead of using blocks, use the exec
command. That is:
stdout_file="/some/path/$1/timestamp.stdout" # Creating job-id specific folders
stderr_file="/some/path/$1/timestamp.stderr"
exec >"$stdout_file" 2>"$stderr_file"
# ...all code below this point has stdout going to stdout_file, and stderr to stderr_file
Shell redirection: Command doesn't appear to output to stdout or stderr
@Gordon Davisson is right on the money. It appears the output was being sent directly to /dev/tty, which apparently is a thing people do... Thanks, Gordon!
Update: Upon further tinkering and input from others, it looks like the important part is using script
to capture all the output. Additional redirection (ie. 2>&1
) is not necessary, but can be done if need be. Continue below to see it in action.
Here's my basic code:
The binary app that sends data to /dev/tty is called 'binApp', and let's say it takes an arbitrary number of command line arguments. My wrapper/watcher script will be run with binApp and all its args, like so:
WrapScript binApp arg1 arg2 ... argn
WrapScript:
#!/bin/bash
args=("$@")
cmd=`echo "${args[@]:0}"`
run() {
script -q -c "$cmd" 2>&1 | while read -r line; do
if [ "$line" = "$badthing" ]; then
echo "restarting..."
break
fi
echo "$line"
done
}
badthing="ERROR"
while true; do
run
sleep 0.5
done
The sleep 0.5
allows user to press "Ctrl+c" twice to exit.
Redirect stdout / stderr to bash script
You can use xargs to move data from a pipe into an argument:
java -jar build/libs/bot-kt-1.1.3.jar 2>&1 | xargs ./script.sh
to pass everything as a single argument:
java -jar build/libs/bot-kt-1.1.3.jar 2>&1 | xargs --null ./script.sh
Check if script has been redirected
You can use -t
option of bash:
-t fd True if file descriptor fd is open and refers to a terminal.
And check like this:
if [[ -t 1 ]]; then
# console is attached
else
# Redirected to somewhere
fi
Redirect stderr and stdout in Bash
Take a look here. It should be:
yourcommand &> filename
It redirects both standard output and standard error to file filename.
Redirect STDOUT by variable in Bash
bash
will recognize a file name of /dev/stdout
as standard output, when used with a redirection, whether or not your file system has such an entry.
# If an argument is given your script, use that value
# Otherwise, use /dev/stdout
out=${1:-/dev/stdout}
zip bar.zip foo > "$out"
Related Topics
Difference Between Completion Variables and Semaphores
How to Repeat a Dash (Hyphen) in Shell
Using Perf to Monitor Raw Event Counters
Grep String Inside Double Quotes
Determine the Os Version, Linux and Windows from Powershell
How to Identify Multiple Usb-Serial Adapters Under Ubuntu 10.1
When Should Xargs Be Preferred Over While-Read Loops
Nasm Linux Assembly Printing Integers
What's the Best Way to Find a String/Regex Match in Files Recursively? (Unix)
Hook into Linux Key Event Handling
How to Use Awk for a Compressed File
How to Use Git Namespace to Hide Branches