web-dev-qa-db-fra.com

Comment exécuter un groupe de commandes en tant qu'autre utilisateur dans Bash?

Il y a déjà quelques questions existantes ici demandé d'exécuter des commandes en tant qu'utilisateur différent. Cependant, la question et les réponses se concentrent sur une seule commande au lieu d'un long groupe de commandes.

Par exemple, considérons le script suivant:

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

Il y a quelques points importants à noter ici:

  • Les trois dernières commandes doivent être exécutées comme un autre utilisateur à l'aide de su ou Sudo. Dans l'exemple, il y avait trois commandes, mais supposons qu'il y en ait beaucoup plus ...

  • Les commandes elles-mêmes utilisent des guillemets simples et doubles.

Le deuxième point ci-dessus empêche l'utilisation de la syntaxe suivante:

su somebody -c "command"

... puisque les commandes elles-mêmes contiennent des guillemets.

Quelle est la bonne façon de "grouper" les commandes et de les exécuter sous un autre compte utilisateur?

63
Nathan Osman

Essaye ça:

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

<< introduit un ici-doc. Le jeton suivant est le délimiteur, et tout ce qui va jusqu'à une ligne commençant par le délimiteur est alimenté en entrée standard de la commande. Mettre le délimiteur entre guillemets simples empêche la substitution de variable dans le here-doc.

144
Barmar

Je ne suis pas très bon avec bash-foo, alors il y a forcément une manière plus élégante, mais j'ai déjà abordé ce problème en utilisant plusieurs scripts et un "pilote".

Par exemple.

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

Ce script vérifie si l'utilisateur actuel exécutant le script est l'utilisateur souhaité. Sinon, le script est réexécuté avec l'utilisateur souhaité.

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