Zajímalo by mě, zda existuje obecný způsob předávání více možností spustitelnému souboru prostřednictvím řádku shebang (#!
).
Používám NixOS a první část Shebang v jakémkoli skriptu, který píšu, je obvykle /usr/bin/env
. Problém, na který narážím, je, že vše, co následuje, je systémem interpretováno jako jeden soubor nebo adresář.
Předpokládejme například, že chci napsat skript, který má spustit bash
v režimu posix. Naivní způsob psaní shebang by byl:
#!/usr/bin/env bash --posix
ale pokus o provedení výsledného skriptu způsobí následující chybu:
/usr/bin/env: ‘bash --posix’: No such file or directory
Znám tento příspěvek, ale zajímalo mě, zda existuje obecnější a čistší řešení.
UPRAVIT :Vím, že pro Guile skripty existuje způsob, jak dosáhnout toho, co chci, zdokumentovaný v části 4.3.4 příručky:
#!/usr/bin/env sh
exec guile -l fact -e '(@ (fac) main)' -s "$0" "[email protected]"
!#
Trik je v tom, že druhý řádek (začínající exec
) je interpretován jako kód pomocí sh
ale je v #!
… !#
blokovat jako komentář, a tudíž ignorován tlumočníkem Guile.
Nebylo by možné tuto metodu zobecnit na jakýkoli interpret?
Druhá ÚPRAVA :Po malém hraní se zdá, že pro tlumočníky, kteří dokážou číst svůj vstup z stdin
, fungovala by následující metoda:
#!/usr/bin/env sh
sed '1,2d' "$0" | bash --verbose --posix /dev/stdin; exit;
Pravděpodobně to však není optimální, protože sh
proces trvá, dokud tlumočník nedokončí svou práci. Oceníme jakoukoli zpětnou vazbu nebo návrh.
Přijatá odpověď:
Neexistuje žádné obecné řešení, alespoň ne, pokud potřebujete podporovat Linux, protože linuxové jádro považuje vše, co následuje po prvním „slovu“ v řádku shebang, za jediný argument.
Nejsem si jistý, jaká jsou omezení NixOS, ale obvykle bych prostě napsal váš shebang jako
#!/bin/bash --posix
nebo pokud je to možné, nastavte možnosti ve skriptu:
set -o posix
Případně můžete skript nechat restartovat pomocí příslušného shellu:
#!/bin/sh -
if [ "$1" != "--really" ]; then exec bash --posix -- "$0" --really "[email protected]"; fi
shift
# Processing continues
Tento přístup lze zobecnit na jiné jazyky, pokud najdete způsob, jak prvních pár řádků (které jsou interpretovány shellem) cílový jazyk ignorovat.
Související:Jak připojit více řádků k souboru?
GNU coreutils
’ env
poskytuje řešení od verze 8.30, podrobnosti naleznete v odpovědi unode. (Toto je k dispozici v Debianu 10 a novějších, RHEL 8 a novějších, Ubuntu 19.04 a novějších atd.)