If I run set -x and then run a script in a shell, the option set by set -x doesn't work inside the script.

I was wondering if all the shell options are not inherited by scripts?

I didn't find this is mentioned in bash manual. The only relevant that I found is "Unless otherwise noted, the values are inherited from the shell." So I guess shell options are inherited. Do I miss it in the manual?

I have read a related question which asked how to let scripts inherit shell options. I was wondering whether and why instead of how.


When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following. Unless otherwise noted, the values are inherited from the shell.

• the shell’s open files, plus any modifications and additions specified by redirections to the command

• the current working directory

• the fi le creation mode mask

• shell variables and functions marked for export, along with variables exported for the command, passed in the environment (see Section 3.7.4 [Environment], page 37)

• traps caught by the shell are reset to the values inherited from the shell’s parent, and traps ignored by the shell are ignored A command invoked in this separate environment cannot aff ect the shell’s execution environment.

  • 1
    No shell options are inherited. There's no readily available underlying mechanism that could facilitate such inheritance (well export - could be made to provide that through an environment variable, but I'm not aware of any shell that implements that. I also don't think implementing it would be a good idea).
    – PSkocik
    Aug 19 '17 at 19:40
  • 3
    @PSkocik, in bash, you can have options inherited with the $SHELLOPTS (for the set -o ones) and $BASHOPTS (for the shopt ones). Try env SHELLOPTS= bash -xc 'bash -c :' and see how the second bash inherited the xtrace option set by the first one. Aug 21 '17 at 22:43
  • @StéphaneChazelas Good to know. Thanks for the info.
    – PSkocik
    Aug 21 '17 at 22:47

In the case of bash, that depends on whether $SHELLOPTS is in the environment or not.

bash-4.4$ export SHELLOPTS
bash-4.4$ set -x
bash-4.4$ bash -c 'echo x'
+ bash -c 'echo x'
+ echo x

See how the bash -c 'echo x' inherited the xtrace option. For the options set by shopt, it's the same but with the $BASHOPTS variable.

It comes handy especially for the xtrace option for debugging when you want to run a bash script (or any command running a bash script) and all other bash script it may invoke, recursively with xtrace (provided nothing does a set +x in those scripts). If your sh is bash, that will also affect them, so also the system("command line") made in other languages:

env SHELLOPTS=xtrace some-command

You could call scripts (or a shell with a command line) explicitly with options:

shopt -s expand_aliases
alias shell_call='bash -$-'
shell_call /path/to/script

Changes to the script would automatically be passed to child shells. This approch does only turn features on, though.

  • 2
    You mean bash -$- so you're passing the options as options instead of attempting to run a file named "$-" Aug 19 '17 at 21:11
  • Thanks, Hauke! I wonder if I misunderstand the manual? It doesn't explicitly mention set options, so I think "Unless otherwise noted, the values are inherited from the shell" applies to set options. Am I missing something?
    – Tim
    Aug 21 '17 at 0:43
  • @Tim I guess your misunderstanding is "execution environment". The environment is external to a running binary, the shell options are internal. This paragraph is about simple commands in general. Calling a shell explicitly is a very special case. Aug 21 '17 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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