我的目标是向需要超级用户权限的文件写入一些内容,并且我想用一行代码来完成它。我尝试过的步骤:
我可以通过以下方式传递密码标准输入通过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的想法,即使用辅助文件来编写目标文件:
以 root 身份登录,创建一个名为 的简单脚本
write-to-file
,其中包含以下代码:echo $1 > /etc/test.txt
(它必须放置在 /usr/local/bin 并且必须只有根执行权限)。
作为普通用户,您可以通过以下方式从任何地方运行它:
echo 'password' | sudo -S write-to-file "hello!"
通过这种方式,一个字符串作为标准输入传递,另一个作为参数传递。
笔记:我不知道这个解决方案是否会导致安全漏洞。在我看来,应该和平时使用一样安全sudo
。