如何使用su作为该用户执行bash脚本的其余部分?

如何使用su作为该用户执行bash脚本的其余部分?,bash,permissions,sudo,user-permissions,su,Bash,Permissions,Sudo,User Permissions,Su,我编写了一个脚本,它以用户名和项目的串联字符串作为参数。脚本应该根据项目字符串将(su)切换到用户名cd到特定目录 我基本上想做: su $USERNAME; cd /home/$USERNAME/$PROJECT; svn update; 问题是,一旦我做了一个苏。。。它就在那里等着。这是有意义的,因为执行流程已经转移到切换到用户。一旦我退出,其余的事情就会执行,但它并没有按预期的那样工作 我在svn命令前添加了su,但命令失败(即,它没有更新所需目录中的svn) 如何编写一个脚

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

我基本上想做:

su $USERNAME;  
cd /home/$USERNAME/$PROJECT;  
svn update;  
问题是,一旦我做了一个苏。。。它就在那里等着。这是有意义的,因为执行流程已经转移到切换到用户。一旦我退出,其余的事情就会执行,但它并没有按预期的那样工作

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

如何编写一个脚本,允许用户切换用户并调用svn(除其他外)?

诀窍是使用“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
而不是username1

使用
sudo

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

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


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

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

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

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

如果您疯狂地以root用户身份运行perl脚本,则可以使用包含真实/有效uid/gid的
$<$($>$)
变量来执行此操作,例如:

#!/usr/bin/perl -w
$user = shift;
if (!$<) {
    $> = getpwnam $user;
    $) = getgrnam $user;
} else {
    die 'must be root to change uid';
}
system('whoami');
#/usr/bin/perl-w
$user=shift;
如果(!$=getpwnam$用户;
$)=getgrnam$user;
}否则{
die“必须是根才能更改uid”;
}
系统(“whoami”);

使用如下脚本在其他用户下执行脚本的其余部分或部分:

#!/bin/sh

id

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

id

eof
#/垃圾箱/垃圾箱
身份证件

exec sudo-u transmission/bin/sh-简单得多:使用
sudo
运行shell,并使用

#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami
#/usr/bin/env bash
哇
sudo-i-u someuser bash这对我很有效

我将我的“资源调配”从“启动”中分离出来

然后在我的开始_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 &
#/usr/bin/env bash
回显“启动服务器环境”
#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安装0/dev/null&;bower安装0/dev/null&”)
cd/vagrant_项目/myproj
nohup grunt connect:服务器:keepalive 0/dev/null&
nohup apimocker-c/vagrant_projects/myproj/mock_api_data/config.json 0/dev/null&

这里是另一种方法,在我的情况下更方便(我只想放弃根权限,从受限用户处执行脚本的其余部分):您可以让脚本从正确的用户处重新启动。让我们假设它最初作为根运行。然后它会像这样:

#!/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 beyond that line,
  # because exec replaces running process with the new one
fi

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

灵感来自@的想法,但我改变了以下几行:

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
脚本。

但不起作用-在第一个sudo完成执行后,cd将丢失。实际上,您甚至不能直接调用cd,因为它不是一个外部命令。
sudo
可能很方便,但如果它不是现成的(比如在AIX上)
su-c'commands'
是正确的答案。-1因为sudo可以暂时获得其他用户的权限。这是不可能的,因为shell脚本本身运行的用户无法更改(这是原始问题所问的)。使用sudo调用其他进程不会改变脚本本身的运行身份。我有一个类似的问题,但我想为其他用户运行
chsh
。我的问题列在这里的“如何根据我的情况调整你的答案?”上。我这样做了-但它仍然要求我输入密码。@Hippyjim你确定你的用户名正确吗?我这样做了-结果我还需要允许使用/bin/bash。无论你使用
sudo
还是
su
,都是次要的,虽然
sudo
更安全、更方便。你可能想使用“sudo-i-u…”来确保$HOME之类的东西设置正确。对不起,noob的问题,这里有什么id?@NitinJadhav,他在这里使用它只是为了显示当前用户的id,root的id是0,所以第一个id会显示一些数字,但第二个将明确显示0(因为第二个是在root运行的块中执行的)。您可以使用用户
whoami
代替
id
,后者将返回名称而不是id@MohammedNoureldin谢谢
sudo
可能很方便,但如果它不是现成的(比如在AIX上),那就没有什么好处
su-c'commands'
是正确答案。这是唯一正确的答案。sudo不是必需的。您可能还需要为shell提供
su-s/bin/bash
。对于root用户的最佳解决方案对于那些默认情况下没有安装sudo的用户来说是最好的答案(我正在查看AIX),我想知道为什么它的评级不高。它最好地解决了原始问题,同时将所有内容都保存在bash中。或者
runuser-u$user--“$@”
,如su(1)Yes中所述,

#!/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 beyond that line,
  # because exec replaces running process with the new one
fi

echo "This will be run from user $UID"
...
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