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

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

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

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

例如,我可能会尝试

foo >> /tmp/foo.log 0644

我最终想要0644的权限在哪里?我在 bash 中试验过的大多数命令最终都被解释为 的附加参数。foo.log0644foo

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

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

答案1

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

if [ -e /tmp/foo.log ]; then
    foo >> /tmp/foo.log
else
    foo >> /tmp/foo.log
    chmod 0644 /tmp/foo.log
fi

答案2

我知道这是一个老问题,但我想发表一下我的看法。

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

foo | ( umask 0033; cat >> /tmp/foo.log; )

此处,仅影响子 shell 中的umask重定向。其他所有内容均不受影响。foo.log

有点复杂,但确实有效。

答案3

无需真正的脚本,您可以进行一些链接:

touch /tmp/foo.log; chmod 0644 /tmp/foo.log; foo >> /tmp/foo.log

效果类似于Slowki 的回答,但浓缩成一行。

我能想到的唯一其他事情就是修改 umask。最好在子 shell 中执行此操作,这样就不会污染当前环境:

(umask 0033 && foo >> /tmp/foo.log)

但是,有两个问题。

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

答案4

当重定向设置了错误的权限时,例如:

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ perl -e 'print STDERR "$$ STDERR\n"; print STDOUT "$$ STDOUT\n"' \
                            >> capture.STDOUT 2>> capture.STDERR
$ ls -l capture.*
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDERR
-rw-rw-rw- 1 jcookinf jcookinf 22 Jun 12 10:38 capture.STDOUT
$ cat capture.*
215 STDERR
216 STDERR
215 STDOUT
216 STDOUT

我相信你可以使用 xynomorf 提供的东西,并解决 Orsiris de Jong 的 stderr 问题,只需稍加修改即可使用bash 进程替换

$ rm capture.*
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ perl -e 'print STDERR "$$ STDERR text\n"; print STDOUT "$$ STDOUT text\n"' \
            > >(umask 0033; cat >> capture.STDOUT) 2> >(umask 0033; cat >> capture.STDERR)
$ ls -l capture.*
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDERR
-rw-r--r-- 1 jcookinf jcookinf 32 Jun 12 10:43 capture.STDOUT
$ cat capture.*
233 STDERR text
238 STDERR text
233 STDOUT text
238 STDOUT text

当然,使用umask 0077获取模式600 并禁止任何其他用户查看内容。

相关内容