2016-04-20 38 views

risposta

12

clojure.java.shell/sh esegue un comando (il primo argomento passato alla funzione sh) con argomenti specificati (il resto dei parametri passati a sh).

quando si esegue:

(sh "ls" "-a" "| grep" "Doc")

vi chiedo di eseguire ls con i parametri -a, | grep e Doc.

Quando si digita ls -a | grep Doc nel vostro terminale allora la shell interpreta come l'esecuzione di ls, prendendo il suo std fuori e passarla come std a un altro processo (grep) che dovrebbe essere avviato dalla shell.

Si può simulare quanto il guscio sta facendo avviando ls come un unico processo, prendere la sua uscita std e quindi eseguire grep passando uscita dal ls come input.

La soluzione più semplice sarebbe quella di chiedere solo un processo shell di eseguire tutto come se sia stata scritta nel terminale:

(sh "bash" "-c" "ls -a | grep Doc")

E 'importante passare -c e ls ... come argomenti separati in modo bash li manifestino come un parametro separato. È inoltre necessario disporre dell'intero comando che si desidera eseguire come una stringa (ls -a | grep Doc). Altrimenti solo il primo argomento dopo -c verrà trattato come un comando. Ad esempio, questo non farà ciò che si desidera:

(sh "bash" "-c" "ls -a" "|" "grep Doc")

+0

Questa è una risposta molto ben spiegato-, grazie! Ora, solo per pura conoscenza, c'è un modo per farlo inviando effettivamente l'output di '(": out (sh "ls" "-a")) 'a un altro' (sh "grep" "Doc") '? – shakedzy

+0

È possibile utilizzare l'opzione ': in' di' sh' per passare il valore di ': out' da un processo precedente, tuttavia, utilizzandolo, si perde la caratteristica dello streaming di dati da un processo a un altro - si bufferizzerà tutto uscita da un processo e quando termina passerai tutto il suo contenuto a un altro, Shell usa pipeline dove i dati sono trasmessi da un processo all'altro senza bisogno di bufferizzare tutto.Potresti usare 'java.lang.Runtime.exec()' e 'java.lang.Process.getOutputStream' per ottenere i dati di output dal primo processo e passarli al successivo, ma Clojure' sh' non lo supporta –

+1

Puoi anche dare un'occhiata a https: // github .com/Raynes/conch. Supporta pipeline: https://github.com/Raynes/conch#piping –