Pisanie /usr/bin/env sed -f
w terminalu działa.
Ale jeśli użyjesz go jako shebang,
#!/usr/bin/env sed -f
s/a/b/
Wykonanie skryptu nie powiedzie się:
/usr/bin/env: sed -f: No such file or directory
Wierzę, że jest to związane z -f. Ale jak to rozwiązać?
scripting
sed
executable
env
Cheng
źródło
źródło
Odpowiedzi:
Nie można przenośnie umieścić więcej niż jednego argumentu w
#!
wierszu . Oznacza to tylko pełną ścieżkę i jeden argument (np.#!/bin/sed -f
Lub#!/usr/bin/sed -f
) lub#!/usr/bin/env
brak argumentu dla tłumacza.Obejściem, które pozwala uzyskać przenośny skrypt, jest użycie
#!/bin/sh
i otoki powłoki, które przekazują skrypt sed jako argument wiersza poleceń. Zauważ, że nie jest to sankcjonowane przez POSIX (skrypty składające się z wielu instrukcji muszą być napisane z osobnym-e
argumentem dla każdej instrukcji przenośności), ale działa z wieloma implementacjami.W przypadku długiego skryptu wygodniejsze może być użycie heredoc. Zaletą heredoc jest to, że nie musisz cytować pojedynczych cudzysłowów, jeśli takie istnieją. Główną wadą jest to, że skrypt jest zasilany standardowym wejściem, co ma dwie irytujące konsekwencje. Niektóre wersje sed wymagają
-f /dev/stdin
zamiast tego-f -
, co stanowi problem w zakresie przenośności. Co gorsza, skrypt nie może działać jako filtr, ponieważ standardowym wejściem jest skrypt i nie mogą to być dane.Minusem heredoka można zaradzić poprzez przydatne użycie
cat
. Ponieważ powoduje to ponowne umieszczenie całego skryptu w wierszu poleceń, nie jest on zgodny z POSIX, ale w dużej mierze jest przenośny w praktyce.Innym obejściem jest napisanie skryptu, który można przeanalizować zarówno przez sh, jak i przez sed. Jest przenośny, dość wydajny, tylko trochę brzydki.
Objaśnienia:
b
; zawartość nie ma znaczenia, o ile funkcja jest poprawnie sformatowana pod względem składniowym (w szczególności nie można mieć pustej funkcji). Następnie, jeśli jest to prawda (tj. Zawsze), uruchomsed
skrypt.()
etykiety, a następnie dobrze sformułowany tekst. Następniei
polecenie, które nie działa, ponieważ zawsze jest pomijane. Na koniec()
etykieta, po której następuje przydatna część skryptu.źródło
#!/usr/bin/env
bez argumentu”. nie jest dobrze sformułowany. Być może „lub#!/usr/bin/env sed
bez argumentu do sed”.Istnieje wiele różnych niekompatybilnych implementacji shebang (#!) W zależności od systemu operacyjnego. Niektórzy budują pełną listę argumentów, inni zachowują ścieżkę poleceń i umieszczają wszystkie pozostałe argumenty jako jeden, inni ignorują wszystkie argumenty i przekazują tylko ścieżkę poleceń, a na koniec niektórzy przekazują cały ciąg jako pojedynczy dowództwo. Wydaje się, że jesteś w tym drugim przypadku.
źródło
env próbuje znaleźć plik o nazwie „sed -f”. Możesz wypróbować „#! / Usr / bin / sed -f” jako linię shebang.
źródło
Od wersji GNU coreutils 8.30 możesz:
Ta cecha dodano w ostatnim (2018-04-20) zobowiązać do
env.c
W GNU Coreutils opakowania, które dodaje się do-S
lub--split-string
opcji.Ze strony podręcznika
env
:Więcej przykładów jest dostępnych w podręczniku GNU coreutils .
Jeśli użyjesz również
-v
opcji dla pełnych danych wyjściowych, możesz dokładnie zobaczyć, jakenv
dzieli ciąg argumentów:W
my_sed_script.sed
:Wykonanie:
Uwaga: Dotyczy to tylko shebangów, które są używane
/usr/bin/env
, ponieważ--split-string
jest to właściwość GNUenv
.źródło
Ta odpowiedź zawiera ścieżkę do eleganckiego rozwiązania: /programming//a/1655389/642372
read
heredoc w zmienną powłoki.sed
.Próba:
źródło
Podoba mi się rozwiązanie Walkera, ale można je ulepszyć (umieszczając to w osobnej odpowiedzi, ponieważ komentarze nie akceptują sformatowanego tekstu). To może nie działać na wszystkich wersjach Linuxa lub Basha, ale w Ubuntu 17.10 możesz to ograniczyć do następujących elementów:
Możesz usunąć
eval
i uprościćread
polecenie, ale musisz pozbyć się komentarza w heredoc.Ponadto, o wszystko, co kiedykolwiek chciałeś wiedzieć o sed, ale bałeś się zapytać, jest bardzo przydatny samouczek na stronie http://www.grymoire.com/unix/sed.html . To sugeruje jeszcze lepsze rozwiązanie, kosztem utraty
/usr/bin/env
i twardego kodowania ścieżki do sed:Ma to tę dodatkową zaletę, że obsługuje więcej niż jedną
s///
wymianę.źródło