Służy <(command)do przekazywania wyników jednego polecenia do innego programu, tak jakby to była nazwa pliku. Bash przesyła dane wyjściowe programu do potoku i przekazuje nazwę pliku, taką jak /dev/fd/63do polecenia zewnętrznego.
diff <(./a)<(./b)
Podobnie możesz użyć, >(command)jeśli chcesz przesłać coś do polecenia.
Na stronie podręcznika systemowego Bash jest to nazywane „Zastępowaniem procesów”.
Jedną wadą, o której należy pamiętać, jest to, że jeśli ./a lub ./b zawiedzie, dzwoniący nie dowie się o tym.
Alexander Pogrebnyak
5
OP oznaczył bash pytania, ale dla przypomnienia, nie działa to w żadnej innej powłoce. Jest to rozszerzenie bash standardu narzędziowego Posix.
DigitalRoss
5
Próbowałem to rozwiązanie z programem Java i mam ten błąd: -bash: syntax error near unexpected token ('. Spróbowałem ponownie bez nawiasów i otrzymałem -bash: java: No such file or directory. Czy to nie działa, jeśli polecenie ma parametry?
styfle
1
@DigitalRoss - Rozwiązanie można rozszerzyć na inne powłoki za pomocą aliasu. W tcsh następujące brzydota działa: alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\'. (Na przykład: diffcmd "ls" "ls -a").
Paul Lynch
Dla każdego, kto błąka się poza Google, działa to również pod zsh. (Ponadto, jeśli chcesz wprowadzić dane wejściowe do czegoś, co wywołuje fseek, zsh oferuje, =(./a)które mogą być używane identycznie, <(./a)ale używają tymczasowego pliku pod maską, który zsh usunie za ciebie.)
ssokolow Stycznia
26
Dodając do obu odpowiedzi, jeśli chcesz zobaczyć porównanie obok siebie, użyj vimdiff:
Lepiej usuń nazwane potoki po ich użyciu, z rm a_fifo b_fifo.
Franklin Yu,
15
Dla każdego, kto jest ciekawy, w ten sposób wykonujesz podstawianie procesów przy użyciu skorupy ryby :
Grzmotnąć:
diff <(./a)<(./b)
Ryba:
diff (./a | psub)(./b | psub)
Niestety implementacja u ryb jest obecnie niewystarczająca ; fish albo zawiesi się, albo użyje tymczasowego pliku na dysku. Nie możesz również użyć psub do wyjścia z polecenia.
Obecnie nie działa to poprawnie w przypadku ryb. Jeśli wyjście programów jest większe niż jeden BUFSIZ, polecenie zawiesi się. (lub ryba po prostu użyje pliku tymczasowego na dysku)
Evan Benn,
7
Dodanie trochę więcej do już dobrych odpowiedzi (pomogło mi!):
Polecenie dockerwyświetla pomoc do STD_ERR(tj. Deskryptor pliku 2)
Chciałem zobaczyć, czy docker attachi docker attach --helpdała taki sam efekt
$ docker attach
$ docker attach --help
Po wpisaniu tych dwóch poleceń wykonałem następujące czynności:
$ diff <(!-2 2>&1) <(!! 2>&1)
!! jest tym samym, co! -1, co oznacza uruchomienie polecenia 1 przed tym - ostatnim poleceniem
! -2 oznacza uruchomienie polecenia dwa przed tym
2> & 1 oznacza wysyłanie wyjścia file_descriptor 2 (STD_ERR) do tego samego miejsca, co wyjście file_descriptor 1 (STD_OUT)
W przypadku zsh użycie =(command)automatycznie tworzy plik tymczasowy i zastępuje =(command)ścieżką samego pliku. Przy normalnym zastępowaniu procesu, $(command)jest zastępowane danymi wyjściowymi polecenia.
Ta funkcja zsh jest bardzo przydatna i może być używana w ten sposób do porównania wyników dwóch poleceń za pomocą narzędzia porównywania, na przykład Beyond Compare:
bcomp =(ulimit -Sa| sort)=(ulimit -Ha| sort)
W przypadku Beyond Compare należy pamiętać, że należy użyć bcomppowyższego (zamiast bcompare), ponieważ bcompuruchamia porównanie i czeka na zakończenie. Jeśli używasz bcompare, uruchamia porównanie i natychmiast kończy pracę, dzięki czemu znikają pliki tymczasowe utworzone do przechowywania danych wyjściowych poleceń.
Zauważ, że powłoka tworzy plik tymczasowy i usuwa go po zakończeniu polecenia.
a następujące, które są różnicą między $(...)i =(...):
Jeśli przeczytasz stronę podręcznika zsh, możesz zauważyć, że <(...) jest inną formą podstawiania procesu, która jest podobna do = (...). Jest między nimi ważna różnica. W przypadku <(...) powłoka tworzy nazwany potok (FIFO) zamiast pliku. To jest lepsze, ponieważ nie wypełnia systemu plików; ale to nie działa we wszystkich przypadkach. W rzeczywistości, gdybyśmy w powyższych przykładach zamienili = (...) na <(...), wszystkie z nich przestałyby działać z wyjątkiem fgrep -f <(...). Nie możesz edytować potoku ani otwierać go jako folderu poczty; fgrep nie ma jednak problemu z odczytaniem listy słów z potoku. Możesz się zastanawiać, dlaczego diff <(foo) bar nie działa, ponieważ foo | diff - bar działa; Dzieje się tak, ponieważ diff tworzy plik tymczasowy, jeśli zauważy, że jednym z jego argumentów jest -, a następnie kopiuje swoje standardowe wejście do pliku tymczasowego.
Odpowiedzi:
Służy
<(command)
do przekazywania wyników jednego polecenia do innego programu, tak jakby to była nazwa pliku. Bash przesyła dane wyjściowe programu do potoku i przekazuje nazwę pliku, taką jak/dev/fd/63
do polecenia zewnętrznego.Podobnie możesz użyć,
>(command)
jeśli chcesz przesłać coś do polecenia.Na stronie podręcznika systemowego Bash jest to nazywane „Zastępowaniem procesów”.
źródło
-bash: syntax error near unexpected token ('
. Spróbowałem ponownie bez nawiasów i otrzymałem-bash: java: No such file or directory
. Czy to nie działa, jeśli polecenie ma parametry?alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\'
. (Na przykład: diffcmd "ls" "ls -a").fseek
, zsh oferuje,=(./a)
które mogą być używane identycznie,<(./a)
ale używają tymczasowego pliku pod maską, który zsh usunie za ciebie.)Dodając do obu odpowiedzi, jeśli chcesz zobaczyć porównanie obok siebie, użyj
vimdiff
:Coś takiego:
źródło
vimdiff
tworzy piękne, inteligentne i interaktywne widoki porównujące różnice. Wydaje się, że jest dostarczany zvim
pakietem w większości systemów.vimdiff
pokazuje również nie tylko różniący się wiersz, ale także specyficzny fragment tekstu, który się różni.Jedną z opcji byłoby użycie nazwanych potoków (FIFO) :
... ale rozwiązanie Johna Kugelmana jest znacznie czystsze.
źródło
rm a_fifo b_fifo
.Dla każdego, kto jest ciekawy, w ten sposób wykonujesz podstawianie procesów przy użyciu skorupy ryby :
Grzmotnąć:
Ryba:
Niestety implementacja u ryb jest obecnie niewystarczająca ; fish albo zawiesi się, albo użyje tymczasowego pliku na dysku. Nie możesz również użyć psub do wyjścia z polecenia.
źródło
Dodanie trochę więcej do już dobrych odpowiedzi (pomogło mi!):
Polecenie
docker
wyświetla pomoc doSTD_ERR
(tj. Deskryptor pliku 2)Chciałem zobaczyć, czy
docker attach
idocker attach --help
dała taki sam efekt$ docker attach
$ docker attach --help
Po wpisaniu tych dwóch poleceń wykonałem następujące czynności:
$ diff <(!-2 2>&1) <(!! 2>&1)
!! jest tym samym, co! -1, co oznacza uruchomienie polecenia 1 przed tym - ostatnim poleceniem
! -2 oznacza uruchomienie polecenia dwa przed tym
2> & 1 oznacza wysyłanie wyjścia file_descriptor 2 (STD_ERR) do tego samego miejsca, co wyjście file_descriptor 1 (STD_OUT)
Mam nadzieję, że to się przydało.
źródło
W przypadku zsh użycie
=(command)
automatycznie tworzy plik tymczasowy i zastępuje=(command)
ścieżką samego pliku. Przy normalnym zastępowaniu procesu,$(command)
jest zastępowane danymi wyjściowymi polecenia.Ta funkcja zsh jest bardzo przydatna i może być używana w ten sposób do porównania wyników dwóch poleceń za pomocą narzędzia porównywania, na przykład Beyond Compare:
W przypadku Beyond Compare należy pamiętać, że należy użyć
bcomp
powyższego (zamiastbcompare
), ponieważbcomp
uruchamia porównanie i czeka na zakończenie. Jeśli używaszbcompare
, uruchamia porównanie i natychmiast kończy pracę, dzięki czemu znikają pliki tymczasowe utworzone do przechowywania danych wyjściowych poleceń.Przeczytaj więcej tutaj: http://zsh.sourceforge.net/Intro/intro_7.html
Zwróć również uwagę na to:
a następujące, które są różnicą między
$(...)
i=(...)
:źródło