如何`touch`和`cat`文件名为`-`

Tom*_*ale 5 linux cat touch

如何使用 GNUtouch更新名为-?

如何使用 GNUcat显示名为-?


我在跑:

% cat --version | head -n1
cat (GNU coreutils) 8.29
% touch --version | head -n1
touch (GNU coreutils) 8.29
Run Code Online (Sandbox Code Playgroud)

首先,touch

% touch -
% ls -l
total 0
% touch -- -
% ls -l -- -
ls: cannot access '-': No such file or directory
Run Code Online (Sandbox Code Playgroud)

好的,我将放弃使用touch. 让我们来创建它date

% date > -
% ls -l -
-rw-r--r-- 1 ravi ravi 29 Sep  8 19:54 -
%
Run Code Online (Sandbox Code Playgroud)

现在,让我们尝试cat一下:

% cat -
% # I pressed ^D
% cat -- -
% # Same again - I pressed ^D
Run Code Online (Sandbox Code Playgroud)

我知道我可以解决:

% > -
Run Code Online (Sandbox Code Playgroud)

% cat < -
Run Code Online (Sandbox Code Playgroud)

但是为什么这些 GNU 实用程序不支持--意味着以下所有内容都被视为非选项的约定?

在一般情况下如何使用这些工具,例如我有一个包含内容的变量-

Kus*_*nda 13

使用文件的显式路径:

touch ./-
cat ./-
Run Code Online (Sandbox Code Playgroud)

GNU特别touch对待文件操作数-

一个 FILE 参数字符串-被特殊处理并导致touch更改与标准输出相关联的文件的时间。

对于catPOSIX 标准指定文件操作数-应被解释为从标准输入读取的请求。

双破折号约定仍然有效,但它不是用于表示参数结束而是选项结束。在这两种情况下都-不会被视为一个选项(一个单独的-不能是一个选项),而是一个操作数(“文件名参数”)。


关于你的最后一个问题:

保护变量的内容在使用它时不被解释为一组选项

utility "$variable"
Run Code Online (Sandbox Code Playgroud)

utility -- "$variable"
Run Code Online (Sandbox Code Playgroud)

请注意,如果实用程序catsedawkpastesort,可能还有其他几个人(或GNU touch),并且$variable-,这仍然会导致该实用程序做了特殊处理,因为,如上面所说,-是不是一种选择。相反,请做出规定,以便文件名(如果它们可能以 开头或等于 )-前面有一个路径,例如./对于当前工作目录中的文件。

一个好习惯是使用

for filename in ./*; do
Run Code Online (Sandbox Code Playgroud)

而不是

for filename in *; do
Run Code Online (Sandbox Code Playgroud)

例如。

  • @TomHale 如果您在目录中循环文件,请养成使用 `for file in ./*` 或类似的习惯,而不是使用 `for file in *`。 (4认同)