Come posso inviare caratteri a un comando come se provenissero da un file?
Ad esempio ho provato:
wc < "apple pear orange"
-bash: apple pear orange: No such file or directory
Come posso inviare caratteri a un comando come se provenissero da un file?
Ad esempio ho provato:
wc < "apple pear orange"
-bash: apple pear orange: No such file or directory
Risposte:
Nelle shell che supportano qui stringhe , incluso bash
, zsh
e ksh93
, puoi usare
wc <<< "apple pear orange"
Altri due approcci (che consentono input su più righe senza sforzo aggiuntivo):
Usa un "documento qui":
$ wc << EOF mela pera arancia EOF 1 3 18 $
La EOF
stringa è un delimitatore. Puoi usare qualsiasi stringa; EOF
è solo una scelta convenzionale.
Usa tty come input:
$ wc mela pera arancia Ctrl+D 1 3 18 $
Questo ha lo svantaggio che il programma inizia a funzionare e inizia a leggere l'input, non appena si digita il suo nome. Questo può essere sconcertante; per esempio:
$ grep v La rapida volpe marrone (dattiloscritta) salta (dattiloscritta) salta sopra (Questo è prodotto da grep!) Il cane pigro. (digitato) Ctrl + D (Nessun output qui) $
<<<
modulo consente anche l'inserimento di più righe senza ulteriore sforzo, poiché la "
stringa racchiusa può contenere nuove righe. Naturalmente il << EOF
modulo (la sintassi here-doc originale) è più facile da leggere se si dispone di input multilinea.
<<<
word
- ovviamente, nel contesto della shell, a word
può essere una stringa tra virgolette, contenente spazi e newline! D'oh! È così ovvio che è ovvio (e, in effetti, non lo vedo menzionato nella pagina man). :-( Grazie per avermelo fatto notare!
word
è definito nella manpage come "Una sequenza di caratteri considerata come una singola unità dalla shell" (aka "token"), e devi sapere che le stringhe tra virgolette sono trattate come "una singola unità" nel senso rilevante (dopo elaborazione di barre rovesciate, espansione variabile ecc. "Ma in effetti questo è l'intero scopo della doppia virgoletta nella shell. (Le virgolette singole proteggono anche dall'espansione.) Il modello di elaborazione della shell è molto ben pensato e tutt'altro che semplice.
Sebbene ci siano diverse soluzioni valide qui, un'altra sintassi che può essere utile a volte è quella di eseguire un comando <()
. Ciò consentirebbe di creare più di 1 oggetto descrittore di file su una riga di comando.
Questo può essere utile quando stai facendo qualcosa come confrontare lunghe stringhe di testo, o se vuoi diff un po 'di contenuto che non è in un file.
Ad esempio, confrontando i file hosts su due nodi senza dover copiare il file hosts su localhost:
diff -Naur <(cat /etc/hosts) <(ssh -q otherhost 'cat /etc/hosts')
Il <
reindirizza un file per STDIN, e il ()
creare una subshell per eseguire il comando tra parentesi. È lo STDOUT della subshell che viene passato a STDIN del comando in esecuzione.
È un modo più semplice per creare più di 1 "file" di input in un comando piuttosto che provare a utilizzare più documenti qui o provare a inviare più comandi a una pipeline al comando finale.
<fileorpathname
reindirizza stdin, ma <(subcmd)
non lo fa; sostituisce un nome che quando / se aperto dal programma può leggere stdout da subcmd. < <(subcmd)
(spazio richiesto) reindirizza lo stdin da quel file, quasi come subcmd |
. Potresti diff
leggere uno dei suoi input da stdin specificando un argomento di -
ma non entrambi.
cmd <(cmd2 ...)
e cmd < <(cmd2 ...)
. Il primo consente di utilizzare i dati derivati (output di cmd2) al posto di un nome file. Quest'ultimo è equivalente a cmd2 ... | cmd
. I comandi devono essere scritti per accettare esplicitamente l'input stdin e molti non lo sono. Ciò è particolarmente vero per gli script di shell.
Potresti voler usare qualcosa di simile ad aspettarti. Di seguito è riportato un semplice esempio di apertura di una sessione telnet remota, in attesa del prompt, invio di alcuni dati, attesa di una risposta, sospensione e chiusura.
#!/usr/bin/expect
spawn telnet localhost 8555
expect "Escape character is '^]'."
send "Hello World\n"
expect "Connection closed by foreign host."
sleep 1