Piping ein Skript mit "Lesen", um zu schlagen

10

Ich brauche ein Skript ausgeführt werden soll , indem es durch Rohrleitungen bashmit wget(anstatt es direkt mit bash ausgeführt wird ).

$ wget -O - http://example.com/my-script.sh | bash

Es funktioniert nicht, weil mein Skript readAnweisungen enthält. Aus irgendeinem Grund funktionieren diese nicht, wenn Sie zu bash leiten:

# Piping to bash works in general
$ echo 'hi'
hi
$ echo "echo 'hi'" | bash
hi

# `read` works directly
$ read -p "input: " var
input: <prompt>

# But not when piping - returns immediately
$ echo 'read -p "input: " var' | bash
$

Anstatt input:nach einem Wert zu fragen und ihn anzufordern, wird der Lesebefehl einfach von übergeben bash.

Weiß jemand, wie ich ein Skript mit readzu bashleiten kann ?

Robin Winslow
quelle

Antworten:

16

readliest von der Standardeingabe. Die Standardeingabe des Bash-Prozesses wird jedoch bereits vom Skript übernommen. Abhängig von der Shell wird entweder readnichts gelesen, da die Shell das gesamte Skript bereits gelesen und analysiert hat, oder es readwerden unvorhersehbare Zeilen im Skript verwendet.

Einfache Lösung:

bash -c "$(wget -O - http://example.com/my-script.sh)"

Komplexere Lösung, eher für Bildungszwecke als zur Veranschaulichung einer guten Lösung für dieses spezielle Szenario:

echo '{ exec </dev/tty; wget -O - http://example.com/my-script.sh; }' | bash
Gilles 'SO - hör auf böse zu sein'
quelle
Super danke. Das ist fast genauso elegant.
Robin Winslow
2

Die Prozessersetzung macht das, was Sie wollen:

bash <(wget ...)

Trotzdem muss ich Ihre Motivation hier in Frage stellen. Wenn Sie den Webserver steuern (und https verwenden), ist dies möglicherweise sinnvoll. Aber nur ein Skript über das Internet blind auszuführen, ist sehr riskant.

Lexelby
quelle
just running a script from the internet blind is very risky- Ja, wir wissen, dass es riskant ist, aber die Leute können Skripten bestimmter Organisationen vertrauen. Siehe die Diskussion in den Kommentaren zur Antwort von @ Xen2050.
Robin Winslow
1

Stimmt etwas nicht mit:

wget -O tmpscript.sh http://example.com/my-script.sh
chmod +x tmpscript.sh
tmpscript.sh

?

Xen2050
quelle
Denn dann muss ich eine Datei erstellen. Ich meine, es würde funktionieren, es ist nur ein bisschen chaotisch.
Robin Winslow
1
Wahr. Obwohl dies ein guter Grund ist, verwenden /tmpviele Programme temporäre Dateien. Ich würde es leid sein, heruntergeladene Skripte sofort auszuführen, ohne vorher einen Blick darauf zu werfen ...
Xen2050
Nun, das ist dein Anruf. Viele Projekte bieten diese Einzeiler an, z. B. Docker , Ohmyzsh und andere, an die ich mich derzeit nicht erinnern kann. In diesem Fall handelt es sich um ein Setup-Skript, das ich auf neuen Systemen aus meinem eigenen Repository ausführen möchte. Ich mache mir keine Sorgen um den Inhalt, wie ich ihn geschrieben habe.
Robin Winslow
3
Ich denke an jemanden, der diese Frage findet (vielleicht ein völlig neuer Benutzer), der es vielleicht nicht besser weiß.
Xen2050