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?
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.
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'
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