Często chcę podawać stosunkowo krótkie dane łańcuchowe (choć może to być kilka wierszy) do programów wiersza poleceń, które przyjmują tylko dane wejściowe z plików (np. Wdiff) w powtarzający się sposób. Jasne, że mogę utworzyć jeden lub więcej plików tymczasowych, zapisać tam ciąg i uruchomić polecenie z nazwą pliku jako parametrem. Ale wydaje mi się, że ta procedura byłaby wysoce nieefektywna, jeśli dane są faktycznie zapisywane na dysk, a także może uszkodzić dysk bardziej niż to konieczne, jeśli powtórzę tę procedurę wiele razy, np. Jeśli chcę podać pojedyncze wiersze długiego tekstu pliki do wdiff. Czy istnieje zalecany sposób na obejście tego, na przykład za pomocą pseudoplików, takich jak potoki, do tymczasowego przechowywania danych bez faktycznego zapisywania ich na dysku (lub zapisywania tylko wtedy, gdy przekracza on długość krytyczną). Zauważ, że wdiff bierze dwa argumenty i,wdiff <"text"
.
98
xargs
?xargs
, wprowadziłbym wiersze wejściowe z argumentów ciągu pliku dla polecenia. Ale potrzebuję czegoś przeciwnego.echo $data_are_here | dumb_program
?Odpowiedzi:
Użyj nazwanego potoku . Tytułem ilustracji:
-e
Mówi echo poprawnie zinterpretować ucieczkę nowej linii (\n
). Spowoduje to zablokowanie, tzn. Twoja powłoka zawiesi się, dopóki coś nie odczyta danych z potoku.Otwórz kolejną powłokę gdzieś w tym samym katalogu:
Przeczytasz echo, które uwolni drugą powłokę. Chociaż potok istnieje jako węzeł pliku na dysku, dane, które przez niego przechodzą, nie istnieją; wszystko odbywa się w pamięci. Możesz włączyć
&
echo w tle ( ).Potok ma bufor 64k (na Linuksie) i, podobnie jak gniazdo, zablokuje pisarz po zapełnieniu, więc nie stracisz danych, dopóki nie zabijesz przedwcześnie pisarza.
źródło
/tmp
jest skonfigurowany w większości dystrybucji, aby używaćtmpfs
systemu plików, który jest w pamięci RAM. Kiedy piszesz w/tmp
nim plik , przechodzi on bezpośrednio do pamięci RAM, co stanowi dobrą odpowiedź na pliki półelastyczne, do których trzeba szybko uzyskać dostęp i wielokrotnie przepisywać.W Bash możesz użyć
command1 <( command0 )
składni przekierowania, która przekierowuje standardowecommand0
wyjście i przekazuje je do pliku,command1
który przyjmuje nazwę pliku jako argument wiersza poleceń. Nazywa się to substytucją procesu .Niektóre programy, które pobierają argumenty wiersza polecenia z nazwą pliku, tak naprawdę potrzebują prawdziwego pliku o swobodnym dostępie, więc ta technika nie będzie działać dla tych. Działa to jednak dobrze z
wdiff
:W tle tworzy to FIFO,
<( )
przekazuje polecenie do FIFO i przekazuje deskryptor pliku FIFO jako argument. Aby zobaczyć, co się dzieje, spróbuj użyć goecho
do wypisania argumentu, nie robiąc nic z tym:Tworzenie nazwanego potoku jest bardziej elastyczne (jeśli chcesz napisać skomplikowaną logikę przekierowań przy użyciu wielu procesów), ale dla wielu celów to wystarczy i jest oczywiście łatwiejsze w użyciu.
Istnieje również
>( )
składnia, kiedy chcesz użyć go jako danych wyjściowych, npZobacz także ściągawki przekierowań Bash dla powiązanych technik.
źródło
ssh -F <(vagrant ssh-config) default
byłoby naprawdę miło, ale niestety.wdiff jest szczególnym przypadkiem, ponieważ wymaga 2 argumentów nazwy pliku, ale dla wszystkich poleceń, które wymagają tylko 1 argumentu i które uparcie nie przyjmują niczego oprócz argumentu nazwy pliku, istnieją 2 opcje:
Nazwa pliku „-” (czyli znak minus) działa przez około 1/2 czasu. Wygląda na to, że zależy od danego polecenia i tego, czy twórca polecenia przechwytuje tę sprawę i obsługuje ją zgodnie z oczekiwaniami. na przykład
Istnieje plik psuedo o nazwie / dev / stdin, który istnieje w systemie Linux i można go użyć, jeśli nazwa pliku jest absolutnie wymagana przez polecenie. Jest to bardziej prawdopodobne, że zadziała, ponieważ nie wymaga specjalnej obsługi nazw plików z polecenia. Jeśli fifo działa lub działa metoda podstawiania procesu bash , to powinno to również działać i nie jest specyficzne dla powłoki. na przykład
źródło