Jak napisać skrypt akceptujący dane wejściowe z argumentu nazwy pliku lub ze standardowego wejścia?
na przykład możesz użyć w less
ten sposób. można wykonać less filename
i równoważnie cat filename | less
.
czy istnieje prosty sposób „po wyjęciu z pudełka”? czy muszę ponownie wynaleźć koło i napisać trochę logiki w skrypcie?
command-line
bash
stdin
Gilad Hoch
źródło
źródło
Odpowiedzi:
Jeśli argument pliku jest pierwszym argumentem skryptu, sprawdź, czy istnieje argument (
$1
) i czy jest to plik. W przeciwnym razie przeczytaj dane wejściowe ze standardowego wejścia -Więc twój skrypt może zawierać coś takiego:
np. wtedy możesz wywołać skrypt jak
lub
Edytuj Niektóre wyjaśnienia skryptu:
[ $# -ge 1 -a -f "$1" ]
- Jeśli co najmniej jeden argument wiersza poleceń ($# -ge 1
) ORAZ (operator -a) pierwszym argumentem jest plik (-f sprawdza, czy „$ 1” jest plikiem), wynik testu jest prawdziwy.&&
jest logicznym operatorem AND AND powłoki. Jeśli test jest prawdziwy, to przypiszinput="$1"
icat $input
wyśle plik.||
jest logicznym operatorem OR powłoki. Jeśli test jest fałszywy, następujące polecenia||
są analizowane. wejście jest przypisane do „-”. Poleceniecat -
czyta z klawiatury.Podsumowując, jeśli podano argument skryptu i jest to plik, wówczas do nazwy pliku przypisywane jest zmienne wejście. Jeśli nie ma poprawnego argumentu, cat czyta z klawiatury.
źródło
&& input="$1" || input="-"
i dlaczego znajduje się pozatest
operatorem?$@
)?read
odczytuje ze standardowego wejścia. Przekierowanie go z file (./script <someinput
) lub przez pipe (dosomething | ./script
) nie sprawi, że będzie działać inaczej.Wszystko, co musisz zrobić, to przejść przez wszystkie linie wejściowe (i nie różni się to od iteracji po liniach w pliku).
(przykładowy kod, przetwarza tylko jedną linię)
Powtórzy echo pierwszego wiersza standardowego wejścia (przez
<
lub|
).źródło
Nie wspominasz o tym, jakiej powłoki zamierzasz użyć, więc przyjmuję bash, choć są to dość standardowe rzeczy w różnych powłokach.
Plik argumentów
Dostęp do argumentów można uzyskać za pomocą zmiennych
$1
-$n
($0
zwraca polecenie użyte do uruchomienia programu). Powiedzmy, że mam skrypt, którycat
wyrzuca n liczby plików z separatorem między nimi:W tym przypadku przekazujemy nazwę pliku do cat. Jeśli jednak chcesz przekształcić dane w pliku (bez wyraźnego zapisywania i przepisywania), możesz również zapisać zawartość pliku w zmiennej:
Czytaj ze standardowego
Jeśli chodzi o czytanie ze standardowego wejścia, większość powłok ma dość standardowe
read
wbudowanie, chociaż istnieją różnice w sposobie określania podpowiedzi (przynajmniej).Strona podręcznika wbudowanego Bash ma dość zwięzłe wyjaśnienie
read
, ale ja wolę stronę hakerów Bash .Po prostu:
Wiele zmiennych
Aby ustawić wiele zmiennych, wystarczy podać wiele nazw parametrów, aby
read
:read
umieści następnie jedno słowo ze stdin w każdej zmiennej, zrzucając wszystkie pozostałe słowa do ostatniej zmiennej.Jeśli wprowadzonych zostanie mniej słów niż zmiennych, pozostałe zmienne pozostaną puste (nawet jeśli zostały wcześniej ustawione):
Monity
-p
Często używam flagi do pytania:Uwaga: ZSH i KSH (i być może inne) używają innej składni monitów:
Wartości domyślne
To naprawdę nie jest
read
sztuczka, ale używam jej często w połączeniu zread
. Na przykład:Zasadniczo, jeśli zmienna (odpowiedź) istnieje, zwróć się, ale jeśli jest pusta, zwróć następujący parametr („N”).
źródło
Najprostszym sposobem jest samodzielne przekierowanie standardowego wejścia:
Lub jeśli wolisz bardziej zwięzłą formę:
Teraz reszta skryptu może po prostu czytać ze standardowego wejścia. Oczywiście możesz zrobić podobnie z bardziej zaawansowanym parsowaniem opcji zamiast na stałe wpisywać pozycję nazwy pliku jako
"$1"
.źródło
exec
spróbuje wykonać argument jako polecenie, które nie jest tym, czego chcemy tutaj.if [ "$1" ] ; then exec < "$1" ; fi
w skrypcie testowym i wyświetla komunikat o błędzie, ponieważ polecenie jest nieznane. To samo z postacią zwięzłą.użyj (lub odetnij) czegoś, co już zachowuje się w ten sposób, i użyj
"$@"
powiedzmy, że chcę napisać narzędzie, które zastąpi ciągi spacji w tekście tabulatorami
tr
jest najbardziej oczywistym sposobem na zrobienie tego, ale akceptuje tylko standardowe wejście, więc musimy odłączyć odcat
:na przykład, gdy używane narzędzie zachowuje się już w ten sposób, moglibyśmy
sed
zamiast tego zaimplementować :źródło
Możesz także:
Więcej ciekawych sztuczek podstawiania parametrów w Bash, zobacz to .
źródło
uglifyjs < /dev/stdin
i działa wspaniale!Możesz także zachować prostotę i użyć tego kodu
Kiedy tworzysz plik skryptu pass_it_on.sh z tym kodem,
Możesz biegać
a cała zawartość standardowego ekranu zostanie po prostu wyrzucona na ekran.
Alternatywnie użyj tego kodu, aby zachować kopię standardowego pliku w pliku, a następnie wyrzucić ją na ekran.
a oto inny przykład, może bardziej czytelny, wyjaśniony tutaj:
http://mockingeye.com/blog/2013/01/22/reading-everything-stdin-in-a-bash-script/
Baw się dobrze.
RaamEE
źródło
Najprostszym sposobem i zgodnym z POSIX jest:
co jest równoważne z
${1:--}
.Następnie przeczytaj plik jak zwykle:
źródło