停止在使用 sudo 运行的脚本中间成为 root
Stop being root in the middle of a script that was run with sudo
有一个命令列表,只有在它们以 sudo
开头时才会成功。
还有另一个命令列表,只有当用户在没有 sudo
.
的情况下运行它们时才会成功
我想从同一个脚本执行所有这些命令。
我想避免必须执行以下操作:
#!/usr/bin/env bash
sudo sudo_command_one;
sudo sudo_command_two;
sudo sudo_command_three;
non_sudo_command;
sudo sudo_command_four;
之所以这样,是因为 sudo 有超时,这些命令可能会花费很长时间。我不想因为偶尔必须重新输入 sudo 密码而感到负担。我也许可以无限期地延长 sudo 的超时时间,但如果有更简单的方法,那也是我希望避免的事情。
因此,我将按如下方式运行脚本:
sudo ./script
但这会阻止非 sudo 命令工作。
我需要哪些缺少的命令:
#!/usr/bin/env bash
sudo_command_one;
sudo_command_two;
sudo_command_three;
[turn sudo off for a moment]
non_sudo_command;
[ok, turn sudo back on]
sudo_command_four;
不幸的是,无法重新排列命令的顺序,因此我首先运行所有 sudo 命令,然后运行所有非 sudo 命令(反之亦然)。
在 sudo 的脚本 运行 中,使用:
su -c "shell command; shell command" $SUDO_USER
在该脚本中以调用 sudo 的普通用户身份执行命令。
这是有效的,因为 sudo
将环境变量 SUDO_USER
设置为原始用户名。
如果你有一堆命令 运行 作为原始用户,你可以使用 hereis 文档。
这是一个示例脚本文件作为概念证明:
myscript.sh
#!/bin/bash
echo "Part 1"
echo "now running as:"
whoami
echo "SUDO_USER is:"
echo $SUDO_USER
su $SUDO_USER <<EOF
echo "Part 2"
echo "now running as:"
whoami
echo "SUDO_USER is:"
env | grep ^SUDO_USER
sleep 5
EOF
echo "Part 3"
echo "now running as:"
whoami
echo "SUDO_USER is:"
echo $SUDO_USER
这是 sudo ./myscript.sh
上的输出
Part 1
now running as:
root
SUDO_USER is:
paul
Part 2
now running as:
paul
SUDO_USER is:
SUDO_USER=paul
Part 3
now running as:
root
SUDO_USER is:
paul
警告:此技术不适用于嵌套的 sudo。如果 sudo 被嵌套两次,例如
sudo su
echo $SUDO_USER
---> me
sudo su
echo $SUDO_USER
---> root
SUDO_USER 将 return root,而不是原始用户名。 su $SUDO_USER 然后将 运行ning 保持为 root。小心避免这种情况,它应该可以正常工作。
这是我在脚本中 运行 的方式。
#! /bin/bash
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root";
exit 1;
else
NON_ROOT_USER=$(who am i | awk '{print }');
echo "root ran this echo.";
sudo -u $NON_ROOT_USER echo "$NON_ROOT_USER ran this echo.";
fi
sudo ./script.sh
有一个命令列表,只有在它们以 sudo
开头时才会成功。
还有另一个命令列表,只有当用户在没有 sudo
.
我想从同一个脚本执行所有这些命令。
我想避免必须执行以下操作:
#!/usr/bin/env bash
sudo sudo_command_one;
sudo sudo_command_two;
sudo sudo_command_three;
non_sudo_command;
sudo sudo_command_four;
之所以这样,是因为 sudo 有超时,这些命令可能会花费很长时间。我不想因为偶尔必须重新输入 sudo 密码而感到负担。我也许可以无限期地延长 sudo 的超时时间,但如果有更简单的方法,那也是我希望避免的事情。
因此,我将按如下方式运行脚本:
sudo ./script
但这会阻止非 sudo 命令工作。
我需要哪些缺少的命令:
#!/usr/bin/env bash
sudo_command_one;
sudo_command_two;
sudo_command_three;
[turn sudo off for a moment]
non_sudo_command;
[ok, turn sudo back on]
sudo_command_four;
不幸的是,无法重新排列命令的顺序,因此我首先运行所有 sudo 命令,然后运行所有非 sudo 命令(反之亦然)。
在 sudo 的脚本 运行 中,使用:
su -c "shell command; shell command" $SUDO_USER
在该脚本中以调用 sudo 的普通用户身份执行命令。
这是有效的,因为 sudo
将环境变量 SUDO_USER
设置为原始用户名。
如果你有一堆命令 运行 作为原始用户,你可以使用 hereis 文档。
这是一个示例脚本文件作为概念证明:
myscript.sh
#!/bin/bash
echo "Part 1"
echo "now running as:"
whoami
echo "SUDO_USER is:"
echo $SUDO_USER
su $SUDO_USER <<EOF
echo "Part 2"
echo "now running as:"
whoami
echo "SUDO_USER is:"
env | grep ^SUDO_USER
sleep 5
EOF
echo "Part 3"
echo "now running as:"
whoami
echo "SUDO_USER is:"
echo $SUDO_USER
这是 sudo ./myscript.sh
Part 1
now running as:
root
SUDO_USER is:
paul
Part 2
now running as:
paul
SUDO_USER is:
SUDO_USER=paul
Part 3
now running as:
root
SUDO_USER is:
paul
警告:此技术不适用于嵌套的 sudo。如果 sudo 被嵌套两次,例如
sudo su
echo $SUDO_USER
---> me
sudo su
echo $SUDO_USER
---> root
SUDO_USER 将 return root,而不是原始用户名。 su $SUDO_USER 然后将 运行ning 保持为 root。小心避免这种情况,它应该可以正常工作。
这是我在脚本中 运行 的方式。
#! /bin/bash
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root";
exit 1;
else
NON_ROOT_USER=$(who am i | awk '{print }');
echo "root ran this echo.";
sudo -u $NON_ROOT_USER echo "$NON_ROOT_USER ran this echo.";
fi
sudo ./script.sh