我注意到,在源文件和执行脚本方面唯一的区别是,在后面的情况下,父环境仍然不受影响。
考虑下面的示例脚本:
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'
返回当前目录.
发布于 2012-12-17 02:17:47
所以我想知道,这是玉米壳中已知的一种行为吗?如何解决这一问题?
当/bin/login
以登录shell的形式启动ksh时,它的$0
将以-
作为前缀,因此$0
将是-ksh
而不是ksh
或/bin/ksh
。登录是为了向shell表示它是作为登录shell启动的。,因为这通常会影响配置文件加载。
ksh手册记录了它遵守本公约的情况:
如果shell由exec(2)调用,且参数0 ($0)的第一个字符是-,则假定shell是登录shell,并从.
连字符前缀没有出现在bash中,我假设bash正在编辑命令行,以防止它在进程列表中可见。
因此,dirname $0
是dirname -ksh
,dirname试图将其解析为传递k
、s
和h
选项。
您可以通过使用dirname
显式终止--
解析选项来解决这一问题。
dirname -- "$0"
我的第二个一般性问题是,为什么dirname 'sh‘返回当前目录。
dirname
试图提供帮助并返回一个可用的路径,即使在您所提供的路径中没有目录部分时也是如此。因为您的"$0“只有一个部分,所以它假设它相对于当前的工作目录,即sh
== ./sh
,并返回.
这是根据dogbane的回答记录下来的
发布于 2012-12-17 02:11:31
回答你的第二个问题,来自man dirname
删除其尾部/component的打印名称;如果名称不包含/'s,输出‘。(意思是当前目录)。
这就是在运行.
时获得dirname sh
的原因。
我无法在ksh
中复制您的错误。
https://stackoverflow.com/questions/13911886
复制