Answers:
诀窍是使用“ 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
sudo
还是su
次要的,它sudo
都更加安全和方便。
简单得多:用于sudo
运行Shell并使用Heredoc向其提供命令。
#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami
(最初在SuperUser上回答)
-i
获得someuser
的预期环境。
sudo
可能很方便,但是如果不开箱即用(例如在AIX上),那就不好了。su -c 'commands'
是正确的答案。
使用类似于以下的脚本在另一个用户下执行脚本的其余部分:
#!/bin/sh
id
exec sudo -u transmission /bin/sh - << eof
id
eof
whoami
代替,id
而是返回名称而不是id
sudo
可能很方便,但是如果不开箱即用(例如在AIX上),那就不好了。su -c 'commands'
是正确的答案。
您需要将所有不同用户的命令作为自己的脚本执行。如果只是一个或几个命令,那么内联应该起作用。如果命令很多,最好将它们移动到自己的文件中。
su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME"
su -s /bin/bash
。
这是另一种方法,在我的情况下更方便(我只想放弃root特权,并从受限用户处执行脚本的其余部分):您可以使脚本从正确的用户处重新启动。假设它最初是作为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 beyond that line,
# because exec replaces running process with the new one
fi
echo "This will be run from user $UID"
...
runuser -u $user -- "$@"
,如su(1)
exec su "$user" "$0" -- "$@"
--
是非常有用的。
使用sudo
替代
编辑:正如道格拉斯指出的那样,您不能使用它cd
,sudo
因为它不是外部命令。您必须在子shell中运行命令才能进行cd
工作。
sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"
sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update
可能会要求您输入该用户的密码,但只能输入一次。
sudo
可能很方便,但是如果不开箱即用(例如在AIX上),那就不好了。su -c 'commands'
是正确的答案。
无法在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');
这对我有用
我从“启动”中拆分了“配置”。
# 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 &
受@ 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
。如果不需要环境变量,请-E
从sudo中删除。
该/usr/bin/bash -l
保证,该profile.d
脚本用于初始化的环境中执行。
sudo
可能很方便,但是如果不开箱即用(例如在AIX上),那就不好了。su -c 'commands'
是正确的答案。
sudo
。实际上,sudo并不是那么简单,在很多情况下,您甚至需要偶数,sudo -E
并且需要在sudoers.d中添加一个配置条目以允许使用tty而无需执行!requiretty
。但是在很多情况下,对于自动调用的脚本,必须使用sudo,否则密码对话框可能会受到干扰。因此,我不会将其从标准解决方案中删除。
"$@"
字符串意味着将第一个参数之后的参数附加到一个单独的字符串中,而不包含在-c
参数中。如果您想使其安全,可以printf -v arg_q '%q ' "$0" "$@"
然后使用su "$USERNAME" -c "/usr/bin/bash -l $arg_q"
COMMANDARGS=$@
解决了-c
。的问题,以前没有问题,但是我实现了您的良好输入。我只需要做一些实验就可以使它起作用。已经编辑了问题,希望我不会再粘贴其他错误。感谢您的评论,让您
chsh
为其他用户运行。我的问题在此处列出在stackoverflow.com/q/15307289/80353中,如何根据您的情况调整您的答案?