如何仅更改一个命令的 umask?

如何仅更改一个命令的 umask?

如何仅针对一个命令,使用与默认值不同的 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/printfwhich 不支持%Tbash扩展受ksh93's 启发)。用于type cmd检查是否cmd内置于您的特定版本的bash.

答案2

您可以将其包装在 shell 脚本中。 umask 继承给所有子进程。

cmd.sh:

umask 0022
cmd

答案3

install另一个技巧是使用和处理替换来保存文件。但只有当命令将其数据输出到 stdout 并且只是一个文件时,这才有效。

install -m 600 <(cmd) newfile

相关内容