Why can't I execute some commands from Process?

Viewed 1014

In python, I can execute a shell script/command by doing this.

import os

os.system('echo hello')

This code will yield the expected output, hello from stdout, and exit code of 0. But when I try to execute commands from rust or dart, commands like echo and ls won't work.

// rust
Command::new("echo")
        .arg("hello")
        .spawn()
        .expect("echo command failed to start");
// dart
await Process.run('echo', ['hello'])

Both of these will yield binary file/command not found errors. Why is that? I am simply looking for an equivalent of python's system function in both of these languages.

I don't think it is because of the OS used. Because even if ls don't wok on windows, echo should. I tested both dir and ls because I was worried it is about OS, but none of them worked.

2 Answers

Because echo is not a program found on the computer, it is a shell command. Command::new takes in an executable to run as a sub-process.

If you are on windows you can use

Command::new("cmd")
    .args(&["/C", "echo hello!"])
    .spawn()
    .expect("echo command failed to start");

to run the CMD program and /C to pass in a command, in this case echo.

On linux you can use the bash executable.

Command::new("bash")
    .args(&["-c", "echo hello"])
    .spawn()
    .expect("echo command failed to start");

See the rust docs for std::process::Command

You need to set the runInShell param to true, like:

  var r = await Process.run('echo', ['hello'], runInShell: true);
  print(r.stdout); //Prints 'hello'

From the dart api

If runInShell is true, the process will be spawned through a system shell. On Linux and OS X, /bin/sh is used, while %WINDIR%\system32\cmd.exe is used on Windows.

Related