如何使用 su 以该用户身份执行 bash 脚本的其余部分?

发布于 2024-08-16 17:31:14 字数 357 浏览 3 评论 0原文

我编写了一个脚本,它采用一个由用户名和项目连接而成的字符串作为参数。该脚本应该根据项目字符串切换 (su) 到用户名,cd 到特定目录。

我基本上想做:

su $USERNAME;  
cd /home/$USERNAME/$PROJECT;  
svn update;  

问题是,一旦我做了 su... 它就在那里等待。这是有道理的,因为执行流程已经传递到切换到用户。一旦我退出,其余的事情就会执行,但它不会按预期工作。

我在 svn 命令前面添加了 su,但该命令失败了(即它没有在所需的目录中更新 svn)。

如何编写一个允许用户切换用户并调用 svn(以及其他功能)的脚本?

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.

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.

I prepended su to the svn command but the command failed (i.e. it didn't update svn in the directory desired).

How do I write a script that allows the user to switch user and invoke svn (among other things)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

狼性发作 2024-08-23 17:31:14

更简单:使用 sudo 运行 shell 并使用 heredoc 来喂它命令。

#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami

最初在 SuperUser 上回答

Much simpler: use sudo to run a shell and use a heredoc to feed it commands.

#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami

(answer originally on SuperUser)

糖果控 2024-08-23 17:31:14

诀窍是使用“sudo”命令而不是“su”

您可能需要将其添加

username1 ALL=(username2) NOPASSWD: /path/to/svn

到 /etc/sudoers 文件

并将脚本更改为:

sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update" 

其中 username2 是您要运行 SVN 命令的用户,而 username1 是运行脚本的用户。

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

The trick is to use "sudo" command instead of "su"

You may need to add this

username1 ALL=(username2) NOPASSWD: /path/to/svn

to your /etc/sudoers file

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.

If you need multiple users to run this script, use a %groupname instead of the username1

π浅易 2024-08-23 17:31:14

这是另一种方法,在我的情况下更方便(我只是想放弃 root 权限并从受限用户执行脚本的其余部分):您可以使脚本从正确的用户重新启动。这种方法比使用 sudosu -c 与“嵌套脚本”更具可读性。假设它最初是作为 root 启动的。那么代码将如下所示:

#!/bin/bash
if [ $UID -eq 0 ]; then
  user=$1
  dir=$2
  shift 2     # if you need some other parameters
  cd "$dir"
  exec su "$user" "$0" -- "$@"
  # nothing will be executed from root beyond that line,
  # because exec replaces running process with the new one
fi

echo "This will be run from user $UID"
...

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 the correct user. This approach is more readable than using sudo or su -c with a "nested script". Let's suppose it is started as root initially. Then the code will look like this:

#!/bin/bash
if [ $UID -eq 0 ]; then
  user=$1
  dir=$2
  shift 2     # if you need some other parameters
  cd "$dir"
  exec su "$user" "$0" -- "$@"
  # nothing will be executed from root beyond that line,
  # because exec replaces running process with the new one
fi

echo "This will be run from user $UID"
...
变身佩奇 2024-08-23 17:31:14

您需要将所有不同用户的命令作为自己的脚本来执行。如果它只是一个或几个命令,那么内联应该可以工作。如果有很多命令,那么最好将它们移动到自己的文件中。

su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME" 

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" 
橘寄 2024-08-23 17:31:14

使用如下所示的脚本在另一个用户下执行脚本的其余部分或部分内容:

#!/bin/sh

id

exec sudo -u transmission /bin/sh - << eof

id

eof

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
可可 2024-08-23 17:31:14

使用sudo代替

编辑:正如Douglas指出的,您不能在sudo中使用cd,因为它不是外部命令。您必须在子 shell 中运行命令才能使 cd 工作。

sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"

sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update

系统

可能会要求您输入该用户的密码,但仅输入一次。

Use sudo instead

EDIT: As Douglas pointed out, you can not use cd in sudo since it is not an external command. You have to run the commands in a subshell to make the cd work.

sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"

sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update

You may be asked to input that user's password, but only once.

少女的英雄梦 2024-08-23 17:31:14

无法在 shell 脚本中更改用户。其他答案中描述的使用 sudo 的解决方法可能是您最好的选择。

如果您疯狂地想以 root 身份运行 perl 脚本,您可以使用 $<; $( $> $) 保存真实/有效 uid/gid 的变量,例如:

#!/usr/bin/perl -w
$user = shift;
if (!
lt;) {
    
gt; = getpwnam $user;
    $) = getgrnam $user;
} else {
    die 'must be root to change uid';
}
system('whoami');

It's not possible to change user within a shell script. Workarounds using sudo described in other answers are probably your best bet.

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.:

#!/usr/bin/perl -w
$user = shift;
if (!
lt;) {
    
gt; = getpwnam $user;
    $) = getgrnam $user;
} else {
    die 'must be root to change uid';
}
system('whoami');
夜声 2024-08-23 17:31:14

这对我有用,

我将我的“配置”从“启动”中分离出来。

 # Configure everything else ready to run 
  config.vm.provision :shell, path: "provision.sh"
  config.vm.provision :shell, path: "start_env.sh", run: "always"

然后在我的start_env.sh中

#!/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 &

This worked for me

I split out my "provisioning" from my "startup".

 # Configure everything else ready to run 
  config.vm.provision :shell, path: "provision.sh"
  config.vm.provision :shell, path: "start_env.sh", run: "always"

then in my start_env.sh

#!/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 &
落叶缤纷 2024-08-23 17:31:14

受到 @MarSoft 的想法的启发,但我更改了如下行:

USERNAME='desireduser'
COMMAND=$0
COMMANDARGS="$(printf " %q" "${@}")"
if [ $(whoami) != "$USERNAME" ]; then
  exec sudo -E su $USERNAME -c "/usr/bin/bash -l $COMMAND $COMMANDARGS"
  exit
fi

我使用了 sudo 允许无密码执行脚本。如果您想输入用户密码,请删除 sudo。如果不需要环境变量,请从 sudo 中删除 -E

/usr/bin/bash -l 确保在初始化的环境中执行 profile.d 脚本。

Inspired by the idea from @MarSoft but I changed the lines like the following:

USERNAME='desireduser'
COMMAND=$0
COMMANDARGS="$(printf " %q" "${@}")"
if [ $(whoami) != "$USERNAME" ]; then
  exec sudo -E su $USERNAME -c "/usr/bin/bash -l $COMMAND $COMMANDARGS"
  exit
fi

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.

The /usr/bin/bash -l ensures, that the profile.d scripts are executed for an initialized environment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文