SoFunction
Updated on 2025-04-08

Two ways to execute linux commands in Erlang

(Cmd)

The Os module provides a cmd function that can execute Linux system shell commands (or windows commands can be executed). Returns the standard output string result of a Cmd command. For example, execute os:cmd("date") in linux system. Returns the time of linux. This is relatively simple, and in general, it also meets most needs.

erlang:open_port(PortName, PortSettings)

When (Cmd) cannot meet your needs, you can use the powerful open_port(PortName, PortSettings) to solve it. The simplest requirement is that I want to execute a linux command and also need to return the exit code. (Cmd) is a little anxious. Don't think that with open_port(PortName, PortSettings) you can completely replace (Cmd). Being strong comes at a price.

%% Advantages: Can return exit status and execution process
%% Disadvantages: It greatly affects performance. When open_port is executed, it will block

When the performance requirements of the system are relatively high, it is not recommended to use erlang:open_port(PortName, PortSettings).

Below is a very useful piece of code that returns exit status and execution results.

Copy the codeThe code is as follows:

my_exec(Command) ->
    Port = open_port({spawn, Command}, [stream, in, eof, hide, exit_status]),
    Result = get_data(Port, []),
    Result.

get_data(Port, Sofar) ->
    receive
    {Port, {data, Bytes}} ->
        get_data(Port, [Sofar|Bytes]);
    {Port, eof} ->
        Port ! {self(), close},
        receive
        {Port, closed} ->
            true
        end,
        receive
        {'EXIT',  Port,  _} ->
            ok
        after 1 ->              % force context switch
            ok
        end,
        ExitCode =
            receive
            {Port, {exit_status, Code}} ->
                Code
        end,
        {ExitCode, lists:flatten(Sofar)}
    end.