在“ sudo find”命令中,如何确保以普通用户身份运行“ -exec”命令?


10

我试图使以下命令以某种方式process_paths运行,使脚本不在提升的特权下运行。有没有办法做到这一点?

sudo find /path/ -exec process_paths '{}' \+

这里/path/有些文件没有普通用户的读取权限。该脚本process_paths只需要路径。


... -exec sudo -u user process_paths {} \+
聪桂

@SatoKatsura有时会失败sudo: unable to execute /usr/bin/perl: Argument list too long:/
pii_ke


2
如果您希望-exec以用户身份调用命令,那么为什么要先运行find使用sudo
marcelm

2
@marcelm我认为问题的最后一句话回答了您的问题。

Answers:


16

在支持它的系统(GNU和很多其他系统)上,您可以这样做:

sudo find /path/ -print0 | xargs -r0 process_paths

xargs不是在之下运行的sudo,因此它仍然具有原始uid / gids以及原始环境(从广义上来说),而不是由修改的sudo

process_paths标准输入最终被修改,但(这取决于xargs实施,它的开放/dev/null或股票pipesudo/ find

为了避免这种情况(与GNU xargs和像贝壳kshzsh或者bash说支持进程替换),你可以这样做:

xargs -r0a <(sudo find /path/ -print0) process_paths

zsh

sudo zsh -c '
   files=(/path/**/*(D))
   USERNAME=$SUDO_USER
   autoload zargs
   zargs $files -- process_paths'

在中zsh,将用户名分配给$USERNAME特殊变量,就像在用户数据库中一样,sudo -u "$SUDO_USER"将uid,gids设置为相应用户的uid和gid 。

您可以这样做:

 sudo sh -c '
   exec find /path/ -exec sudo -u "$SUDO_USER" process_paths {} +'

但是由于sudo$SUDO_COMMAND环境变量(包含带空格的参数的串联)传递给process_paths,因此文件列表最终会被传递两次,process_paths这意味着如果存在较大的参数,很可能会达到args + env的最大大小限制文件数。

使用大多数su实现,您应该能够:

 sudo sh -c '
   exec find /path/ -exec su "$SUDO_USER" -c '\''
     exec "$0" "$@"'\'' process_paths {} +'

虽然su没有相同的问题。


1

您可以使用sudo

sudo find <directory> -exec sudo -u <normal_user> <command> {} \;

但是正如评论中所说,如果{}对于sudo来说太长,它显然会失败。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.