如何使用su来执行该用户的其余bash脚本?

Ave*_*ery 116 permissions bash sudo su user-permissions

我编写了一个脚本,它接受一个字符串作为参数,该字符串是用户名和项目的串联.该脚本应该切换(su)到用户名,cd到基于项目字符串的特定目录.

我基本上想做:

su $USERNAME;  
cd /home/$USERNAME/$PROJECT;  
svn update;  
Run Code Online (Sandbox Code Playgroud)

问题是,一旦我做了su ...它只是在那里等待.这是有道理的,因为执行流程已经转移到用户.一旦我退出,其余的东西都会执行,但它不能按预期工作.

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

如何编写允许用户切换用户并调用svn(以及其他内容)的脚本?

Dan*_*scu 89

更简单:用于sudo运行shell并使用heredoc来提供命令.

#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami
Run Code Online (Sandbox Code Playgroud)

(最初在SuperUser上回答)

  • 这个答案效果最好.我建议使用选项`-i`来获得'someuser`的预期环境. (5认同)
  • 真棒解决方案! (3认同)
  • sudo可能很方便,但是如果不能立即使用就不好了(例如在AIX上)。su -c'commands'是正确的答案。 (2认同)
  • 史诗般的解决方案! (2认同)

Kim*_*ais 83

诀窍是使用"sudo"命令而不是"su"

您可能需要添加此项

username1 ALL=(username2) NOPASSWD: /path/to/svn
Run Code Online (Sandbox Code Playgroud)

到你的/ etc/sudoers文件

并将您的脚本更改为:

sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update" 
Run Code Online (Sandbox Code Playgroud)

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

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

  • 无论你使用`sudo`还是`su`都是次要的,尽管`sudo`更加安全和方便. (3认同)

小智 53

使用以下脚本在另一个用户下执行其余部分或部分脚本:

#!/bin/sh

id

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

id

eof
Run Code Online (Sandbox Code Playgroud)

  • 你可能想使用"sudo -i -u ..."来确保正确设置$ HOME之类的东西. (11认同)
  • 抱歉,我问了一个菜鸟问题,但是这里的 id 是什么? (2认同)
  • @NitinJadhav,他在这里用它只是为了显示当前用户的ID,root的ID是0,所以第一个id会显示一些数字,但第二个id肯定会显示0(因为第二个是在里面执行的)由 root 运行的块)。您可以使用“whoami”而不是“id”,这将返回名称而不是 ID (2认同)

Dou*_*der 45

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

su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME" 
Run Code Online (Sandbox Code Playgroud)

  • 这是唯一正确的答案.sudo不是必需的. (3认同)

Mar*_*oft 38

这是另一种方法,在我的情况下更方便(我只想删除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"
...
Run Code Online (Sandbox Code Playgroud)

  • 我想知道为什么这不是更高的评级.它正在解决最原始的问题,同时保持一切都在bash中. (4认同)
  • 或者 `runuser -u $user -- "$@"`,如 su(1) 中所述 (2认同)
  • 用 `exec sudo -i -u "$user" $( readlink -f "$0" ) -- "$@"` 替换 exec 行对我有用。 (2认同)

iam*_*mac 7

sudo改用

编辑:道格拉斯指出,你不能使用cd,sudo因为它不是一个外部命令.您必须在子shell中运行命令才能完成cd工作.

sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"
Run Code Online (Sandbox Code Playgroud)

sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update
Run Code Online (Sandbox Code Playgroud)

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


P-N*_*uts 6

在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');
Run Code Online (Sandbox Code Playgroud)

  • 从某种意义上说,shell脚本本身运行的用户无法更改(这是原始问题所要求的).使用sudo调用其他进程不会更改脚本本身的运行方式. (4认同)