1

I know what bash -x does, but what does bash +x do?

Googling found no results and the manual also says nothing about it.

Kusalananda
  • 333,661
  • "Using + rather than - causes these options to be turned off." But it's kinda pointless, since it's off by default anyway. I'm going to guess it was a typo and whoever wrote intended to use -x – muru Apr 24 '22 at 05:57
  • @muru I was first thinking it would negate any xtrace in SHELLOPTS, present in the environment when bash started, but it doesn't. So I'm also unable to find a real use for bash +x. It's probably there for symmetry with all other (short) shell options. – Kusalananda Apr 24 '22 at 06:20
  • 2
    @Kusalananda, processing options is what bash does first, so +x won't be able to cancel a set -x done by a $BASH_ENV file or SHELLOPTS=xtrace. In any case, I wouldn't call it a duplicate as it would make sense to clarify those things here. – Stéphane Chazelas Apr 24 '22 at 06:35
  • @StéphaneChazelas I agree. Reopened. Feel free to provide an answer. – Kusalananda Apr 24 '22 at 06:39

1 Answers1

5

-x, same as -o xtrace enables the xtrace option.

+x, same as +o xtrace disables it.

Those options can be passed to the interpreter for those options to be enabled / disabled upon start or to set (set -o xtrace / set -x / set +o xtrace / set +x) for them to be enabled / disabled at runtime.

In the case of the xtrace option however, that option is not enabled by default, and since bash processes command line options before the $SHELLOPTS env variable, or the initialisation file whose path is stored in $BASH_ENV, calling bash with the +x option is pointless:

$ cat env
set -o xtrace
$ BASH_ENV=env bash +x -c 'echo foo'
+ echo foo
foo
$ env SHELLOPTS=xtrace bash +x -c 'echo foo'
+ echo foo
foo

In both cases, +x was not able to cancel the set -o xtrace set by $BASH_ENV or $SHELLOPTS.

It would only be effective after a -x or -o xtrace:

$ bash -x +x -c 'echo foo'
foo

So one case where bash +x ./script.sh¹ could make sense would be if you had a alias bash='bash -x' (unlikely).

You could do however:

$ bash +B -c 'echo {a,b}'
{a,b}

To disable the braceexpand option which is enabled by default.

Or you could do:

$ env SHELLOPTS=xtrace bash -c 'set +x; echo foo'
+ set +x
foo

To disable xtrace after it was enabled upon processing $SHELLOPTS.


¹ note the ./ which is required to prevent bash from looking for script.sh in $PATH when it can't be found in the current directory.