重定向输出时如何设置特定的文件权限?

Pat*_*k M 17 linux bash shell command-line file-permissions

这可能是重复的,但我所有的搜索都提出了有关权限被拒绝错误的问题。

我在 bash shell 中运行命令。我想重定向输出以附加到第一次运行时可能不存在的文件。如果输出重定向必须创建此文件,我想设置特定的文件权限模式。有没有办法用一个命令来做到这一点?

例如,我可能会尝试

foo >> /tmp/foo.log 0644
Run Code Online (Sandbox Code Playgroud)

0644我想foo.log最终获得的权限在哪里。我在 bash 中尝试过的大多数命令最终都被解释0644foo.

我觉得这将chmod在写入之前或之后对权限执行第二个命令。

我正在使用 GNU bash 4.2.25 和 Ubuntu 12.04,如果这有区别的话 - 一般的答案是首选。

小智 15

我知道这是一个老问题,但我想补充两分钱。

我有同样的想法,并想出了一个类似于BowlesCR的解决方案。他的解决方案的问题是,foo如果我在运行之前更改了 umask ,我的命令 ( ) 将不起作用,所以这是我对这个问题的看法:

foo | ( umask 0033; cat >> /tmp/foo.log; )
Run Code Online (Sandbox Code Playgroud)

在这里,umask只影响到foo.log子shell 中的重定向。其他一切都不受影响。

有点复杂,但它有效。


小智 6

据我所知,在管道传输时没有办法做到这一点,一个简单的脚本可能是最好的解决方案。

if [ -e /tmp/foo.log ]; then
    foo >> /tmp/foo.log
else
    foo >> /tmp/foo.log
    chmod 0644 /tmp/foo.log
fi
Run Code Online (Sandbox Code Playgroud)

  • 这种方法的问题在于,当文件的权限错误时,它会创建一个很短的时间窗口。如果目标是保护敏感数据,我不会使用它。 (4认同)
  • 就目前而言,这个答案是有效的,但 @proski 是对的:“umask”答案更好,其中之一应该被接受。 (2认同)

Bow*_*sCR 6

如果没有真正的脚本,你可以链接一点:

touch /tmp/foo.log; chmod 0644 /tmp/foo.log; foo >> /tmp/foo.log
Run Code Online (Sandbox Code Playgroud)

Slowki的回答有效相似,但浓缩为一行。

我能想到的唯一另一件事是修补 umask。最好在子shell中执行此操作,以免污染当前环境:

(umask 0033 && foo >> /tmp/foo.log)
Run Code Online (Sandbox Code Playgroud)

不过,这有两个问题。

  1. Umask 不能将权限提升到creat()系统调用中指定的级别以上(0666 似乎是 Bash 使用的)。
  2. 这不会更改现有文件的权限(因为umask仅适用于文件创建)。