sudo at -f

sudo at -f

如果我做:

at -f <(echo "rm $file") now + 2 hours

效果很好

但是如果我这样做:

sudo at -f <(echo "rm $file") now + 2 hours

我得到:

at: /dev/fd/63: No such file or directory

我认为这是因为命令的处理顺序所致。有什么办法可以使用 sudo 命令来解决这个问题吗?我能想到的唯一方法是将命令放在脚本上并 sudo 该脚本(这是一个选项),但现在我想知道为什么会发生这种情况。

抱歉,如果这个问题已经在某个地方得到了回答,我只是找不到它,因为我不确定要寻找什么。

答案1

因为 shell 打开了指向 中命令的管道<(...),并将文件句柄传递给它运行的子进程(sudo在本例中)。路径/dev/fd/63是内核提供的一种方法,允许通过普通路径名访问已经打开的文件句柄。

但是,sudo不会将句柄传递给它运行的进程(出于安全原因):默认情况下,它会关闭除 stdin、stdout 和 stderr 之外的所有文件句柄,因此最终运行的程序没有与 和 对应的文件/dev/fd/63句柄它出错了。

您可以通过在 sudo 内的 shell 中进行替换来解决该问题:

sudo bash -c 'cat <(echo something)' 

当然,这意味着内部替换也以提升的特权运行:

$ sudo bash -c 'cat <(id)'
uid=0(root) gid=0(root) groups=0(root)

标志-C提供sudo了另一种方式,但可能需要允许额外的配置:

-C num, --close-from=num
在执行命令之前关闭所有大于或等于 num 的文件描述符。不允许小于三的值。默认情况下,sudo 在执行命令时会关闭除标准输入、标准输出和标准错误之外的所有打开的文件描述符。安全策略可能会限制用户使用此选项的能力。当管理员启用 closefrom_override 选项时,sudoers 策略仅允许使用 -C 选项。

答案2

我假设您的意图是将cat所有文件作为 root,您当前的ls

使用xargs管道代替可能是明智的。尝试用这个:

ls | xargs sudo cat

相关内容