Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is it possible to test whether a bash script was executed with -x?

I'm writing a script which also runs some remote scripts, and I'd like to be able to do something like:

USE_X="$( run_with_x && "-x" || "" )"
ssh $host "bash $USE_X some_script.sh"
share|improve this question

4 Answers 4

Just look at the $- variable.

USE_X=`case "$-" in *x*) echo "-x" ;; esac`

(Yup, I did manage to do that without invoking grep. Save the pids!)

share|improve this answer
    
what does *x* expand to? –  bbaja42 Oct 3 '11 at 6:55
2  
What a waste of pid! case $- in *x*) USE_X="-x";; *) USE_X=;; esac @bbaja42 It doesn't expand to anything: it's a pattern that the string $- is matched against. –  Gilles Oct 3 '11 at 21:08
    
@Gilles Your example also contains unnecessary part: *) USE_X=;; changes nothing, if USE_X was not set previously. Also, the whole case construct is unnecessary (see my version - isn't that simpler?) –  rozcietrzewiacz Oct 4 '11 at 16:12
    
@rozcietrzewiacz This part is unnecessary if USE_X has been initialized earlier on. I don't consider your version simpler: it's a few characters shorter (and even then only if USE_X has been initialized, otherwise it's longer), but at the expense of clarity and portability. –  Gilles Oct 4 '11 at 17:11
    
@Gilles Portability is not the subject of this question, it is about bash. Initializing USE_X is not necessary for the purpose of OP's intended use (to pass $USE_X to further scripts). Using case construct looks less clear and natural than a regular condition evaluation in my view. –  rozcietrzewiacz Oct 4 '11 at 17:53

After reading man pages and grepping for things, here's the solution:

$ cat show_x.sh
#!/bin/bash
if [ "$(set | grep xtrace)" ]; then
    echo "xtrace is on. :D"
else
    echo "xtrace is off. :("
fi

Result:

$ bash show_x.sh 
xtrace is off. :(

$ bash -x show_x.sh 
++ set
++ grep xtrace
+ '[' SHELLOPTS=braceexpand:hashall:interactive-comments:xtrace ']'
+ echo 'xtrace is on. :D'
xtrace is on. :D
share|improve this answer

The bash man page documents set -o xtrace as equivalent to set -x, which in turn is equivalent to giving -x as an argument to the shell. (So far, this is compatible with SUSv3 sh, with the caveat that -o option is required "if the system supports the User Portability Utilities option".)

Also, set -o without an option prints the current status of all of the -o options. (SUSv3 specifies this as well, but not usefully; the format is unspecified, so you can only depend on it if you know you're running a shell that uses a format similar to bash's.)

So, the pipeline set -o | grep xtrace | grep -q on should be what you're looking for.

share|improve this answer

Probably the simplest way of parsing $-, similar to dagbrown's method (also pure bash), but without using case and backticks (subshell):

if  [[ ${-/x} != $- ]] ; then USE_X="-x"; fi

or even shorter:

[[ ${-/x} != $- ]] && USE_X="-x"

Note that [[ is not an invocation of test builtin program (as is the case with [), but a bash syntax construct (according to man bash and this dev recommendation). So I claim it to be "purer bash" ;)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.