2017-03-16 3 views
0

ich das Folgende ausführen möchten:BASH - wie Echo Arbeiten innerhalb EOF-Tags

PASSWORD="mypassword" 
RUNCOMMAND=$(cat <<EOF 
echo $PASSWORD | sudo -S sudo echo "this is it babe" 
EOF 
) 

Aber statt this is it babe ich folgendes Ergebnis:

mypassword | sudo -S sudo echo "this is it babe" 

ich mit cat <<\EOF versucht, cat <<'EOF' immer noch kein Glück.

Irgendwelche Ideen?

+0

Könnte es sein, dass du den Wald verloren hast, als du nach den Bäumen hier gesucht hast? Es scheint mir, dass Ihr tatsächliches Problem ziemlich einfach ist. In jedem Fall wird Code innerhalb eines Heredoc-Blocks nicht ausgeführt. Das ist der Punkt. Wenn Sie es ausführen möchten, schreiben Sie es einfach als normalen Code. – 5gon12eder

Antwort

2

Sie verwechseln eine heredoc mit einer pipeline.

heredoc mit variabler Expansion:

cat <<EOF 
some text, possibly with variables: ${HOME}/$(whoami) 
EOF 
some text, possibly with variables: /home/attie/attie 

heredoc ohne variable Expansion:

cat <<"EOF" 
some text, possibly with variables: ${HOME}/$(whoami) 
EOF 
some text, possibly with variables: ${HOME}/$(whoami) 

Pipeline mit variabler Ausdehnung (man beachte die Anführungszeichen, "):

echo "some text, possibly with variables: ${HOME}/$(whoami)" | cat 
some text, possibly with variables: /home/attie/attie 

Pipeline ohne variable Erweiterung (die Anführungszeichen beachten, '):

echo 'some text, possibly with variables: ${HOME}/$(whoami)' | cat 
some text, possibly with variables: ${HOME}/$(whoami) 

${...} erweitert eine Umgebungsvariable

$(...) einen Befehl ausgeführt wird, und setzt seine stdout


Es sieht auch wie Sie versuchen, Ihr Kennwort in sudo eintragen lassen - das wird nicht funktionieren, wie sudo das Terminal repoen Ihr Passwort zu erhalten, bevor es stdin auf die endgültige Anwendung übergeben.

+0

'sudo -S' erhält das Passwort von stdin. Das ursprüngliche Beispiel funktioniert, wenn Sie einfach in das Terminal einfügen. In der Zwischenzeit fand ich die Lösung, obwohl ich danke Ihnen für Ihre Zeit, sehr geschätzt. – arcol

+0

ah, ja. Entschuldigung – Attie

-1

Die endgültige Lösung ist recht einfach:

PASSWORD="mypassword" 
RUNCOMMAND=$(cat <<EOF 
echo $PASSWORD | sudo -S sudo echo "this is it babe" 
EOF 
) 

und führen Sie es über eval:

eval $RUNCOMMAND 

Sorry für Ihre Zeiten mit diesem offensichtlichen Problem Jungs stehlen :)

Die usecase für das obige ist zu echo ein gegebener Befehl, bevor er es wirklich durchführt.

So:

fun_run_command(){ 
# execute the final command 
echo `eval $RUNCOMMAND` 
} 

fun_echo_command(){ 
# echo the command which will be launched (fun_run_command()) 
echo ${RUNCOMMAND//$PASSWORD/PASSWORD} 
} 

RUNCOMMAND=$(cat <<EOF 
echo $PASSWORD | sudo -S sudo docker run --restart=always \ 
--name ${USER_NAME}_`date +%Y%m%d-%H%M%S` \ 
-d \ 
-e "VIRTUAL_HOST=$USER_VIRTUAL_HOST" \ 
-e "VIRTUAL_PORT=$USER_VIRTUAL_PORT" \ 
-e "PORT=$USER_VIRTUAL_PORT" \ 
-p $USER_VIRTUAL_PORT:$USER_VIRTUAL_PORT \ 
$USER_IMAGE 
EOF 
) 

Wie Sie den Befehl sehen kann, was ich starten ist ziemlich lang, so ist es immer sinnvoll, Doppelprüf was durch das Skript ausgeführt wird.

Mit Kopie & fügen Sie den gleichen Befehl auf mehrere Funktion ist anfällig für Fehler.

1

Sie beginnen von einer falschen Voraussetzung, dass eval $RUNCOMMAND etwas ist, was Sie tun sollten. Es ist nicht; Variablen sind für Daten, Funktionen sind für Code.

run_command() { 
    docker_run_options=(
     --restart=always 
     --name "${USER_NAME}_$(date +%Y%m%d-%H%M%S)" 
     -d 
     -e "VIRTUAL_HOST=$USER_VIRTUAL_HOST" 
     -e "VIRTUAL_PORT=$USER_VIRTUAL_PORT" 
     -e "PORT=$USER_VIRTUAL_PORT" 
     -p "$USER_VIRTUAL_PORT:$USER_VIRTUAL_PORT" 
    ) 

    echo "$1" | sudo -S sudo docker run "${docker_run_options[@]}" "$USER_IMAGE" 
} 

fun_run_command() { 
    run_command "PASSWORD" 
} 
+0

der springende Punkt ist, einfach den Befehl zu echo, was ausgeführt wird. Man fügt also den Befehl in eine Variable ein und verwendet eine Funktion ('fun_echo_command'), die ihn als Standard ausgibt und eine andere Funktion (' fun_run_command') verwendet, die ihn ausführt. Diese Funktion ist allgemein genug, um in einer externen Datei zu leben (in meinem Fall ist dies "common/variables.sh"), die ich in meine Skripte einbeziehe. Ich sehe nicht, wie Sie das Echo vor der Ausführung erzielen könnten, ohne Befehle an die andere Funktion zu kopieren. – arcol

+0

Die Sicherheitsimplikation von 'eval' ist in diesem Fall eher strittig. Da das Skript nach einer * Benutzereingabe * fragt, kann der Benutzer also, wenn er bösartigen Code in eine der Variablen schreiben will, dies im Terminal (ohne das Skript) überhaupt tun. Trotzdem sehe ich nicht, wie du den Befehl "echo" hören könntest, was zuerst ausgeführt wird. (das ist mein Ziel) – arcol