At a very early stage of learning the language, and working through the ElixirSips series of videos. I keep hitting stuff that's been slightly obseleted by language changes. Trying to wrap my head around this, and Google/Github issue trackers/SO trawling is getting me nowhere useful. I have this very basic module, which should just run a shell command:
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
However, when this file is compiled and the tests run, I get an argument error; fair enough - System.cmd/1 seems to no longer be part of the standard lib.
System.cmd/3 is in the standard lib, and reading the docs indicated the options are, well, optional. So I pass empty args note |> command |> System.cmd([])
, and what I get back is erlang: :enoent
: again after reading the docs a bit more carefully, fair enough.
So I try to use Erlang's :os.cmd/1
, so note |> command |> :os.cmd
, and I get (FunctionClauseError) no function clause matching in :os.validate/1
. And I am now stuck.
The shell parses the command line and finds the program to execute. It passes any options and arguments to the program as part of a new process for the command such as ps above. While the process is running ps above the shell waits for the process to complete.
A shell is a computer program that presents a command line interface which allows you to control your computer using commands entered with a keyboard instead of controlling graphical user interfaces (GUIs) with a mouse/keyboard/touchscreen combination.
In RStudio, commands can be executed from shell scripts by pressing Ctrl + Enter .
System.cmd/3
seems to accept the arguments to the command as a list and is not happy when you try to sneak in arguments in the command name. For example System.cmd("ls", ["-al"])
works, while System.cmd("ls -al", [])
does not. So in your case you'll probably need something like:
System.cmd("play", ["-qn", "synth", "2", "pluck", note])
What in fact happens underneath is System.cmd/3
calls :os.find_executable/1
with its first argument, which works just fine for something like ls
but returns false for ls -al
.
If you decide to go the pure erlang route, then the call expects a char list instead of a binary, so you need something like the following:
"ls -al" |> String.to_char_list |> :os.cmd
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With