如何在 Bash 中以另一个用户身份执行一组命令?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17758235/
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 23:57:44  来源:igfitidea点击:

How to execute a group of commands as another user in Bash?

bashsu

提问by Nathan Osman

There are already some existing questionsasked here about running commands as another user. However, the question and answers focus on a single commandinstead of a long group of commands.

这里已经有一些关于以其他用户身份运行命令的现有问题。但是,问题和答案集中在单个命令上,而不是一长串命令上。

For example, consider the following script:

例如,考虑以下脚本:

#!/bin/bash
set -e

root_command -p param1  # run as root

# these commands must be run as another user
command1 -p 'parameter with "quotes" inline'
command2 -p 'parameter with "quotes" inline'
command3 -p 'parameter with "quotes" inline'

There are a couple of important points to note here:

这里有几个要点需要注意:

  • The final three commands must be run as another user using suor sudo. In the example there were three commands, but suppose that there were many more...

  • The commands themselves make use of single and double quotes.

  • 最后三个命令必须作为另一个用户使用su或运行sudo。在示例中有三个命令,但假设还有更多...

  • 命令本身使用单引号和双引号。

The second point above prevents the use of the following syntax:

上面的第二点阻止使用以下语法:

su somebody -c "command"

...since the commands themselves contain quotes.

...因为命令本身包含引号。

What is the proper way to "group" the commands and run them under another user account?

“分组”命令并在另一个用户帐户下运行它们的正确方法是什么?

回答by Barmar

Try this:

尝试这个:

su somebody <<'EOF'
command1 -p 'parameter with "quotes" inline'
command2 -p 'parameter with "quotes" inline'
command3 -p 'parameter with "quotes" inline'
EOF

<<introduces a here-doc. The next token is the delimiter, and everything up to a line beginning with the delimiter is fed as standard input to the command. Putting the delimiter in single quotes prevents variable substitution within the here-doc.

<<介绍了一个here-doc。下一个标记是定界符,直到以定界符开头的一行的所有内容都作为命令的标准输入提供。将分隔符放在单引号中可防止 here-doc 中的变量替换。

回答by stefancarlton

I'm not that great with bash-foo so there is a bound to be a more elegant way, but I've approached this problem in the past by using multiple scripts and a "driver"

我对 bash-foo 不是很好,所以肯定有一种更优雅的方式,但我过去通过使用多个脚本和一个“驱动程序”来解决这个问题

E.g.

例如

Driver

司机

#!/bin/bash
set -e

su root script1
su somebody script2

Script1

脚本1

#!/bin/bash
set -e

root_command -p param1  # run as root

Script2

脚本2

#!/bin/bash
set -e

# these commands must be run as another user
command1 -p 'parameter with "quotes" inline'
command2 -p 'parameter with "quotes" inline'
command3 -p 'parameter with "quotes" inline'

回答by swift_dodo

This script checks if the current user running the script is the desired user. If not, then the script is re-executed with the desired user.

此脚本检查当前运行脚本的用户是否是所需的用户。如果没有,那么脚本会以所需的用户重新执行。

#!/usr/bin/env bash

TOKEN_USER_X=TOKEN_USER_X
USER_X=peter # other user!

SCRIPT_PATH=$(readlink -f "$BASH_SOURCE")

if [[ "$@" != "$TOKEN_USER_X" ]]; then

    ###### RUN THIS PART AS the user who started the script

    echo "This script is $SCRIPT_PATH"

    echo -n "Current user: "
    echo $USER

    read -p "insert: "
    echo "got $REPLY"

    su - $USER_X -c "$SCRIPT_PATH $TOKEN_USER_X" # execute code below after else (marked #TOKEN_USER_X)

else
    #TOKEN_USER_X -- come here only if script received one parameter TOKEN_USER_X

    ###### RUN THIS PART AS USER peter

    echo
    echo "Now this script is $SCRIPT_PATH"

    echo -n "Current user: "
    echo $USER

    read -p "insert: "
    echo "got $REPLY"

    exit 0
fi

echo
echo "Back to initial user..."
echo -n "Current user: "
echo $USER