如何仅针对一个命令,使用与默认值不同的 umask 在 Linux 中交互执行命令(zsh,如果重要的话)?也许将命令组合合并在一行中?新的 umask 应仅应用于该命令,并为下一个输入的命令返回其默认值。
理想情况下,该命令与输入之前生效的默认 umask 无关(换句话说,不必指定默认 umask)。
答案1
开始一个子外壳:
(umask 22 && cmd)
那么 newumask
只会改变该子 shell。
请注意,zsh
在子 shell 进程中执行子 shell 的最后一个命令,而不是派生另一个命令,这意味着如果该命令是外部的,您甚至不会浪费一个进程,只是派生较早完成(因此umask
完成在稍后将执行您的命令的子进程中)。
在诸如 之类的 shell 中bash
,尚未执行该优化,您可以使用exec
来显式请求不生成子进程。比较:
$ zsh -c '(umask 22 && ps -H); exit'
PID TTY TIME CMD
3806 pts/0 00:00:00 zsh
3868 pts/0 00:00:00 zsh
3869 pts/0 00:00:00 ps
$ bash -c '(umask 22 && ps -H); exit'
PID TTY TIME CMD
3806 pts/0 00:00:00 zsh
3870 pts/0 00:00:00 bash
3871 pts/0 00:00:00 bash
3872 pts/0 00:00:00 ps
$ bash -c '(umask 22 && exec ps -H); exit'
PID TTY TIME CMD
3806 pts/0 00:00:00 zsh
3884 pts/0 00:00:00 bash
3885 pts/0 00:00:00 ps
在 bash 中,与 zsh 相反,执行以下操作不是用于exec
内置命令或函数,因为它不会运行内置命令/函数,而是尝试使用该名称运行外部命令。
$ bash -c '(printf "%(%F)T\n" -1)'
2022-02-27
$ bash -c '(exec printf "%(%F)T\n" -1)'
printf: %(: invalid conversion specification
后者称为/usr/bin/printf
which 不支持%T
(bash
扩展受ksh93
's 启发)。用于type cmd
检查是否cmd
内置于您的特定版本的bash
.
答案2
您可以将其包装在 shell 脚本中。 umask 继承给所有子进程。
cmd.sh:
umask 0022
cmd
答案3
install
另一个技巧是使用和处理替换来保存文件。但只有当命令将其数据输出到 stdout 并且只是一个文件时,这才有效。
install -m 600 <(cmd) newfile