【问题标题】:How can I execute a group of commands as another user in Bash?如何在 Bash 中作为另一个用户执行一组命令?
【发布时间】:2013-07-19 10:56:46
【问题描述】:

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

例如,考虑以下脚本:

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

这里有几点需要注意:

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

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

以上第二点禁止使用以下语法:

su somebody -c "command"

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

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

【问题讨论】:

标签: bash su


【解决方案1】:

试试这个:

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

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

【讨论】:

  • 如果遇到“su: must be run from a terminal”,试试sudo su somebody &lt;&lt;'EOF'
  • 如果你使用&lt;&lt;EOF而不是&lt;&lt;'EOF',那么here-doc中的变量将会被展开。
  • 这对某些人很有用:如果您需要命令在用户的完整环境中实际运行,就好像他们已经登录一样,例如可能包括不同的路径。在“某人”之前添加连字符,如下所示:su - 某人 ...
  • 确保在关闭 EOF 之前没有空格(例如,从缩进的 'if' 语句调用时)。否则会引发错误 - 请参阅 tldp.org/LDP/abs/html/here-docs.html
  • @PatrizioBekerle 我在终端中以交互方式完成了它,但我也只是在脚本中尝试过,它们都有效。
【解决方案2】:

我不太擅长使用 Bash-foo,所以肯定会有更优雅的方式,但我过去曾通过使用多个脚本和一个“驱动程序”来解决这个问题。

例如,

司机

#!/bin/bash
set -e

su root script1
su somebody script2

脚本1

#!/bin/bash
set -e

root_command -p param1  # Run as root

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

【讨论】:

    【解决方案3】:

    此脚本检查当前运行该脚本的用户是否是所需用户。如果不是,则使用所需用户重新执行脚本。

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

    【讨论】:

      猜你喜欢
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      • 2021-10-07
      • 2017-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多