How can one avoid printing escape sequences based on the terminal type?
I've written a test script that I usually call from a cygwin bash. This test script colors it's output with escape sequences, i.e.
OKSTRING="\E[32;42mOK \033[39;49m"
echo -e " $OKSTRING开发者_如何转开发"
in case of a success. Actually, the string OK
isn't visible since foreground and background have the same color. So, I just output a green, yellow or red box to indicate the test result.
Now, I want to run the same script as a Hudson build step. The escape codes make the output quite hard readable.
Is there any way that I could influence the printing of the escape codes without having to pass further information to the test script itself?
I know that I could do it using command line parameters and redefine OKSTRING
when I pass a certain parameter. But I'm looking for some easier way (i.e. set some environment variable outside the script and echo
knows that it shouldn't print the escape sequences).
if [ -t 1 ]
then
echo -e "\E[32;42mstdout is a tty"
else
echo "stdout is not a tty"
fi
As I understand your question, in the case you run the script manually from the command line you want to have it print colour codes, while when it is run through the Hudson build server you want it to just print plain text.
You can test if the terminal is considered a tty with the isatty, library call although you might have cases this will not be exactly what you want (i.e. it might miss some cases). Bash provides access to a -t
test
-t fd
True if file descriptor fd is open and refers to a terminal.
Accorting to LDP, the following is the preffered way to test for interactive/non-interactive
if [[ -t 0 || -p /dev/stdin ]]
then
echo interactive
else
echo non-interactive
fi
If you use tput
instead of hard-coding the escape sequences, you can set the TERM
variable to control whether color codes are output. It has the bonus of making the output portable to terminals other than xterm.
$ printf '%s\n%s\n' "setaf 2" "setab 2" | tput -S; echo -n hi; tput sgr0; echo
[green box]
$ (TERM=dumb; printf '%s\n%s\n' "setaf 2" "setab 2" | tput -S; echo -n hi; tput sgr0; echo)
hi
The second one is run in a subshell so TERM
returns to its previous value when the subshell exits.
In order to avoid repeatedly calling tput
, you can call it just a few times at the beginning of your script and set variables to hold the sequences:
allgreen=$(printf '%s\n%s\n' "setaf 2" "setab 2" | tput -S)
none=$(tput sgr0)
echo "${allgreen}hi${none}"
Then you can call your script in a subshell or prepend the variable assignment (or save and restore TERM
yourself).
$ TERM=dumb ./your_script
That makes the assignment local to that invocation.
To be more robust, you need detect both interactivity and terminal capabilities. The -t
test detects the interactivity. The tput
detects the terminal capabilities:
[[ -t 1 ]] || export TERM=dumb
CYAN=$(tput setf 3)
GRAY=$(tput setf 7)
echo ${CYAN}COLORED TEXT${GRAY}
This way only you detect interactivity while in reality you should detect both interactivity (through -t
and terminal capabilities (through $TERM
/tput
).
精彩评论