2013-07-20 9 views
55

Ci sono già some existing questions qui richiesti sull'esecuzione di comandi come un altro utente. Tuttavia, la domanda e le risposte si concentrano su un singolo comando invece di un lungo gruppo di comandi.Come eseguire un gruppo di comandi come un altro utente in Bash?

Ad esempio, si consideri il seguente 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' 

ci sono un paio di punti importanti da notare qui:

  • I tre comandi finali deve essere eseguito come un altro utente che utilizza su o sudo. Nell'esempio c'erano tre comandi, ma supponiamo che ce ne fossero molti altri ...

  • I comandi stessi fanno uso di virgolette singole e doppie.

Il secondo punto sopra impedisce l'uso della seguente sintassi:

su somebody -c "command" 

... poiché i comandi stessi contengono virgolette.

Qual è il modo corretto di "raggruppare" i comandi ed eseguirli con un altro account utente?

+1

Qualche fortuna su Unix stackexchange? – icedwater

+0

Vedi anche ora http://stackoverflow.com/questions/37586811/pass-commands-as-input-to-another-command-su-ssh-sh-etc/37586820#37586820 – tripleee

risposta

125

Prova questo:

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

<< introduce un qui-doc. Il token successivo è il delimitatore e tutto quanto fino a una riga che inizia con il delimitatore viene alimentato come input standard per il comando. Mettendo il delimitatore tra virgolette singole si evita la sostituzione di variabili all'interno di here-doc.

+0

Tu, signore, sei un genio. Avevo pensato di usare HEREDOC ma non ho trovato la sintassi corretta per farlo funzionare. Grazie! –

+0

Perché il flag '-c' non è necessario? Senza '-c', ottengo un errore di autorizzazione negato. – rightfold

+0

'-c' viene utilizzato quando il comando viene fornito come argomento, anziché essere letto dallo standard input. – Barmar

5

io non sono quel grande con bash-foo per cui v'è un limitato per essere un modo più elegante, ma ho affrontato questo problema in passato utilizzando più script e un "driver"

esempio

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' 
0

Questo script controlla se l'utente corrente che esegue lo script è l'utente desiderato. In caso contrario, lo script viene rieseguito con l'utente desiderato.

#!/usr/bin/env bash 

TOKEN_USER_X=TOKEN_USER_X 
USER_X=peter # other user! 

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

if [[ "[email protected]" != "$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 
Problemi correlati