如何将两个标准输入传递给 sudo?

如何将两个标准输入传递给 sudo?

我的目标是向需要超级用户权限的文件写入一些内容,并且我想用一行代码来完成它。我尝试过的步骤:

我可以通过以下方式传递密码标准输入通过sudo使用其-S选项:

printf 'password\n' | sudo -S cat /etc/test.txt

我还可以传递一个字符串标准输入sudo做某事:

echo 'hello' | sudo tee /etc/test.txt

但是,我无法在同一行传递字符串和密码。这可能吗?我怎样才能实现这个目标?

答案1

你写了

我的目标是向需要超级用户权限的文件写入一些内容

一种方法是放宽文件的权限,使其具有(例如)组写入权限。然后将相关用户添加到该组中。注销/登录后,他们将能够写入文件,而无需sudo.

另一种“正确”的方法sudo是创建一个管理写入过程的脚本,然后在其中授权该脚本,/etc/sudoers以便选定的用户不需要提供密码。这样做的一大优点是,即使您的目标用户也无法自由访问目标文件;您的脚本可以在将输入写入文件之前对其进行验证和清理

获取 root shell。保持此打开状态,并且在确定其sudo仍在工作之前不要将其关闭

sudo -s

现在创建脚本

cat >/usr/local/bin/write-to-file <<'EOF'
#!/bin/bash
#
export PATH=/usr/local/bin:/usr/bin:/bin        # Only necessary for a non-standard PATH

# Restart with sudo if we are not already root
[[ $(id -u) != 0 ]] && exec sudo "$0" "$@"


# Read just one line into the target file
head -n1 >/etc/test.txt
EOF

仍然使用这个 root shell,使脚本可执行,然后将一行添加到sudoers.将初始值更改user为允许write-to-file在没有密码的情况下运行的用户帐户,或者ALL如果允许任何用户。

chown root /usr/local/bin/write-to-file         # Ensure no-one else can modify the script
chmod a+rx,go-w /usr/local/bin/write-to-file    # Make it executable

echo 'user ALL = NOPASSWD: /usr/local/bin/write-to-file' >/etc/sudoers.d/write-to-file

暂时不要关闭 root shell。

在另一个(非 root)终端中,测试新脚本。如果你得到write-to-file: command not found那么/usr/local/bin不在你的路径中(运行export PATH="$PATH:/usr/local/bin"

echo hello | write-to-file                      # Should not prompt for password
cat /etc/test.txt                               # Should contain "hello"

write-to-file < /etc/passwd                     # Multiline input
cat /etc/test.txt                               # Contains only the first line from passwd

请注意,我们甚至不需要sudo在这里使用。发生的情况是,脚本注意到它没有以 root 身份运行,并以sudo.

答案2

使用子外壳:

(echo "password"; cat /some/file ) | sudo -S tee /etc/test.txt

哪里cat /some/file可以是任何产生输出的命令。

答案3

这遵循@roaima的想法,即使用辅助文件来编写目标文件:

  1. 以 root 身份登录,创建一个名为 的简单脚本write-to-file,其中包含以下代码:

    echo $1 > /etc/test.txt
    

(它必须放置在 /usr/local/bin 并且必须只有执行权限)。

  1. 作为普通用户,您可以通过以下方式从任何地方运行它:

    echo 'password' | sudo -S write-to-file "hello!"
    

通过这种方式,一个字符串作为标准输入传递,另一个作为参数传递。

笔记:我不知道这个解决方案是否会导致安全漏洞。在我看来,应该和平时使用一样安全sudo

相关内容