2010-08-13 10 views

Odpowiedz

15

Skrypty powłoki są przetwarzane w trybie line-by-line podczas wykonywania, więc wystarczy upewnić się, że wykonanie nigdy nie dotrze do danych, które chcesz chronić. Można to zrobić, na przykład:

# Some shell code... 

exit 

[data (possibly binary) goes here] 

Aby rzeczywiście czytać dane ze skryptu, można użyć trochę sed magii, aby wydobyć wszystko po pierwszej linii zawierającej jedynie __DATA__, a następnie przechowywać dane wyjściowe, które sed w zmiennej. Oto przykład:

#!/bin/sh 

data=$(sed '0,/^__DATA__$/d' "$0") 
printf '%s\n' "$data" 

exit 

__DATA__ 
FOO BAR BAZ 
LLAMA DUCK COW 

Jeśli zapiszesz ten skrypt jako test-data.sh i uczynić go wykonywalnym, można go uruchomić i uzyskać następujące dane wyjściowe:

$ ./test-data.sh 
FOO BAR BAZ 
LLAMA DUCK COW 
+0

To jest fajne, czy ktoś może wyjaśnić, jak to działa? Nie rozumiałem 'danych = $ (sed '0,/^ __ DATA __ $/d'" $ 0 ")' – rodee

+0

Uruchom polecenie 'sed' i z linii 0 do linii, która pasuje do __DATA__, usuń linię. Reszta zostanie wydrukowana. 0 USD to skrypt, plik do odczytania zawierający dane. – mpersico

+0

Ostrożnie, choć; jeśli pozyskujesz w swoim skrypcie, nie tylko uruchamiasz go, wtedy '$ 0' to twoja nazwa powłoki, a twoje' wyjście' zakończy twoją całą sesję. Zastąp '$ 0'' $ {BASH_ARGV [0]} 'i' exit' opcją 'return'. – mpersico

3

przede wszystkim Perl „__DATA__” pragma jest sposób dostarczania danych wejściowych do $ _ bez określania pliku. W bashu nie ma odpowiednika, ponieważ nie ma on nic podobnego do $ _. Możesz jednak dostarczać dane bezpośrednio w skrypcie bash za pomocą innych środków, takich jak wyraźne ustawienia zmiennych, korzystanie z dokumentów TUTAJ itp.

Jednak nie jestem przekonany, że to jest to, co chcesz zrobić. Wygląda na to, że po jakimś rodzaju metody komentowania blokowego. Czy tak jest?

+0

Tak, ale druga część też jest interesująca. Więc przyjmuję rozwiązanie wyjścia, chociaż nie jest tak ładne jak __DATA__, ponieważ po __DATA__ nie ma już podświetlania składni, a __DATA__ jest bardziej widoczne w kodzie niż wyjście. Jeśli chodzi o dostarczanie danych, prawdopodobnie byłby to dokument TUTAJ, ponieważ łatwiej go zapamiętać niż propozycję bcat. –

+1

Tak, używanie heredoc jest prawie na pewno najlepszym rozwiązaniem do dostarczania dużych ilości danych do skryptu. Jedynym sposobem, w którym skorzystam z mojego rozwiązania (innego niż jako dowód koncepcji), jest to, czy potrzebuję łatwego dołączania danych do skryptu powłoki, który może zawierać terminator heredoc. – bcat

+0

IIUC, jawne ustawianie zmiennych i używanie heredoców spowoduje, że twoje dane będą prawidłowo przycinane w środku kodu. Technika __DATA__ umieści wszystkie dane na końcu, abyś mógł odczytać kod bez przerwania kontekstu. IMO, użycie tego dla danych NIE jest optymalne. Lepiej czytać z zewnętrznego źródła. ALE, może być właściwe dla testu samo-dokumentowania. Używam go tylko do instrukcji USGE, jak wyżej. – mpersico

0

Jest to przydatna technika, jeśli chcesz podać informacje o użytkowaniu skryptu, ale nie chcesz zaśmiecać głównego wiersza kodu tekstem pomocy. Jest także świetny, jeśli chcesz odwołać się do użycia więcej niż jeden raz. Na przykład fragment ze skryptu powłoki:

... 
declare OPTSARGS  
OPTSARGS=$(getoptp -o wh --long nopager,help -n myScript-- "[email protected]") 
status=$? 
if ((status != 0))  
then 
    printf '%s\n' "$(sed '0,/^__USAGE__$/d' $0)" 
    exit $status 
fi 
eval set -- "$OPTSARGS" 
while true 
do 
    case "$1" in 
     -w) diffargs="$diffargs -w"; shift;; 
     --nopager) pager=cat; shift;; 
     --) shift; break ;; ## end of opts, remaining $*, if any, are args 
     -h | --help) 
      printf '%s\n' "$(sed '0,/^__USAGE__$/d' $0)" 
      exit 0;; 
     *) 
      echo "Internal error!" 
      printf '%s\n' "$(sed '0,/^__USAGE__$/d' $0)" 
      exit 1;; 
    esac 
done 

... 

echo "Done" 
exit 0 

__USAGE__ 
myScript [-w] [--nopager] [file [file...] ] 

Some description goes here. 

     -w - Do not compare whitespace 
--nopager - Do not pass the output through 'less' 
Powiązane problemy