Julia spawn several commands

Hi Julia users,

I would like to run a command that is actually several commands separated by semi-colons.

ex:

run(`ls; ls`)

I get an error that semi-colons needs to be quoted.

  • run('ls; ls') does not work
  • run(ls';' ls) does not work
  • run([ls, ls]) does not work

I intend to run the command in a Process using spawn, so doing run(ls); run(ls) does not work either.

Is there a good workaround?

WARNING: special characters "#{}()[]<>|&*?~;" should now be quoted in commands

Try:

run(`ls\; ls`)

actually, that doesn’t work either (it gives ERROR: could not spawn ‘ls;’ ls: no such file or directory (ENOENT)). The reason is that ; is a shell feature, and Julia commands aren’t run through the shell at all. That’s also why globbing, $-expansion, and aliases don’t work in Julia commands.

@tawheeler what’s wrong with:

run(`ls`)
run(`ls`)

?

Or, if you really want to use shell features, you can invoke the shell:

run(`bash -c "ls; ls"`)

but then you lose Julia’s nice handling of quoting and escaping and are instead back in the wild west of shell syntax.

3 Likes

I wanted to call them in the same spawn process. So actually, spawn(ls; ls). It isn’t the end of the world if this doesn’t work, but I figured there was just some simple thing I was missing.
Thanks!

You can combine Cmd objects with &:

spawn(`ls` & `ls`)

which returns something called a ProcessChain… which sounds promising? Thought I think it might kick them off asynchronously.

Thanks - I can just put what I need in a bash script and call that.

Why? Even if they are originally in a single process like a shell that then has to run them as separate processes.

I want to first prepare env variables and then call a ros command.

It may be easier to use the withenv function in Julia.

2 Likes

I encounter a similar problem as yours, my solution is to create an iobuffer to emulate a script, and run the script. For instance, we want to run powershell commands to sleep a computer through Julia, we know the working powershell commands like

Add-Type -Assembly System.Windows.Forms
[System.Windows.Forms.Application]::SetSuspendState(“Suspend”, $false, $true)

Then, the julia code can be written as

io = IOBuffer()
write(io, """Add-Type -Assembly System.Windows.Forms
            [System.Windows.Forms.Application]::SetSuspendState("Suspend", \$false, \$true)""")
run(`powershell $(String(take!(io)))`)

In this way, you could theoretically execute any complex command sequence without using pipeline.