Include other shell script to current shell script

Dear All,

After upgrading to 11.2, I found that the shell script will not able to find other included shell scripts unless the path of the included shell scripts are specified.

eg.
[original]
. test.sh

[now]
. ./test.sh

The BASH version in 11.2 is
GNU bash, version 4.0.33(1)-release (i586-suse-linux-gnu)

Does anybody encounter this problem too?

I’m not on 11.2 so can’t test for you, but have you tried with source ? eg, source test.sh

You may want to report this to Novell’s bugzilla

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Is ‘test.sh’ in your path? If it is not then that should not work, but if
it is then I imagine it should work. Compare where it is (post its
location in the directory structure) with your environment’s path:

echo $PATH

Good luck.

knightchang wrote:
> Dear All,
>
> After upgrading to 11.2, I found that the shell script will not able to
> find other included shell scripts unless the path of the included shell
> scripts are specified.
>
> eg.
> [original]
> . test.sh
>
> [now]
> . ./test.sh
>
> The BASH version in 11.2 is
> GNU bash, version 4.0.33(1)-release (i586-suse-linux-gnu)
>
> Does anybody encounter this problem too?
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJLAU5YAAoJEF+XTK08PnB5SmQP/jBatLruv2HLppbFIrCBEyDA
Oemdqj1EpmjwGRCP7XB1FAw4KfW350fQnubZSiS6hOmGct1q/iRx33FpsVsYYKfD
G4aMawdorpN6ftjaVQEnOJlrpZBnkPhm/TNdesUOIEE0Z84/Y9bPU3ILE45qlrsL
2VMJdUTwY8h3DYsKAwZCH4dRDdLfZr0bY08Z2pqCZ7MAElc6ViTFUTvcqWh8urOV
hWdMrkr8Gb+C+AnjvEIrP9a1Qj7wXDq/VyRy1TpbPP+ajaoJkPbfmDlqWo/AUvNe
nbsYeEJmYW10RxTUGK5gBPuwUoQ36u7ZbtmAXQa1b7EPUNRuUTH/NEnLAy+8yGbq
MyJIeFlEWGmbbJypn1lhDkEWpQkMB/HVOc9x6WeOQBC0Z7PDUASa79a0rr6ua2Eg
yP0F5WqYfNByq7ROWUyMcOydsIMF5fUd5u8MYBZYQgutB6zGzIw14v49g7f5DIL4
eIQXJs4xfcUpqp+CN1f1fOfhiYYapDbr8FLWYIUEuhxoPI8f6Dy2NwydsmklzUJD
PKKxLEVbNYWAOWDZXWgMZAt/XrsdnOiOv8kP7SnZKMFjgn6xaCe0bxtRRc8s2RJ9
t/GD1kv/parlEjuT1TwKmb2TwhIk5CTd4JUAU0AuPPFf1JlXkNwe7+/Ny+iCvCph
vtxmzrTi+BKgpXt92iaA
=LuWb
-----END PGP SIGNATURE-----

Depending on the mode it should find the script in the current directory as well, even if it is not in the PATH. The relevant snippet from the man page:

If filename does not contain a slash, file names in PATH are used to find the directory containing filename. The file searched for in PATH need not be executable. When bash is not in posix mode, the current directory is searched if no file is found in PATH. If the sourcepath option to the shopt builtin command is turned off, the PATH is not searched.

I just tried this in 10.3 and 11.2. Both work as expected.

The construction

. test

is the same as

source test

From man bash:

. filename [arguments]
source filename [arguments]
Read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename. If filename does not contain a slash, file names in PATH are used to find the directory containing filename. The file searched for in PATH need not be executable. When bash is not in posix mode, the current directory is searched if no file is found in PATH. If the sourcepath option to the shopt builtin command is turned off, the PATH is not searched. If any arguments are supplied, they become the positional parameters when filename is executed. Otherwise the positional parameters are unchanged. The return status is the status of the last command exited within the script (0 if no commands are executed), and false if filename is not found or cannot be read.

