如何使用 su 以该用户身份执行 bash 脚本的其余部分?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1988249/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I use su to execute the rest of the bash script as that user?
提问by Avery
I've written a script that takes, as an argument, a string that is a concatenation of a username and a project. The script is supposed to switch (su) to the username, cd to a specific directory based upon the project string.
我编写了一个脚本,该脚本将一个字符串作为参数,该字符串是用户名和项目的串联。该脚本应该根据项目字符串将 (su) 切换到用户名,将 cd 切换到特定目录。
I basically want to do:
我基本上想做:
su $USERNAME;
cd /home/$USERNAME/$PROJECT;
svn update;
The problem is that once I do an su... it just waits there. Which makes sense since the flow of execution has passed to switching to the user. Once I exit, then the rest of the things execute but it doesn't work as desired.
问题是,一旦我做了一个 su... 它就在那里等着。这是有道理的,因为执行流程已经传递到切换到用户。一旦我退出,其余的事情就会执行,但它不能按预期工作。
I prepended su to the svn command but the command failed (i.e. it didn't update svn in the directory desired).
我在 svn 命令前添加了 su 但命令失败(即它没有在所需目录中更新 svn)。
How do I write a script that allows the user to switch user and invoke svn (among other things)?
如何编写允许用户切换用户并调用 svn(除其他外)的脚本?
采纳答案by Kimvais
The trick is to use "sudo" command instead of "su"
诀窍是使用“sudo”命令而不是“su”
You may need to add this
你可能需要添加这个
username1 ALL=(username2) NOPASSWD: /path/to/svn
to your /etc/sudoers file
到您的 /etc/sudoers 文件
and change your script to:
并将您的脚本更改为:
sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update"
Where username2 is the user you want to run the SVN command as and username1 is the user running the script.
其中 username2 是您要运行 SVN 命令的用户,而 username1 是运行脚本的用户。
If you need multiple users to run this script, use a %groupname
instead of the username1
如果您需要多个用户来运行此脚本,请使用 a%groupname
而不是 username1
回答by Dan Dascalescu
Much simpler: use sudo
to run a shell and use a heredocto feed it commands.
更简单:用于sudo
运行 shell 并使用heredoc为其提供命令。
#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami
(answer originally on SuperUser)
(最初在 SuperUser 上回答)
回答by Walder
Use a script like the following to execute the rest or part of the script under another user:
使用如下脚本在另一个用户下执行脚本的其余部分或部分:
#!/bin/sh
id
exec sudo -u transmission /bin/sh - << eof
id
eof
回答by Douglas Leeder
You need to execute all the different-user commands as their own script. If it's just one, or a few commands, then inline should work. If it's lots of commands then it's probably best to move them to their own file.
您需要将所有不同用户的命令作为它们自己的脚本执行。如果它只是一个或几个命令,那么内联应该可以工作。如果有很多命令,那么最好将它们移动到自己的文件中。
su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME"
回答by MarSoft
Here is yet another approach, which was more convenient in my case (I just wanted to drop root privileges and do the rest of my script from restricted user): you can make the script restart itself from correct user. Let's suppose it is run as root initially. Then it will look like this:
这是另一种方法,在我的情况下更方便(我只想删除 root 权限并从受限用户执行脚本的其余部分):您可以让脚本从正确的用户重新启动。假设它最初以 root 身份运行。然后它看起来像这样:
#!/bin/bash
if [ $UID -eq 0 ]; then
user=
dir=
shift 2 # if you need some other parameters
cd "$dir"
exec su "$user" "sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"
" -- "$@"
# nothing will be executed beyond that line,
# because exec replaces running process with the new one
fi
echo "This will be run from user $UID"
...
回答by iamamac
Use sudo
instead
使用sudo
替代
EDIT: As Douglas pointed out, you can not use cd
in sudo
since it is not an externalcommand. You have to run the commands in a subshell to make the cd
work.
编辑:正如道格拉斯所指出的,您不能使用cd
in,sudo
因为它不是外部命令。您必须在子 shell 中运行命令才能完成cd
工作。
sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update
sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update
#!/usr/bin/perl -w
$user = shift;
if (!$<) {
$> = getpwnam $user;
$) = getgrnam $user;
} else {
die 'must be root to change uid';
}
system('whoami');
You may be asked to input that user's password, but only once.
您可能会被要求输入该用户的密码,但只能输入一次。
回答by P-Nuts
It's not possible to change user within a shell script. Workarounds using sudo described in other answers are probably your best bet.
无法在 shell 脚本中更改用户。使用其他答案中描述的 sudo 的解决方法可能是您最好的选择。
If you're mad enough to run perl scripts as root, you can do this with the $< $( $> $)
variables which hold real/effective uid/gid, e.g.:
如果您足够疯狂地以 root 身份运行 perl 脚本,您可以使用$< $( $> $)
保存真实/有效 uid/gid的变量来执行此操作,例如:
# Configure everything else ready to run
config.vm.provision :shell, path: "provision.sh"
config.vm.provision :shell, path: "start_env.sh", run: "always"
回答by httpete
This worked for me
这对我有用
I split out my "provisioning" from my "startup".
我从我的“启动”中分离出我的“供应”。
#!/usr/bin/env bash
echo "Starting Server Env"
#java -jar /usr/lib/node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-2.40.0.jar &
#(cd /vagrant_projects/myproj && sudo -u vagrant -H sh -c "nohup npm install 0<&- &>/dev/null &;bower install 0<&- &>/dev/null &")
cd /vagrant_projects/myproj
nohup grunt connect:server:keepalive 0<&- &>/dev/null &
nohup apimocker -c /vagrant_projects/myproj/mock_api_data/config.json 0<&- &>/dev/null &
then in my start_env.sh
然后在我的 start_env.sh
USERNAME='desireduser'
COMMAND=##代码##
COMMANDARGS="$(printf " %q" "${@}")"
if [ $(whoami) != "$USERNAME" ]; then
exec sudo -E su $USERNAME -c "/usr/bin/bash -l $COMMAND $COMMANDARGS"
exit
fi
回答by Trendfischer
Inspired by the idea from @MarSoftbut I changed the lines like the following:
灵感来自@MarSoft的想法,但我改变了如下几行:
##代码##I have used sudo
to allow a password less execution of the script. If you want to enter a password for the user, remove the sudo
. If you do not need the environment variables, remove -E
from sudo.
我曾经sudo
允许少密码执行脚本。如果要为用户输入密码,请删除sudo
. 如果不需要环境变量,请-E
从 sudo 中删除。
The /usr/bin/bash -l
ensures, that the profile.d
scripts are executed for an initialized environment.
该/usr/bin/bash -l
保证,该profile.d
脚本用于初始化的环境中执行。