2014-12-29 11 views
15

In einem sehr frühen Stadium des Erlernens der Sprache und Arbeiten durch die ElixirSips-Serie von Videos. Ich treffe immer wieder Sachen, die durch Sprachänderungen leicht obsletiert wurden. Der Versuch, meinen Kopf darum zu wickeln, und Google/Github Problem Tracker/SO Trawling bringt mich nirgends nützlich. Ich habe diese sehr Basismodul, das nur einen Shell-Befehl ausgeführt werden soll:Ausführen eines grundlegenden Shell-Befehls in Elixir

defmodule QuickieSynth.Sound do 
    def command(note) do 
    "play -qn synth 2 pluck #{note}" 
    end 

    def play(note) do 
    note |> command |> System.cmd 
    end 
end 

Wenn jedoch diese Datei kompiliert und die Tests ausgeführt, erhalte ich ein Argument Fehler; Fair genug - System.cmd/1 scheint nicht mehr Teil der Standardbibliothek zu sein.

System.cmd/3 ist in der Standardbibliothek, und das Lesen der Dokumente angegeben, die Optionen sind, nun, optional. Also gebe ich leere Argumente note |> command |> System.cmd([]), und was ich zurückbekomme, ist erlang: :enoent: wieder nach dem Lesen der Dokumente ein wenig sorgfältiger, fair genug.

Also versuche ich Erlang :os.cmd/1 zu verwenden, also note |> command |> :os.cmd, und ich bekomme (FunctionClauseError) no function clause matching in :os.validate/1. Und ich bin jetzt festgefahren.

+2

ich eine andere Funktion schreiben auf neueren Versionen von Elixier, das Tutorial Arbeit zu machen: 'def laufen (full_cmd) do [cmd | args] = String.split (full_cmd, "") System.cmd (cmd, args) Ende' – ghayes

Antwort

29

System.cmd/3 scheint die Argumente für den Befehl als Liste zu akzeptieren und ist nicht glücklich, wenn Sie versuchen, Argumente in den Befehlsnamen einzuschleichen. Zum Beispiel funktioniert System.cmd("ls", ["-al"]) funktioniert, während System.cmd("ls -al", []) nicht funktioniert. Also in Ihrem Fall müssen Sie wahrscheinlich so etwas wie:

System.cmd("play", ["-qn", "synth", "2", "pluck", note]) 

in der Tat, was darunter passiert ist System.cmd/3 Anrufe :os.find_executable/1 mit seinem ersten Argumente, das für so etwas wie ls ganz gut funktioniert, aber wieder falsch für ls -al zum Beispiel.

Der erlang Anruf erwartet eine char Liste anstelle eines binären, so müssen Sie etwas wie folgt aus:

"ls -al" |> String.to_char_list |> :os.cmd 
+1

Ah, das macht Sinn. Ich werde sowieso Optionen einbauen wollen, also war es nur dieser erste Grundschritt, der mich aus der Fassung brachte; Ich kann es nicht so verkabeln, wie ich es versucht habe. BTW, irgendeine Idee, warum der Erlang Anruf nicht funktioniert (: os.cmd)? – DanCouper

+1

Hinzugefügt, dass die Antwort –

+1

Vielen Dank, das ist großartig. – DanCouper

Verwandte Themen