如何使用 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:49:48  来源:igfitidea点击:

How do I use su to execute the rest of the bash script as that user?

bashpermissionssudouser-permissionssu

提问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 %groupnameinstead of the username1

如果您需要多个用户来运行此脚本,请使用 a%groupname而不是 username1

回答by Dan Dascalescu

Much simpler: use sudoto 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 sudoinstead

使用sudo替代

EDIT: As Douglas pointed out, you can not use cdin sudosince it is not an externalcommand. You have to run the commands in a subshell to make the cdwork.

编辑:正如道格拉斯所指出的,您不能使用cdin,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 sudoto 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 -Efrom sudo.

我曾经sudo允许少密码执行脚本。如果要为用户输入密码,请删除sudo. 如果不需要环境变量,请-E从 sudo 中删除。

The /usr/bin/bash -lensures, that the profile.dscripts are executed for an initialized environment.

/usr/bin/bash -l保证,该profile.d脚本用于初始化的环境中执行。