Niektóre powłoki bash
obsługują proces podstawiania, który jest sposobem prezentacji wyników procesu w postaci pliku:
$ diff <(sort file1) <(sort file2)
Jednak ten konstrukt nie jest POSIX i dlatego nie jest przenośny. Jak można zastąpić proces w sposób przyjazny dla POSIX (tj. Taki, który działa /bin/sh
) ?
uwaga: pytanie nie pyta, jak odróżnić dwa posortowane pliki - to tylko wymyślony przykład pokazujący podstawienie procesu !
shell
pipe
posix
process-substitution
rozgwiazdy
źródło
źródło
/bin/sh
bycia powłoką POSIX, wystarczy, że zostanie wywołane polecenie,sh
które w odpowiednim środowisku jest zgodne z POSIX. Na przykład/bin/sh
w systemie Solaris 10 nie jest powłoką POSIX, jest to starożytna powłoka Bourne'a, w której znajduje się powłoka POSIX/usr/xpg4/bin/sh
.Odpowiedzi:
Ta funkcja została wprowadzona przez
ksh
(po raz pierwszy udokumentowana w ksh86) i korzystała z tej/dev/fd/n
funkcji (dodana niezależnie w niektórych systemach BSD i AT&T wcześniej). Wksh
wersjach ksh93u i nowszych nie działałoby, gdyby Twój system nie obsługiwał / dev / fd / n. Zsh, bash iksh93u+
wyżej mogą korzystać z tymczasowych nazwanych potoków (uważam nazwane potoki dodane w SysIII), gdzie / dev / fd / n nie są dostępne.W systemach, w których jest dostępny (POSIX ich nie określa), możesz samodzielnie dokonać procesu podstawienia ( ):
/dev/fd/n
diff <(cmd1) <(cmd2)
Jednak to nie działa
ksh93
w systemie Linux, ponieważ potoki powłoki są implementowane za pomocą par/dev/fd/3
gniazd zamiast potoków i otwierania, w którym fd 3 wskazuje gniazdo nie działa w systemie Linux.Chociaż POSIX nie określa . Określa nazwane potoki. Nazwane potoki działają jak normalne potoki, z wyjątkiem tego, że można uzyskać do nich dostęp z systemu plików. Problem polega na tym, że musisz utworzyć pliki tymczasowe i wyczyścić je później, co jest trudne do wykonania w sposób niezawodny, szczególnie biorąc pod uwagę, że POSIX nie ma standardowego mechanizmu (takiego jak w niektórych systemach) do tworzenia plików tymczasowych lub katalogów i przenoszenia sygnałów w sposób przenośny (sprzątanie po rozłączeniu lub zabiciu) jest również trudne do przeniesienia.
/dev/fd/n
mktemp -d
Możesz zrobić coś takiego:
(nie zajmując się tutaj obsługą sygnałów).
źródło
/dev/fd/n
przykładu. Dlaczego deskryptor 4 jest zamykany dwukrotnie? (I tak jest z deskryptorem 3.) Zgubiłem się.cmd2
(dup2(0,4)
na zewnętrznym{...}
, przywróconymdup2(4,0)
do wewnątrz{...}
).mktemp -d
pomóc w uzyskaniu FIFO, ponieważ nikt nie powinien pisać w twoim nowym losowym katalogu tymczasowym.mktemp -d
. Ale to nie jest standardowe polecenie / POSIX.W razie potrzeby, aby uniknąć utraty zmiennej użytecznej
cmd | while read A B C
, zamiast:możesz użyć:
Aby odpowiedzieć na pytanie:
źródło