我知道,采购脚本和执行脚本的唯一区别是,在后一种情况下,父环境不会受到影响。
请考虑以下示例脚本:
SETUP_DIR=`dirname $0`
echo $SETUP_DIR
echo $0
echo $1
上述脚本只是获取正在运行的脚本的目录名称。在尝试获取它时,上面的脚本失败并出现以下错误
$ . test.sh foo
dirname: invalid option -- k
Try `dirname --help' for more information.
-ksh
foo
在我看来,原因在于,当脚本在父环境shell中运行时,shell名称作为第一个参数传递,在本例中为-ksh
。
和dirname -ksh
由于-k
而失败,这是dirname
的无效选项
奇怪的是,在sh或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$
dirname 'sh'
会返回当前目录.
答案 0 :(得分:1)
回答第二个问题,来自man dirname
:
打印NAME,删除其尾随/组件;如果NAME包含否 /'s,输出'。' (意思是当前目录)。
这就是您在运行.
时获得dirname sh
的原因。
我无法在ksh
中重现您的错误。
答案 1 :(得分:1)
所以我想知道,这是玉米壳中已知的记录行为吗?如何解决这个问题?
当/bin/login
将ksh作为登录shell启动时,其$0
将以-
为前缀,因此$0
将为-ksh
而不仅仅是ksh
/bin/ksh
或dirname $0
。 Login does this to indicate to the shell that it is being started as a login shell,因为这通常会影响配置文件加载。
ksh手册记录了它遵守这一惯例:
如果shell由exec(2)调用,并且参数零($ 0)的第一个字符是 - ,则假定shell是登录shell并从[...]
使用bash不会出现连字符前缀,我假设bash正在编辑命令行以阻止它在进程列表中显示。
因此,dirname -ksh
为k
,dirname尝试将其解析为传递s
,h
和dirname
选项
您可以通过--
dirname -- "$0"
显式终止选项解析来解决这个问题,即
dirname
我的第二个通用问题是,为什么dirname'sh'会返回当前目录。
sh
正试图提供帮助并返回一个可用的路径,即使您没有提供路径的目录部分也是如此。由于您的“$ 0”只有一个部分,因此它假设它相对于当前工作目录,即./sh
== .
,并返回{{1}}
根据dogbane的回答记录了这个