4

I have two scripts that need to run and both require the same variables set the same way. As a result I figured I'd break the setting of the variables out into a separate script. However, I can't seem to get this to work right where the variables are showing in the main script.

For example, this is my main script:

#!/bin/sh

. ./vars

printenv

This is what I have in the script "vars":

#!/bin/sh
MYVAR=MYVAL

echo "EXECUTED!!"

In the output, I successfully see "EXECUTED!!", but the variable MYVAR is not set to anything.

EXECUTED!!
MAIL=/var/mail/testuser
SSH_CLIENT=192.168.110.1 62953 22
USER=testuser
SHLVL=1
HOME=/home/testuser
OLDPWD=/home/testuser/test
SSH_TTY=/dev/pts/0
LOGNAME=testuser
_=./mainScript
TERM=xterm
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
LANG=en_US.UTF-8
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:
SHELL=/bin/bash
PWD=/home/testuser
SSH_CONNECTION=192.168.110.1 62953 192.168.110.133 22
10

Sourcing your script only sets shell variables, while printenv shows environment variables. You will have to export the variables for printenv to show them. You may have meant to use set instead, which will show shell variables.

You could have made this script:

#!/bin/sh
export MYVAR=MYVAL

echo "EXECUTED!!"

(given that you are using bash, the export works with an assignment as shown).

By the way: when you source a file, shells do not pay any attention to the hashbang line #!/bin/sh: that is the province of the kernel in any case, except obliquely. Oddly enough, that is not mentioned in the manual page. You can see this by making two files, say "foo" and "bar":

#!/bin/bash
echo "outer $0 $SHELL"
. ./bar
printenv |fgrep MYVAR

and

#!/bin/sh
echo "inner $0 $SHELL"
export MYVAR=$MYVAL

to see that the shell variables (such as $0) are the same within the sourced file, and that the shell features are unaffected.

I add that line anyway, to help with syntax highlighting.

  • Sure enough, I tried: echo $MYVAR And it works... I can't believe that's actually it. What a stupid mistake on my part. Thanks for your help! I'll accept this once it lets me do so. – Doug May 4 '16 at 0:02
  • He does explicitly use /bin/sh; Even if that is (currently) linked do bash (would be dash on Ubuntu, I think), I think bash takes some care to behave like sh if called by the name 'sh'. So, the right way for /bin/sh would be MYVAR=MYVAL; export MYVAR; – Volker Siegel May 4 '16 at 4:19
10

The variable is available in the main script, since you used . (the dot builtin, also known as source in some shells). . ./vars executes vars in the context of the calling script.

Your problem is that you're using printenv to check, but printenv only prints environment variables, not shell variables. Environment variables are managed by the operating system and seen by child processes. Shell variables are a feature of the shell programming language and managed by the shell alone.

All environment variables automatically become shell variables¹, but shell variables are only shell variables unless explicitly exported, which makes them environment variables as well.

To check what variables are defined, use the set builtin. This will list MYVAR.

To export a variable, use the export builtin. Do that if you want the variable to be visible by other programs started from the shell.

export MYVAR

¹ Unless their name doesn't match the requirements for a shell variable.

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.