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 ?

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

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.


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

?


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.