这可能是重复的,但我的所有搜索都出现了有关权限被拒绝错误的问题。
我正在 bash shell 中运行一个命令。我想重定向输出以附加到第一次运行时可能不存在的文件。如果输出重定向必须创建此文件,我想设置特定的文件权限模式。有没有办法用一个命令做到这一点?
例如,我可能会尝试
foo >> /tmp/foo.log 0644
我最终想要0644
的权限在哪里?我在 bash 中试验过的大多数命令最终都被解释为 的附加参数。foo.log
0644
foo
我感觉这将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)
但是,有两个问题。
- Umask 无法将权限提升到
creat()
系统调用中指定的级别以上(0666 似乎是 Bash 使用的级别)。 - 这不会改变现有文件的权限(因为
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
并禁止任何其他用户查看内容。