我想将当前目录更改为 shell 脚本到包含特定常规文件的目录。我发现以下技巧适用于 mksh
和 busybox sh
:
path=/path/to/regular/file
cd $path/..
但不是在 GNU Bash 中:
bash: cd: /path/to/regular/file/..: Not a directory
这个技巧是不是 posix 兼容,还是 Bash 太迂腐了?
最佳答案
该标准的最新版本不允许这样做。 POSIX.1-2017 cd
spec.表示如果点点之前的路径名组件不是目录,cd
应认为这是一个错误。
来自 cd
§ DESCRIPTION - step 8.b :
b. For each dot-dot component, if there is a preceding component and
it is neither root nor dot-dot, then:
i. If the preceding component does not refer (in the context of
pathname resolution with symbolic links followed) to a
directory, then the cd utility shall display an appropriate
error message and no further steps shall be taken.
当cd
使用 -P
调用选项,此步骤省略;但后来 chdir()
如果路径名组件之一命名的现有文件既不是目录也不是目录的符号链接(symbolic link),则失败。此外,允许该技巧还允许在
cd
中出现不一致的行为。 .例如,当在包含 的目录中运行时常规文件 命名为 bar
, 和 目录 命名为 foo
包含另一个 目录 命名为 bar
,以下两个命令在 cd
的 shell 中执行不同的操作。忽略点点之前的非目录组件,尽管 CDPATH
在这两种情况下都包含空字符串(即当前工作目录)。CDPATH= cd bar/..
CDPATH=:foo cd bar/..
下面的文字记录清楚地显示了不合格和合格实现之间的区别。$ tree -F
.
├── bar
└── foo/
└── bar/
2 directories, 1 file
$ ash
$ CDPATH= cd bar/..
$ pwd
/home/oguz
$ CDPATH=:foo cd bar/..
/home/oguz/foo
$ bash
$ CDPATH= cd bar/..
bash: cd: bar/..: Not a directory
$ CDPATH=:foo cd bar/..
/home/oguz/foo
bosh , gwsh , ksh93u+m , 和 yash是其他积极维护的 shell,它们实现了与 bash 相同的行为。
关于bash - "/path/file/.."如何符合 POSIX 标准?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62367882/