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.
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”.
-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
:
vimdiff <(./a) <(./b)
Coś takiego:
vimdiff
tworzy piękne, inteligentne i interaktywne widoki porównujące różnice. Wydaje się, że jest dostarczany z vim
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) :
mkfifo a_fifo b_fifo
./a > a_fifo &
./b > b_fifo &
diff a_fifo b_fifo
... ale rozwiązanie Johna Kugelmana jest znacznie czystsze.
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ąć:
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.
Dodanie trochę więcej do już dobrych odpowiedzi (pomogło mi!):
Polecenie docker
wyświetla pomoc do STD_ERR
(tj. Deskryptor pliku 2)
Chciałem zobaczyć, czy docker attach
i docker 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.
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ć bcomp
powyższego (zamiast bcompare
), ponieważ bcomp
uruchamia 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ń.
Przeczytaj więcej tutaj: http://zsh.sourceforge.net/Intro/intro_7.html
Zwróć również uwagę na to:
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.