The red part might be of interrest here.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

So, is bash in posix mode? I see how to load it that way but haven’t seen
how to verify an existing shell is or isn’t. Either way using at least ./
should probably be used to prevent unexpected behaviors.

Good luck.

vodoo wrote:
> Depending on the mode it should find the script in the current directory
> as well, even if it is not in the PATH. The relevant snippet from the
> man page:
>
>> If filename does not contain a slash, file names in PATH are used to
>> find the directory containing filename. The file searched for in PATH
>> need not be executable. When bash is not in posix mode, the current
>> directory is searched if no file is found in PATH. If the sourcepath
>> option to the shopt builtin command is turned off, the PATH is not
>> searched.
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJLAVngAAoJEF+XTK08PnB5DN8P/1LR72SJzYF5mfqRKQ4tHYYJ
nAjxQ1ga0I6+yUneS+t/fnDkQSEEEHqHaice6qqgVsw0ogLbgpF/+H6p4+WrpL3v
6SY0If2H3mReoOQj/kTyntXoryyeHanzgUUwHz9xP7yKbwA2n0zuEMPbqhXUcbw2
s5J5/9WuoN75vawybeKgiDrGXFcUtGDWdACLEzFSKH5uLrsMAJnWd7gvr0esLz45
R6F9/a9vAxE3nXOLGHZuh1hvbcDvjQI1OQ0IHE+gea1jvv7him/8+g9pLTVJrPNw
VZcQYNwUoxQO5tEshmtOF/zw8sTX2E52aWALkeJctjq9Jbwi9wDkdpJF9DWnovuY
6ZZVzcWxrSKtDCvO+zDBPbZU7SAzwnMeWtnWQh1KOLfyLrALkFKrNLaK3zgl8SGV
X6vNDsebUoP41+bNsFWDJu5sMj048wsN9XwFFYD6UVinaOfDVhT7gh4He9NpvVKS
b0ocNlNjqmW106FJvrRRgd+4EKyfLWfEZLE8h3OkzFQniVDUsktDfDP1pK/tuAUY
j4yl8tdvDDoAe7Q1HjeBVr3wMQ5NSxRR823SCYgSW+1/6da4m5PPw89pOC8ZZAEq
aOFpeQKVjx8DEzqWOvayz3vScw9Fxxryvnrl8Mbsr1KKWepvRMYsxKsf/xdRH1zq
l80pA8DKcHVOvXsrROZ+
=uMvw
-----END PGP SIGNATURE-----

Not in my 11.2 install. As said they work the same with me in 10.3 and 11.2, without the ./ .
I only hope the OP can find something with this info. in mind. Is he in Posix mode for some reason? I would not even know how to reach Posix mode :slight_smile:

Another wisdom from the bash manpage:

When invoked as sh, bash enters posix mode after the startup files are read.

That means that the OP should check if he has the current directory in his path and how bash is invoked.

It means that he should check his shebang!
It should be:

#!/bin/bash

and not:

#!/bin/sh

Hi All,

Many thanks for your prompt response to my problem.
Let me detail the script I am testing.
test.sh

#!/bin/sh
echo $PATH
echo pwd
source config.sh

config.sh

BUILD_LLAL=LLAL

I am very sure test.sh and config.sh are existing in the same directory and /bin/sh or /usr/bin/sh both are linked to /bin/bash. And then I execute the following command

./test.sh

It returns me the following messages and error.

/home/abc/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/opt/kde3/bin:/usr/lib/jvm/jre/bin:/usr/lib/mit/bin:/usr/lib/mit/sbin
/home/abc
./test.sh: line 4: source: config.sh: file not found

No matter what I use “.” or “source” to include another script, I always get the error.
After changing the shebang from #!/bin/sh to #!/bin/bash as hcw mentioned, it works.

