3

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.

Thanks.

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.

3
  • 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). Aug 19, 2017 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, 2017 at 22:43
  • @StéphaneChazelas Good to know. Thanks for the info. Aug 21, 2017 at 22:47

2 Answers 2

6

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
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
0
4

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.

3
  • 2
    You mean bash -$- so you're passing the options as options instead of attempting to run a file named "$-" Aug 19, 2017 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, 2017 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, 2017 at 8:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .