Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 寻找脚本源并在KornShell上执行脚本时的行为差异_Linux_Bash_Shell_Scripting_Ksh - Fatal编程技术网

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