Lahiru
Lahiru

Reputation: 2664

Run shell commands in Elixir

I want to execute a program through my Elixir code. What is the method to call a shell command to a given string? Is there anything which isn't platform specific?

Upvotes: 86

Views: 43693

Answers (7)

opensource
opensource

Reputation: 758

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.

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 for example.

The Erlang call expects a char list instead of a binary, so you need something like the following:

"find /tmp -type f -size -200M |xargs rm -f" |> String.to_char_list |> :os.cmd

Upvotes: 17

user1771713
user1771713

Reputation: 9

One could also use erlang's :os module like so:

iex(3)> :os.cmd('time')
'\nreal\t0m0.001s\nuser\t0m0.000s\nsys\t0m0.000s\n'

Beware that you'll have to handle erlang binaries when processing the result :os.cmd('time') |> to_string() for example

Upvotes: 0

7stud
7stud

Reputation: 48659

If I have the following c program in the file a.c:

#include <stdio.h>
#include <stdlib.h>

int main(int arc, char** argv)
{

    printf("%s\n",argv[1]);
    printf("%s\n",argv[2]);

    int num1 = atoi(argv[1]);
    int num2 = atoi(argv[2]);

    return num1*num2;
}

and compile the program to the file a:

~/c_programs$ gcc a.c -o a

then I can do:

~/c_programs$ ./a 3 5
3
5

I can get the return value of main() like this:

~/c_programs$ echo $?
15

Similarly, in iex I can do this:

iex(2)> {output, status} = System.cmd("./a", ["3", "5"])
{"3\n5\n", 15}

iex(3)> status
15

The second element of the tuple returned by System.cmd() is the return value of the main() function.

Upvotes: -1

Overbryd
Overbryd

Reputation: 5006

Here is how you execute a simple shell command without arguments:

System.cmd("whoami", [])
# => {"lukas\n", 0}

Checkout the documentation about System for more information.

Upvotes: 112

Onorio Catenacci
Onorio Catenacci

Reputation: 15343

I cannot link directly to the relevant documentation but it's here under the System module

cmd(command) (function) # 
Specs:

cmd(char_list) :: char_list
cmd(binary) :: binary
Execute a system command.

Executes command in a command shell of the target OS, captures the standard output of the command and returns the result as a binary.

If command is a char list, a char list is returned. Returns a binary otherwise.

Upvotes: 5

parroty
parroty

Reputation: 1375

The "devinus/sh" library is another interesting approach to run shell commands.

https://github.com/devinus/sh

Upvotes: 9

Jonas
Jonas

Reputation: 129103

You can have a look in the Erlang os Module. E.g. cmd(Command) -> string() should be what you are looking for.

Upvotes: 12

Related Questions