Dzisiaj uczę się czegoś o fifo w tym artykule: Wprowadzenie do nazwanych potoków , o którym wspomniano cat <(ls -l)
.
Zrobiłem kilka eksperymentów, używając sort < (ls -l)
, który wyskakuje błąd:
-bash: syntax error near unexpected token `('`
Potem odkryłem, że źle wprowadziłem dodatkowe miejsce w poleceniu.
Ale dlaczego to dodatkowe polecenie doprowadzi do niepowodzenia? Dlaczego symbol przekierowania musi być zbliżony do (
?
Odpowiedzi:
Ponieważ to nie jest
<
, to jest coś<()
zupełnie innego. Nazywa się to substytucją procesu , jest to funkcja niektórych powłok, która pozwala wykorzystać dane wyjściowe jednego procesu jako dane wejściowe dla innego.>
I<
operatorzy przekierować wyjście do i wejście z plikami .<()
Operator zajmuje polecenia (procesów), a nie pliki. Kiedy biegnieszPróbujesz uruchomić polecenie
ls
w podpowłoce (co oznaczają nawiasy), a następnie przekazać tę podpowłokę jako plik wejściowysort
. Nie jest to jednak akceptowana składnia i pojawia się wyświetlony błąd.źródło
then sort is attempting to read the subshell as its input file
→ jest to oczywiście błędna, ponieważ Bash nawet nie przeanalizuje składni. Anils
niesort
jest uruchomiony.< (ls)
nie jest tutaj poprawnym tokenem.(ls)
że działałobyls
w podpowłoce.Ponieważ tak ma być.
<(...)
inbash
to składnia podstawiania procesów. Jest skopiowany od tego samego operatora wksh
.<
,(
,)
,|
,&
,;
Są specjalne tokeny leksykalne wbash
które są stosowane do tworzenia specjalnych operatorów w różnych kombinacjach.<
,<(
,<<
,<&
... każdy ma swoją rolę.<
służy do przekierowania.<file
,< file
przekieruje dane wejściowe z pliku.<'(file)'
przekieruje dane wejściowe z pliku o nazwie(file)
, ale<(file)
jest innym operatorem, który nie jest operatorem przekierowania.< (file)
będzie<
następnie(file)
. W tym kontekście, wbash
,(file)
nie jest ważny.(...)
może być poprawny jako pojedynczy token w niektórych kontekstach, takich jak:Ale nie w
W
fish
powłoce jest inaczej. Wfish
,(...)
jest podstawienie poleceń (równowartość$(...)
wbash
). I<
służy do przekierowywania danych wejściowych jak w powłokach podobnych do Bourne'a.Więc w
fish
:byłby taki sam jak:
To jest:
Ale to coś zupełnie innego niż
bash
podstawianie procesów.W
yash
powłoce kolejna powłoka POSIX<(...)
nie służy do zastępowania procesów, ale do przekierowywania procesówTam,
Skrót od:
jest operatorem przekierowania. Jest to mniej więcej odpowiednik:
Podczas
bash
gdy<(ls -l)
jest rozwinięty do ścieżki potoku, więc bardziej przypomina:W
zsh
,(...)
jest przeciążony jako operator globowania ((*.txt|*.png)
rozwinie siętxt
ipng
pliki) i jako kwalifikator glob (*(/)
na przykład rozszerza się do plików, katalogów).W
zsh
: w:To
(ls -l)
byłoby traktowane jako kwalifikator globalny.l
Glob kwalifikator jest dopasowanie na liczbie linków i oczekuje wiele pol
(jakls -ld ./*(l2)
by wyświetlić listę plików z 2 linków), więc to dlaczego maszzsh: number expected
błąd istnieje.sort < (w)
dałbyzsh: no matches found: (w)
błąd zamiast jako(w)
meczów pliki z pustą nazwą, które są zapisu.sort < (w|cat)
posortowałby zawartość plikóww
i / lubcat
plików w bieżącym katalogu ...źródło
sort < $(ls -l)
podaje ten błąd:bash: $(ls -l): ambiguous redirect
$(ls -l)
rozwija się do więcej niż jednego słowa. Użyj cudzysłowów, aby zapobiec split + glob (sort < "$(echo file)"
). Zauważ, że zachowanie lubbash
różniące się od POSIX sh w tym bashu robi to split + glob również tam, gdy nie jest interaktywny (nie kiedy jest wywoływany tak,sh
jakby).ls -l | sort /dev/fd/0
mogę powiedzieć, że dane wyjściowels -l
są przechowywane/dev/fd/0
isort
polecenie odczytuje je, aby uzyskać pożądany wynik. Używamtail -f --retry /dev/fd/0
do monitorowania tego pliku, ale nie otrzymuję żadnych danych wyjściowych. czemu? jak mogę odczytać ten plik?(foo | psub)
do osiągnięcia substytucji procesu wejściowego; nie ma jeszcze substytutu (ha) dla substytucji procesu wyjściowego.