Jak mogę wysłać znaki do polecenia tak, jakby pochodziły z pliku?


22

Jak mogę wysłać znaki do polecenia tak, jakby pochodziły z pliku?

Na przykład próbowałem:

wc < "apple pear orange"
-bash: apple pear orange: No such file or directory

Odpowiedzi:



18

Dwa inne podejścia (które umożliwiają wprowadzanie wielu wierszy bez dodatkowego wysiłku):

  1. Użyj „tutaj dokumentu”:

    $ wc << EOF
    jabłko-gruszka pomarańczowa
    EOF
      1 3 18
    $

    EOFCiąg jest separator. Możesz użyć dowolnego ciągu; EOFjest tylko konwencjonalnym wyborem.

  2. Użyj tty jako danych wejściowych:

    $ wc
    jabłko-gruszka pomarańczowa
    Ctrl+D
      1 3 18
    $

    Ma to tę wadę, że program zaczyna działać i zaczyna czytać dane wejściowe, gdy tylko wpiszesz jego nazwę. Może to być niepokojące; na przykład:

    $ grep v
    Szybki brązowy lis              (na maszynie) 
    przeskakuje                       (na maszynie) 
    przeskakuje                       (To jest wyjście z grep!) 
    Leniwy pies.                   (wpisany)
    Ctrl + D
                                    (tutaj brak wyników) 
    $

Dla przypomnienia : <<<Formularz umożliwia także wprowadzanie wielu wierszy bez dodatkowego wysiłku, ponieważ "zamknięty łańcuch może zawierać znaki nowej linii. Oczywiście << EOFformularz (oryginalna składnia tutaj-doc) jest łatwiejszy do odczytania, jeśli masz wejście wieloliniowe.
Alexis

Strona man mówi, że tutaj składnia ciągów znaków <<< word- oczywiście w kontekście powłoki, a wordmoże być ciągiem cytowanym, zawierającym spacje i znaki nowej linii! Nie! Jest to tak oczywiste, że jest oczywiste (i w rzeczywistości nie widzę o tym w ogóle na stronie podręcznika). :-( Dziękujemy za zwrócenie mi uwagi!
G-Man mówi „Przywróć Monikę”

Naprawdę nie nazwałbym tego prostym ani oczywistym. A wordjest zdefiniowane na stronie podręcznika jako „Sekwencja znaków uważanych przez powłokę za pojedynczą jednostkę” (aka „token”), i musisz wiedzieć, że cytowane ciągi znaków są traktowane jako „pojedyncza jednostka” w odpowiednim znaczeniu (po przetwarzanie odwrotnego ukośnika, zmienna ekspansja itp. „Ale to jest właśnie ten cel podwójnego cytowania w powłoce. (Pojedyncze cudzysłowy chronią także przed ekspansją). Model przetwarzania powłoki jest bardzo dobrze przemyślany i wcale nie prosty.
Alexis

@alexis: Kiedy przechodzę w ten sposób do góry i dołączam emotikon, należy wziąć pod uwagę możliwość, że jestem ironiczny.
G-Man mówi „Przywróć Monikę”

10

Chociaż istnieje tutaj kilka poprawnych rozwiązań, inną składnią, która może być czasem przydatna, jest uruchomienie polecenia <(). Umożliwiłoby to utworzenie więcej niż 1 obiektu deskryptora pliku w wierszu polecenia.

Może to być przydatne, gdy robisz coś takiego jak porównywanie długich ciągów tekstu lub jeśli chcesz różnicować zawartość, której nie ma w pliku.

Na przykład porównanie plików hosts na dwóch węzłach bez konieczności kopiowania pliku hosts na localhost:

diff -Naur <(cat /etc/hosts) <(ssh -q otherhost 'cat /etc/hosts')

<Przekierowuje plik do standardowego wejścia i ()tworzyć podpowłoce uruchomić polecenie między nawiasach. Jest to STDOUT z podpowłoki, która jest przekazywana do STDIN uruchamianego polecenia.

To łatwiejszy sposób na utworzenie więcej niż 1 wejściowego „pliku” do polecenia niż próba użycia wielu tutaj dokumentów lub próba powtórzenia wielu poleceń w potoku do ostatecznego polecenia.


<fileorpathnameprzekierowuje standardowe wejście, ale <(subcmd)nie; zastępuje nazwę, która gdy / jeśli zostanie otwarta przez program, może odczytać standardowe wyjście z subcmd. < <(subcmd)(wymagane miejsce) przekierowuje standardowe wejście z tego pliku, prawie jaksubcmd | . Możesz diffodczytać jeden z jego danych wejściowych ze standardowego wejścia, podając argument, -ale nie oba.
dave_thompson_085

Jest to podstawianie procesów, które nie jest obsługiwane, w przeciwieństwie do części, które, jak twierdzisz, zostały wykonane (ale nie jest tak, jak wyjaśnił Dave).
phk

1
Mój diff działa dobrze w bash na systemach Ubuntu 16.04 i Solaris 11.2, z którymi muszę testować. Możliwe, że może nie działać dla wszystkich powłok we wszystkich systemach operacyjnych. W rzeczywistości tworzy deskryptory plików, których można użyć do odczytania danych wyjściowych z podprocesu tak, jakby czytał plik. Ponieważ diff pobiera dwa argumenty pliku, jest w stanie odczytać dane wyjściowe obu podprocesów poprzez utworzone deskryptory plików i porównać je.
Tim Kennedy,

Możesz dodać do swojej odpowiedzi różnicę między cmd <(cmd2 ...) i cmd < <(cmd2 ...). Pierwszy pozwala na wykorzystanie danych pochodnych (danych wyjściowych cmd2) zamiast nazwy pliku. Ten ostatni jest równoważny cmd2 ... | cmd. Polecenia muszą być napisane, aby jawnie akceptować wejście standardowego wejścia, a wiele z nich nie. Dotyczy to zwłaszcza skryptów powłoki.
DocSalvager

8

możesz użyć fajki

echo "apple pear orange" | wc

8
Potok nie jest tym samym, co „odczyt z pliku”. Na przykład nie możesz wyszukiwać wstecz w potoku, podczas gdy możesz w pliku.
rbialon

0

Możesz użyć czegoś podobnego, aby się spodziewać. Poniżej znajduje się prosty przykład otwarcia zdalnej sesji telnet, oczekiwania na monit, wysłania danych, oczekiwania na odpowiedź, uśpienia i wyjścia.

#!/usr/bin/expect
spawn telnet localhost 8555
expect "Escape character is '^]'."
send "Hello World\n"
expect "Connection closed by foreign host."
sleep 1
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.