The only difference in Sourcing a Script and Executing it, I was aware of, is in the later case, the parent environment remains unaffected.
Consider this sample Script:
SETUP_DIR=`dirname $0`
echo $SETUP_DIR
echo $0
echo $1
The above script simply fetches the directory name of the running script. While trying to source it, the above script fails with the following error
$ . test.sh foo
dirname: invalid option -- k
Try `dirname --help' for more information.
-ksh
foo
The reason what it seems to me is, when sourcing it, as the script runs in the parent environment shell, the shell name is passed as the first argument, in this case its -ksh.
and dirname -ksh fails because of an -k, which is an invalid option for dirname
Strangely, this problem is not there while running in sh or bash
$ sh
sh-3.2$ . test.sh foo
.
sh
foo
sh-3.2$ bash
bash-3.2$ . test.sh foo
.
bash
foo
bash-3.2$
- So I was wondering, is it a known documented behavior in KornShell (ksh)? How to resolve this issue?
- My second generic question is, why does
dirname 'sh'returns the current directory.
When ksh is started as a login shell by
/bin/login, its$0will be prefixed with-, so$0will be-kshinstead of justkshor/bin/ksh. Login does this to indicate to the shell that it is being started as a login shell, as this typically affects profile loading.The ksh manual documents its adherence to this convention:
The hyphen prefix doesn’t show up for me with bash, I assume that bash is editing the command line to stop it from being visible in the process listing.
As a result,
dirname $0isdirname -ksh, and dirname tries to parse that as passing thek,sandhoptionsYou can get around this by explicitly terminating options parsing by
dirnamewith--, i.e.dirnameis trying to be helpful and return a usable path even when there is no directory part of the path you’re giving it. Since your “$0” only has one part, it assumes it is relative to the current working directory, i.e.sh==./sh, and returns the.This is documented as per dogbane’s answer