I also dump my environment setting here

LESSKEY=/etc/lesskey.bin
NNTPSERVER=news
MANPATH=/usr/local/man:/usr/share/man
HOSTNAME=buildbed
XKEYSYMDB=/usr/share/X11/XKeysymDB
HOST=buildbed
TERM=xterm
SHELL=/bin/bash
PROFILEREAD=true
HISTSIZE=1000
SSH_CLIENT=x.x.x.x 1202 22
MORE=-sl
SSH_TTY=/dev/pts/1
JRE_HOME=/usr/lib/jvm/jre
USER=abc
LS_COLORS=no=00:fi=00:di=01;34:ln=00;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=41;33;01:ex=00;32:.cmd=00;32:.exe=01;32:.com=01;32:.bat=01;32:.btm=01;32:.dll=01;32:.tar=00;31:.tbz=00;31:.tgz=00;31:.rpm=00;31:.deb=00;31:.arj=00;31:.taz=00;31:.lzh=00;31:.lzma=00;31:.zip=00;31:.zoo=00;31:.z=00;31:.Z=00;31:.gz=00;31:.bz2=00;31:.tb2=00;31:.tz2=00;31:.tbz2=00;31:.xz=00;31:.avi=01;35:.bmp=01;35:.fli=01;35:.gif=01;35:.jpg=01;35:.jpeg=01;35:.mng=01;35:.mov=01;35:.mpg=01;35:.pcx=01;35:.pbm=01;35:.pgm=01;35:.png=01;35:.ppm=01;35:.tga=01;35:.tif=01;35:.xbm=01;35:.xpm=01;35:.dl=01;35:.gl=01;35:.wmv=01;35:.aiff=00;32:.au=00;32:.mid=00;32:.mp3=00;32:.ogg=00;32:.voc=00;32:*.wav=00;32:
XNLSPATH=/usr/share/X11/nls
ENV=/etc/bash.bashrc
HOSTTYPE=i386
FROM_HEADER=
PAGER=less
CSHEDIT=emacs
XDG_CONFIG_DIRS=/etc/xdg
MINICOM=-c on
MAIL=/var/mail/abc
PATH=/home/abc/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/opt/kde3/bin:/usr/lib/jvm/jre/bin:/usr/lib/mit/bin:/usr/lib/mit/sbin
CPU=i686
JAVA_BINDIR=/usr/lib/jvm/jre/bin
INPUTRC=/home/abc/.inputrc
PWD=/home/abc
JAVA_HOME=/usr/lib/jvm/jre
LANG=en_US.UTF-8
PYTHONSTARTUP=/etc/pythonstart
QT_SYSTEM_DIR=/usr/share/desktop-data
SHLVL=1
HOME=/home/abc
LESS_ADVANCED_PREPROCESSOR=no
OSTYPE=linux
LS_OPTIONS=-N --color=tty -T 0
XCURSOR_THEME=DMZ
WINDOWMANAGER=/usr/bin/startkde
G_FILENAME_ENCODING=@locale,UTF-8,ISO-8859-15,CP1252
LESS=-M -I
MACHTYPE=i686-suse-linux
LOGNAME=abc
CVS_RSH=ssh
XDG_DATA_DIRS=/usr/share:/etc/opt/kde3/share:/opt/kde3/share
SSH_CONNECTION=x.x.x.x 1202 y.y.y.y 22
LESSOPEN=lessopen.sh %s
LESSCLOSE=lessclose.sh %s %s
G_BROKEN_FILENAMES=1
JAVA_ROOT=/usr/lib/jvm/jre
COLORTERM=1
_=/usr/bin/printenv

Hi All,

