Wir werden den Befehl sh -c und das Verhalten beim Aufruf eines Skripts daraus organisieren, insbesondere wie die Konfigurationsdateien rund um zsh (.zshrc usw.) gelesen werden.
Dies ist der Punkt, an dem Sie leicht von Docker-Einstiegspunkten, CI/CD-Einstellungen und Aufrufen externer Tools begeistert sein können.
Was ist sh -c?
Kurz gesagt, es „interpretiert die Argumentzeichenfolge als Befehl und führt ihn aus“.
sh -c "echo Hello World"Ich spreche davon, wie es sich von der normalen Eingabe eines Befehls unterscheidet, aber es wird hauptsächlich in den folgenden Szenen benötigt.
Wenn Sie mit sudo umleiten möchten
sudo echo "text" > /etc/file führt zu einem Berechtigungsfehler. Dies liegt daran, dass die Umleitung mit allgemeinen Benutzerrechten durchgeführt wird.
sudo sh -c "echo 'text' > /etc/file" ist erfolgreich, da die gesamte Shell als Root ausgeführt wird.
Wenn Sie && oder | mit Docker/K8s verwenden möchten
Wenn Sie mehrere Befehle verbinden oder eine Pipe mit CMD oder ENTRYPOINT verwenden möchten, wird die Syntax nicht analysiert, es sei denn, Sie gehen durch die Shell.
Wenn Sie Go-Binärdateien usw. über sh ausführen möchten
sh ./my-binary verursacht einen Fehler, weil es „versucht, die Binärdatei als Shell-Skript zu lesen“.
sh -c ./my-binary sagt „Führen Sie den Befehl in diesem Pfad aus“, sodass er auch im Binärformat ausgeführt werden kann.
Vererbungsregeln für Umgebungsvariablen
Werden Umgebungsvariablen an das mit sh -c aufgerufene Skript übergeben?
Bestätigungscode
# 親側export MY_ENV="hoge"sh -c "./sample.sh"echo "$MY_ENV"Ergebnisse
- Cover, wenn exportiert (
hogeerscheint) - Wird nicht bestanden, wenn nicht exportiert (wird leer sein)
Die Variable export wird vom untergeordneten Prozess (sh -c) an den untergeordneten Prozess (sample.sh) vererbt. Natürlich müssen Sie sich darüber im Klaren sein, dass sh -c einen separaten Prozess startet.
Ist Shebang wirksam?
Beim Aufruf des Skripts für zsh von main.sh über sh -c.
main.sh```sh sh -c ”./sample.sh”
**sample.sh**```sh#!/usr/bin/env zsh# zsh特有の処理...Ergebnisse
**Es funktioniert ordnungsgemäß als zsh. **
sh fungiert einfach als Launcher, und das Betriebssystem schaut sich die erste Zeile (Shebang) von sample.sh an und startet zsh.
Beim Lesen mit Quelle (oder .) ist es jedoch NG.
- ✅
sh -c "./sample.sh"→ zsh startet und läuft (Shebang aktiviert) - ❌
sh -c ". ./sample.sh"→ Geladen als sh (Shebang ignoriert = Syntaxfehler)
Wird die zsh-Konfigurationsdatei gelesen?
Werden .zshrc und .zprofile geladen, wenn sample.sh (zsh-Skript) ausgeführt wird?
Fazit: Kaum belastet
| Dateiname | Geladen? | Grund |
|---|---|---|
.zshenv | JA | Nur lesen. Gültig in allen Modi. |
.zprofile | NEIN | Wird ignoriert, da es sich nicht um eine „Login-Shell“ handelt. |
.zshrc | NEIN | **Ignoriert, da es sich nicht um eine „interaktive Shell“ handelt. ** |
.zlogin | NEIN | Wird ignoriert, da es sich nicht um eine „Login-Shell“ handelt. |
Beim Ausführen eines Skripts (nicht interaktiver Modus) wird .zshrc übersprungen, um unnötige Ausgaben oder Aliase zu vermeiden.
Aus diesem Grund funktioniert der in .zshrc geschriebene Alias im Skript nicht.
Wenn Sie es wirklich laden möchten
Die einzige Möglichkeit besteht darin, im Skript explizit source anzugeben.
#!/usr/bin/env zshsource ~/.zshrc # 無理やり読み込む
my_alias_commandWenn .zshrc jedoch Ausgaben wie Echo enthält, wird diese mit der Skriptausgabe vermischt, daher wird dies nicht empfohlen.
Die richtige Antwort besteht darin, die vom Skript benötigten Umgebungsvariablen in .zshenv zu schreiben (unabhängig davon, ob sie gut oder schlecht sind).
Zusammenfassung
sh -c ist praktisch, kann aber verwirrend werden, wenn Sie Prozessgrenzen und Regeln zum Laden von Konfigurationsdateien nicht verstehen.
Insbesondere in Docker- und CI/CD-Umgebungen funktioniert es möglicherweise nicht innerhalb des Containers, selbst wenn es lokal funktioniert. Dies wird häufig dadurch verursacht, dass die Umgebungsvariable export vergessen wird oder von .zshrc abhängig ist.
Es ist sicher, in Skripten verwendete Einstellungen in .zshenv zu konsolidieren und Funktionen und Skripte anstelle von Aliasen zu verwenden.
hsb.horse