0

我知道,采购脚本和执行脚本的唯一区别是在后一种情况下,父环境不受影响。

考虑这个示例脚本:

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'返回当前目录.
4

2 回答 2

1

回答您的第二个问题,来自man dirname

打印 NAME 并删除其尾随 / 组件;如果 NAME 不包含 /,则输出 '.' (表示当前目录)。

这就是为什么你.在跑步时得到的原因dirname sh

我无法在 中重现您的错误ksh

于 2012-12-17T10:11:31.057 回答
1

所以我想知道,这是玉米壳中已知的记录行为吗?如何解决这个问题?

当 ksh 作为登录 shell 由 启动时/bin/login,它的$0前缀将是-,因此$0将是-ksh而不是只是kshor /bin/kshLogin 这样做是为了向 shell 表明它正在作为登录 shell 启动,因为这通常会影响配置文件加载。

ksh 手册记录了它对这个约定的遵守:

如果 shell 由 exec(2) 调用,并且参数零 ($0) 的第一个字符是 -,则假定 shell 是登录 shell,并且从 [...]

连字符前缀不会在 bash 中显示给我,我假设 bash 正在编辑命令行以阻止它在进程列表中可见。

结果,dirname $0isdirname -ksh和 dirname 尝试将其解析为传递k,sh选项

您可以通过显式终止dirname使用 with解析的选项来解决此问题--,即

dirname -- "$0"

我的第二个通用问题是,为什么 dirname 'sh' 返回当前目录。

dirname试图提供帮助并返回可用路径,即使您提供的路径没有目录部分。由于您的 "$0" 只有一个部分,它假定它是相对于当前工作目录的,即sh== ./sh,并返回.

这是根据dogbane的回答记录的

于 2012-12-17T10:17:47.037 回答