Linux 寻找脚本源并在KornShell上执行脚本时的行为差异
我知道,在获取脚本和执行脚本方面的唯一区别是,在后一种情况下,父环境不受影响 考虑以下示例脚本:Linux 寻找脚本源并在KornShell上执行脚本时的行为差异,linux,bash,shell,scripting,ksh,Linux,Bash,Shell,Scripting,Ksh,我知道,在获取脚本和执行脚本方面的唯一区别是,在后一种情况下,父环境不受影响 考虑以下示例脚本: 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 在
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$
- 所以我想知道,这是KornShell(ksh)已知的记录行为吗?如何解决这个问题
- 我的第二个一般性问题是,为什么
返回当前目录dirname'sh'
man dirname
:
删除尾随/组件后打印名称;如果名称不包含
/s,输出“”(表示当前目录)
这就是为什么运行dirname sh
时会得到
我无法在ksh
中重现您的错误
所以我想知道,这是玉米壳中已知的记录行为吗?如何解决这个问题
当ksh由/bin/login
作为登录shell启动时,它的$0
将以-
作为前缀,因此$0
将是-ksh
而不仅仅是ksh
或/bin/ksh
,因为这通常会影响配置文件加载
ksh手册记录了其遵守本公约的情况:
如果shell由exec(2)调用,并且参数零($0)的第一个字符是-,则假定shell是登录shell,并且从[…]读取命令
连字符前缀在bash中没有出现,我假设bash正在编辑命令行以阻止它在进程列表中可见
因此,dirname$0
是dirname-ksh
,dirname试图在传递k
、s
和h
选项时解析它
您可以通过使用--
显式终止选项解析来绕过此问题,即
dirname -- "$0"
我的第二个一般性问题是,为什么dirname'sh'返回当前目录
dirname
试图提供帮助并返回可用路径,即使您提供的路径中没有目录部分。由于“$0”只有一个部分,因此它假定它与当前工作目录相关,即sh
==/sh
,并返回
这是根据dogbane的答案记录的我无法重现您的错误。
dirname-ksh
是否适合您?哪个dirname
给了你什么?@dogbane:dirname-ksh
不起作用,正如我在问题中提到的那样失败了。我在问题本身中更新的其他相关信息。有趣。我想这会抑制我现在的好奇心。感谢您的帮助当我运行dirname-ksh
时,我得到了
@dogbane您可能会有一个不同的dirname
实现,例如作为shell内置。我的是gnu Coreutilsi的/usr/bin/dirname
,可能是因为我的是旧版本(5.2.1)。@dogbane是的,可能是。--
选项解析终止是否适用于您,即dirname--a/b
=a
?