tar 及其关键字母:它是错误还是功能?

khi*_*kho 18 linux command-line tar

我想问一下这两个命令的区别(即只有它们的选项顺序不同):

  1. tar -zxvf foo.tar.gz
  2. tar -zfxv foo.tar.gz

第一个运行完美,但第二个说:

tar: You must specify one of the `-Acdtrux' or `--test-label'  options
Try `tar --help' or `tar --usage' for more information.
Run Code Online (Sandbox Code Playgroud)

而焦油--test-label-zfxv说:

tar (child): xv: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
Run Code Online (Sandbox Code Playgroud)

然后我查看了 tar 手册,发现里面的所有示例最终都使用了 switch -f!!

AFAICT 不需要这个限制,或者有吗?!因为在我看来开关应该是免费订购的。

wur*_*tel 55

开关的顺序是自由的,但-f有一个强制参数,tar即将要读/写的文件。

你可以做

tar -zf foo.tar.gz -xv
Run Code Online (Sandbox Code Playgroud)

这将起作用,并且您需要非特定的开关顺序。

这就是所有具有带参数选项的命令的工作方式。

  • Tar 不像其他命令那样工作,因为它使用不同的更旧的命令行解析器 - 与在“ar”命令和旧(POSIX 之前)“ps”命令中使用的相同。 (5认同)

Ran*_*832 14

传统上,焦油的选项或多或少的“无阶”(在顺序fb如果两者都指定选项事做)。然而,使用前导破折号会导致 GNU tar 以一种被认为与其他命令更一致的方式解析选项,其中指定需要参数的选项(例如文件名 for f)将立即消耗“单词”的其余部分,如果有,作为参数(传统上,当指定或时,tar 使用下一个词作为文件名/块大小)。在您的情况下,它以“xv”作为文件名。fb

但是,不能依赖此行为来实现可移植性。为了获得最大的可移植性,您应该避免使用破折号,始终放在f最后,并且始终在f和 文件名之间放置一个空格。但是,这是一种简化,如果您需要该b选项或一般情况下除该选项之外的任何选项(例如Cf需要参数,则该简化会失效。

这在Tar Manual 部分“The Three Option Styles” 中有记录。其他一些实现(例如 FreeBSD)将旧样式选项称为“捆绑选项词”。当然,某些实现可能支持这种类型的选项,并且可能会或可能不会忽略破折号(如果包含的话)。这是单一 Unix 规范中指定的唯一调用形式,因此保证可以在几乎所有系统上工作。

  • 请注意,某些实现支持其他带参数的选项(如 BSD 或 GNU tar 中的 `C`。schily tar 支持它作为 -C 但不支持 C,所有支持它作为 -C)。 (2认同)

sch*_*ily 11

查看您的错误消息,很明显您没有使用tar而是使用gtar.

一般来说,这可能有助于理解:

  • tar通常总是需要一个文件参数。如果它丢失,它将从/向系统的默认真实磁带设备读取/写入。star1982 年将此更改为默认情况下使用 stdin/stdout,最近一些其他 tar 实现(例如 gtar)也遵循此示例。

  • tar不实现在 tar 命令的情况下-调用的选项的前导key letters。一些实现后来添加-为方便用户的无操作密钥字母,但您不能依赖于此。

  • 该方法tar解析其参数(特别是档案文件的说法)是高风险。我看到许多 tar 档案破坏了应该在档案中的文件之一,因为相关的文件参数被视为 tar 档案文件。star出于这个原因(如果本机调用为star)不允许“f”与其他选项连接。如果star被调用,tar它实现与 的命令行兼容性tar,但仍然以不同的方式处理“f”键字母的参数:仅当它引用真实设备文件或(在写入模式下)文件尚不存在时才允许该参数.

我建议避免使用有风险的原始 tar 命令行,而是使用现代更安全的命令行语法star

由于 有问题的命令行语法tartar wars在 1990 年代初就有了所谓的 。结果,该程序pax(在柏油战争中的拉丁语为“和平”)被创建和标准化。pax然而并没有流行起来,因为它的语法风险较小,但也没有 tar 语法直观。另一个问题可能是gpax或多或少没有维护。

  • 焦油战争结束了。冈塔赢了。 (3认同)
  • 如果你是对的,为什么所有的 tar 实现都从 `star` 复制功能? (3认同)
  • `-long` 样式的长选项与精简的 `-xyz` 短选项或 `-xarg` 不兼容。这就是为什么 X11 风格的长选项需要将短选项分开(`-x -y`,而不是 `-xy`)和选项参数在单独的参数上(`xterm -n foo`,而不是 `xterm -nfoo`)。这就是为什么在 GNU 长选项中有一个额外的破折号,以消除可能与短选项的混淆,以及为什么 GNU 风格的长选项是更好的设计。只有当你非常小心地避免重叠时,你才能让 `-foo` 与 `-x -y -xy` 共存。 (3认同)
  • 好吧,看来 `star` 的 `-f"$file"` 也是(除了 `ind` 之外)文件名以 `=` 开头的问题。所以需要写成`-f="$file"` 或`-f "$file"`。我不确定我会称您的星号选项解析 _safer_ 或 _modern_。 (2认同)