GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Pfadunabhängige Shebangs?

Ich habe ein Skript, das ich auf zwei Computern ausführen möchte. Diese beiden Maschinen erhalten Kopien des Skripts aus demselben Git-Repository. Das Skript muss mit dem richtigen Interpreter ausgeführt werden (z. B. zsh ).

Leider beides env und zsh leben an verschiedenen Orten auf den lokalen und entfernten Rechnern:

Remote-Computer

$ which env
/bin/env

$ which zsh
/some/long/path/to/the/right/zsh

Lokaler Computer

$ which env
/usr/bin/env

$which zsh
/usr/local/bin/zsh

Wie kann ich den Shebang so einrichten, dass das Skript als /path/to/script.sh ausgeführt wird verwendet immer den Zsh verfügbar in PATH ?

Akzeptierte Antwort:

Sie können dies nicht direkt durch Shebang lösen, da Shebang rein statisch ist. Was Sie tun könnten, ist, einen »geringsten Multiplikator« (aus Shell-Perspektive) im Shebang zu haben und Ihr Skript mit der richtigen Shell erneut auszuführen, wenn dieses LCM nicht zsh ist. Mit anderen Worten:Lassen Sie Ihr Skript von einer Shell ausführen, die auf allen Systemen zu finden ist, testen Sie auf ein zsh -only-Funktion und wenn der Test falsch ist, führen Sie das Skript exec aus mit zsh , wo der Test erfolgreich ist und Sie einfach fortfahren.

Eine einzigartige Funktion in zsh , ist beispielsweise das Vorhandensein von $ZSH_VERSION Variable:

#!/bin/sh -

[ -z "$ZSH_VERSION" ] && exec zsh - "$0" ${1+"[email protected]"}

# zsh-specific stuff following here
echo "$ZSH_VERSION"

In diesem einfachen Fall wird das Skript zunächst von /bin/sh ausgeführt (Alle Unix-ähnlichen Systeme nach den 80ern verstehen #! und haben einen /bin/sh , entweder Bourne oder POSIX, aber unsere Syntax ist mit beiden kompatibel). Wenn $ZSH_VERSION ist nicht set, das Skript exec ’s selbst durch zsh . Wenn $ZSH_VERSION gesetzt ist (bzw. das Skript bereits durch zsh gelaufen ist ), wird der Test einfach übersprungen. Voilà.

Dies schlägt nur fehl, wenn zsh ist nicht im $PATH überhaupt.

Bearbeiten: Um sicherzugehen, führen Sie nur exec aus ein zsh An den üblichen Stellen könnten Sie so etwas wie

verwenden
for sh in /bin/zsh 
          /usr/bin/zsh 
          /usr/local/bin/zsh; do
    [ -x "$sh" ] && exec "$sh" - "$0" ${1+"[email protected]"}
done

Dies könnte Sie vor versehentlichem exec bewahren etwas in Ihren $PATH einfügen was nicht der zsh ist du erwartest.

Verwandte:Zitieren in ssh $host $FOO und ssh $host “sudo su user -c $FOO” Typkonstrukten?
Linux
  1. Wie debuggt man ein Bash-Skript?

  2. Zeitüberschreitung in einem Shell-Skript?

  3. ${!foo} Und Zsh?

  4. Bestimmen des Pfads zum bezogenen Shell-Skript?

  5. Überprüfen, ob ein Skript ausgeführt wird?

35 Bash-Skriptbeispiele

So führen Sie ein Bash-Skript aus

Wo soll das zsh-Autocompletion-Skript unter Linux platziert werden?

Wie führe ich ein .sh-Skript von einem beliebigen Pfad in einem Terminal aus?

Node.js-Skript konnte nicht mit systemctl gestartet werden

Wie führe ich ein Bash-Skript über einen absoluten Pfad aus?