Issue with RUN command?

Linux specific questions.
Post Reply
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Issue with RUN command?

Post by TJF »

My target is executing commands when my application ends. This I can realize with the last code line

Code: Select all

RUN("/bin/dash", "/tmp/script")
where file /tmp/script is an excutable script file containing the commands

cmd-1
cmd-2


All fine so far.

Now I want to get rid of the extra script file. The dash shell can input commands as an argument. Instead of passing the file name

/bin/dash /tmp/script

one can also pass the file content as argument like

/bin/dash -c 'cmd-1 ; cmd-2'

This works in a terminal. But transfering to my application code

Code: Select all

VAR r = RUN("/bin/dash", "-c 'cmd-1 ; cmd-2'")
doesn't work. Neither of the commands get executed. And the return value r doesn't indicate an error.

Why is executing dash from FB code working with the script file argument, but isn't working with -c option?

Thanks in advance!

PS: FreeBASIC Compiler - Version 1.05.0 (09-21-2018), built for linux-arm (32bit)
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Issue with RUN command?

Post by marcov »

Look with strace to see what is passed to execve. Then you can see what goes wrong breaking up the argument line in its components.

Unix/execve demands an array of parameters, in this case two

(1) -c and (2) 'cmd-1 ; cmd-2' (without ticks maybe?)

this should be visible with strace.

if the FB helper routine (or the libc routine that wraps execve like execl) doesn't get the quoting, it will fail.

We therefore overload our version of RUN with a form that accepts an open array of parameters, so that you can avoid the need for nested quoting, something like

RUN ("/bin/dash","-c","cmd-1; cmd-2"); or

RUN ("/bin/dash","-c","'cmd-1; cmd-2'"); if the ticks are needed.

This omits the need of complicated parsing of cmdlines, after we had to fix said parsing for all kinds of corner cases 4 releases in a row.

But in this case it maybe is easier to use a System() based primitive ?
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: Issue with RUN command?

Post by TJF »

Thanks for the tipp!

I never used strace yet. It'll take some time to find out if it helps.

BTW: The ticks are mandatory, dash expects all commands in one argument (since further arguments may follow).

Regards
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Issue with RUN command?

Post by marcov »

TJF wrote:Thanks for the tipp!

I never used strace yet. It'll take some time to find out if it helps.
(on *BSD often called ktrace/kdump (ktrace is about the same a strace but outputs to a binary file, kdump dumps the file, and on Solaris and Darwin something similar is called "truss".

BTW: The ticks are mandatory, dash expects all commands in one argument (since further arguments may follow).
Yes and no. It is only needed for the separation of a commandline into an argc/argv array to be passed to execve. In that case if you have them in argv/argc form you don't need the ticks no longer, and the parsing should eat them.

If the ticks are backticks and meant to mean "execute this command", then they are mandatory, and must also be present in the array notation.
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: Issue with RUN command?

Post by TJF »

Found the problem!

The RUN statment parses the command line. When the one and only argument is the script name, it gets passed as-is

execve("/bin/dash", ["/bin/dash", "/tmp/script"], [/* 28 vars */]) = 0

In contrast, the commands in the single quotes get butchered

execve("/bin/dash", ["/bin/dash", "-c", "'", "cmd-1", ";", "cmd-2", "'"], [/* 28 vars */]) = 0

IMHO that's a bug. An argument in quotes shouldn't get parsed.

The solution is to pass in double quotes

execve("/bin/dash", ["/bin/dash", "-c", " cmd-1 ; cmd-2 "], [/* 28 vars */]) = 0

Here, fbc works as expected.

Regards
Post Reply