After google-ing this problem, I found some explanations.
When invoked as sh, BASH enters POSIX mode after reading
the startup files. I don’t have any idea if it is a bug
in the previous version (likely in version 3.x), BASH will
search the current directory even it is in POSIX mode.
But in the version after 4.0, this behavior is corrected.
The .' and source’ builtins do not search the current
directory for the filename argument if it is not found by
searching `PATH’.

I think this problem is solved.
Many thanks to you.

So why is it called a ‘shebang’? Is that just another cute gnu pun on ‘the whole shebang’?

I get ! is called a bang (I think perhaps particularly in the states), but ‘she’?

So where does crunch bang (as in crunchbang linux) fit in?

…you can’t hijack a thread once it’s done, can you? :)]

ETA: Ah! Isn’t google clever…

http://wiki.linuxquestions.org/wiki/Shebang

Not sure if I believe that though. Maybe makes more sense that /bin/sh is the ‘sh’?

Here’s a more comprehensive set of theories:

http://en.wikipedia.org/wiki/Shebang_(Unix)

Personally I think it’s a contraction of shell-bang.

As a bit of trivia, the magic numbers on executables in V7 Unix were exactly the PDP11 opcodes needed to jump past the binary header.

A short recap.

Technical.
One can of course make links (hard or symbolic) to an executable program (scripts included). Look at these:

boven:/bin # l *sh
-rwxr-xr-x 1 root root 604040 Sep 22  2007 bash*
lrwxrwxrwx 1 root root      4 Jan 12  2008 csh -> tcsh*
lrwxrwxrwx 1 root root     16 Jan 12  2008 ksh -> /lib/ast/bin/ksh*
-rwxr-xr-x 1 root root  14669 Sep 22  2007 rescan-scsi-bus.sh*
-rwxr-xr-x 1 root root 641612 Sep 22  2007 sash*
lrwxrwxrwx 1 root root      4 Jan 12  2008 sh -> bash*
-rwxr-xr-x 1 root root 318908 Dec 21  2007 tcsh*
-rwxr-xr-x 1 root root 534900 Sep 23  2007 zsh*
boven:/bin #

and these:

boven:/bin # ls -l ex vi vim
lrwxrwxrwx 1 root root  3 Mar 11  2009 ex -> vim
lrwxrwxrwx 1 root root  3 Mar 11  2009 vi -> vim
lrwxrwxrwx 1 root root 21 Mar 11  2009 vim -> /etc/alternatives/vim
boven:/bin # l /usr/bin/view
lrwxrwxrwx 1 root root 3 Mar 11  2009 /usr/bin/view -> vim*
boven:/bin # 

Let us take the vi/ex example. Apperently when one calls either vi or ex the same program will be started but when you do this you will see a different behaviour. How is this achieved? The program itsef tests on the value of argument 0 (zero) to see how it is provoked. In the case of

vi -e file

the respective arguments are:
0: vi
1: -e
2: file
In a bash script you have access to them using ${0}, ${1} and ${2} (or $0, $1 and $2 when you are in a hurry).
Thus the program knows how it is called and can behave accordingly.

Now we know how it is possible that sh and bash behave different in spite of being the same execitable file.

What did knightchang do? He wrote a sh (Posix shell) script. That is proven by the fact that he started it with

#!/bin/sh

This means of course that he should have written this with all the syntactic and other rules of the Posix shell in mind (who does :wink: ). He made a mistake in forgetting about the rules used during ‘sourcing’. And yes, seamingly there is a bug in an earlier version of that shell,: it behaves as if it is the Borne Again shell.

Now there is a change that knightchang in fact tried to write a flawless Borne Again shell cript. In which case his only error was the wrong shebang.
There is also the change that he mixe up the rules for bash and sh in his script, in which case he has to decide what language he wants to use and he has to correct his program so it conforms to the chosen language.

The word ‘shebang’.
I used the word ‘shebang’ because I hoped that everybody writing scripts would know what it is and how important it is. About the etymology of shebang I refer to the links given above (Wikipedia) for what it is worth. (I always thought that it was the #! that made the sound)