web-dev-qa-db-ja.com

Bashで別のユーザーとしてコマンドのグループを実行するにはどうすればよいですか?

いくつかの既存の質問 別のユーザーとしてコマンドを実行することについてここで尋ねられています。ただし、質問と回答は、コマンドの長いグループではなく単一のコマンドに焦点を当てています。

たとえば、次のスクリプトを考えます。

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

ここで注意すべき重要な点がいくつかあります。

  • 最後の3つのコマンドは、suまたはSudoを使用して別のユーザーとして実行する必要があります。例では3つのコマンドがありましたが、さらに多くのコマンドがあると仮定します...

  • コマンド自体は、単一引用符と二重引用符を使用します。

上記の2番目の点により、次の構文を使用できなくなります。

su somebody -c "command"

...コマンド自体に引用符が含まれているため。

コマンドを「グループ化」して別のユーザーアカウントで実行する適切な方法は何ですか?

63
Nathan Osman

これを試して:

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

<<here-docを導入します。次のトークンは区切り文字であり、区切り文字で始まる行までのすべてがコマンドへの標準入力として供給されます。区切り文字を一重引用符で囲むと、here-doc内での変数の置換が防止されます。

144
Barmar

私はbash-fooにはあまり向いていないので、もっとエレガントな方法が必要ですが、過去に複数のスクリプトと「ドライバー」を使用してこの問題に取り組んできました。

例えば。

Driver

#!/bin/bash
set -e

su root script1
su somebody script2

Script1

#!/bin/bash
set -e

root_command -p param1  # run as root

Script2

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

このスクリプトは、スクリプトを実行している現在のユーザーが目的のユーザーかどうかを確認します。そうでない場合、スクリプトは目的のユーザーで再実行されます。

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