Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2012-09

TProcess and arguments with quotes

14 messages · 5 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Martin

From http://bugs.freepascal.org/view.php?id=22801

You should not pass quotes. The quotes are only needed in a shell.

That is not always possible. And the quotes work on most platforms.

I know TProcess changed from a single command-line to a listof arguments. So I couldn't find the User Changes note for this.

An application may however have a list of arguments in a single string (e.g. the IDE ask the user to specify extra arguments. This can be 0, 1 or many)

Those must be broken into individual strings. TProcess does that if send as command line.
In this case the quotes are needed. Or the commandline can not be broken down.

The IDE could in that case of course try to parse the params itself, and try to remove the quotes. but that leaves much room for error (removing quotes that are meant to be passed to the app)

Reply by email

Unknown author
to Martin: From http://bugs.freepascal.org/view.php?id=22801 That is not always possible. And the…
Martin wrote
From http://bugs.freepascal.org/view.php?id=22801 > You should not pass quotes. The quotes are only needed in a shell. That is not always possible. And the quotes work on most platforms.

Windows is an exception (as usual). See below.

I know TProcess changed from a single command-line to a listof arguments. So I couldn't find the User Changes note for this.

You don't need the 'User changes'. It is documented. Press F1.

An application may however have a list of arguments in a single string (e.g. the IDE ask the user to specify extra arguments. This can be 0, 1 or many)

So ?

Those must be broken into individual strings. TProcess does that if send as command line.

No, it does not "break anything down".

On non-windows, each element in the params list is passed as-is in the argv array; No changes are windows, each string is surrounded by quotes if there is a space and no quotes in the string. The string itself is not touched.

This is necessary because the Windows API (CreateProcess) requires a single string:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx

Note that the API does not mention anywhere how quotes or spaces should be handled. The reason is that the started application on windows is supposed to handle its own command-line processing. Unlike Unix, the started application gets the whole command-line and is supposed to take care of everything by itself. How it does this is ruled by custom only.

In short: Windows doesn't cater very well for the command-line. What quoting may work for application 1, may not work for application 2.

Michael.

Reply by email

Unknown author
to Unknown author
Show quoted text 42 lines
On Wed, 5 Sep 2012, Martin wrote: > From http://bugs.freepascal.org/view.php?id=22801 >> You should not pass quotes. The quotes are only needed in a shell. > > That is not always possible. And the quotes work on most platforms. Windows is an exception (as usual). See below. > > I know TProcess changed from a single command-line to a listof arguments. > So I couldn't find the User Changes note for this. You don't need the 'User changes'. It is documented. Press F1. > An application may however have a list of arguments in a single string > (e.g. the IDE ask the user to specify extra arguments. This can be 0, 1 or > many) So ? > > Those must be broken into individual strings. TProcess does that if send > as command line. No, it does not "break anything down". On non-windows, each element in the params list is passed as-is in the argv array; No changes are performed at all. On windows, each string is surrounded by quotes if there is a space and no quotes in the string. The string itself is not touched. This is necessary because the Windows API (CreateProcess) requires a single string: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx Note that the API does not mention anywhere how quotes or spaces should be handled.

I should specify here: for parameters. For the binary, it is specified, because of the spaces in the path.

Michael.

Reply by email

Marco van de Voort
to Martin: From http://bugs.freepascal.org/view.php?id=22801 That is not always possible. And the…

In our previous episode, Martin said:

That is not always possible. And the quotes work on most platforms.

Define "platform" in the context of execution. Both API and shell?

An application may however have a list of arguments in a single string (e.g. the IDE ask the user to specify extra arguments. This can be 0, 1 or many)

No problem. As long as internally you keep them apart (e.g. use a tstrings based control).

The reason why tprocess changed to a list is to avoid the need to concatenate arguments (and thus split them again). So in time it is urgently recommended to follow that.

The IDE could in that case of course try to parse the params itself, and try to remove the quotes. but that leaves much room for error (removing quotes that are meant to be passed to the app)

Do not concatenate in the first place, then there is no need for parsing. That should at least be the long term planning.

Reply by email

Jonas Maebe
to Unknown author: Windows is an exception (as usual). See below. You don't need the 'User changes'. It is…

michael.vancanneyt wrote on Wed, 05 Sep 2012:

Show quoted text 6 lines
On Wed, 5 Sep 2012, Martin wrote: > I know TProcess changed from a single command-line to a listof > arguments. So I couldn't find the User Changes note for this. You don't need the 'User changes'. It is documented. Press F1.

Well, one of the reasons for the existence of the user changes wiki pages is to avoid requiring people to reread the entire manual with every new release just to figure out what has changed that may require code changes.

Jonas

Reply by email

Martin
to Unknown author: Windows is an exception (as usual). See below. You don't need the 'User changes'. It is…
On non-windows, each element in the params list is passed as-is in the argv array; No changes are FPC offer a utility function to break a "shell style" commandline

into the correct arguments?
--foo=abc --bar="several words"

if in a single line, then the quotes are needed, otherwise "words" becomes a 3rd arg.

Is there a function, that breaks the above into 2 args?

Reply by email

Martin
to Unknown author: Windows is an exception (as usual). See below. You don't need the 'User changes'. It is…
On non-windows, each element in the params list is passed as-is in the argv array; No changes are itself supplies a function
function RunCommand(const cmdline:string;var
outputstring:string):boolean; deprecated;

it uses TProcess.CommandLine

using this function, how do I run the following: (example in shell style)

gdb -i mi -eval-command="set disassembly-flavor intel"

Reply by email

Marco van de Voort
to Martin

In our previous episode, Martin said:

Show quoted text 14 lines
> On non-windows, each element in the params list is passed as-is in the > argv > array; No changes are performed at all. FPC itself supplies a function function RunCommand(const cmdline:string;var outputstring:string):boolean; deprecated; it uses TProcess.CommandLine using this function, how do I run the following: (example in shell style) gdb -i mi -eval-command="set disassembly-flavor intel"

Why do you think this new function was added _deprecated_ ? :-)

The commandline_is_a_single string variants of TProcess are deprecated and do not support cornercases wrt quoting. And this is one.

Use the separate arguments facility.

(p.s. it was added despite being deprecated to add in the conversion process. Too many people were trying to do basic piping with the "short" output tprocess template, and I wanted to have a good one in the field to stop the copy-and-pasting)

Reply by email

Martin
to Martin: function RunCommand(const cmdline:string;var outputstring:string):boolean; deprecated; it…
Martin wrote
function RunCommand(const cmdline:string;var outputstring:string):boolean; deprecated;

Sorry seen to late, it is deprecated...

Seems that FPC is missing the functionality for "commandline" (which is a property that existed for very long). Seen that it is now deprecated probably means there are no plans to implement it?

However the reason

Marco van de Voort wrote
The reason why tprocess changed to a list is to avoid the need to concatenate arguments (and thus split them again). So in time it is urgently recommended to follow that.

does not explain the lack of a working command line property. For code that has already individual params, the new Parameters[] property could live together with a fully implemented commandline.

Assuming, that there are many apps that have a single string, IMHO it would be a good idea to add this functionality in fpc.

Reply by email

Unknown author
to Martin
Martin wrote 10 lines
On 05/09/2012 10:38, Martin wrote: > > function RunCommand(const cmdline:string;var outputstring:string):boolean; > deprecated; Sorry seen to late, it is deprecated... Seems that FPC is missing the functionality for "commandline" (which is a property that existed for very long). Seen that it is now deprecated probably means there are no plans to implement it?

Correct.

Show quoted text 10 lines
However the reason On 05/09/2012 10:00, Marco van de Voort wrote: > The reason why tprocess changed to a list is to avoid the need to > concatenate arguments (and thus split them again). So in time it is > urgently recommended to follow that. does not explain the lack of a working command line property. For code that has already individual params, the new Parameters[] property could live together with a fully implemented commandline.

The reason we want to get rid of the commandline is EXACTLY what you are experiencing. The quoting rules, which are non-existent and application specific on Windows, and which cause nothing but problems on Unix because most people do not understand them.

To avoid these, we switched to Parameters. They have the benefit of a simple use, and it is easier to 'imitate' windows using the unix Argv paradigm than vice versa. Namely: it avoids parsing.

Assuming, that there are many apps that have a single string, IMHO it would be a good idea to add this functionality in fpc.

It will not be added to TProcess.
On the contrary: CommandLine is marked deprecated becase it will disappear.

I have explained what to do, I will check if the documentation needs some enhancements. But you must use parameters correctly.

Michael.

Reply by email

Marco van de Voort
to Martin: Sorry seen to late, it is deprecated... Seems that FPC is missing the functionality for…

In our previous episode, Martin said:

Show quoted text 8 lines
> function RunCommand(const cmdline:string;var > outputstring:string):boolean; deprecated; Sorry seen to late, it is deprecated... Seems that FPC is missing the functionality for "commandline" (which is a property that existed for very long). Seen that it is now deprecated probably means there are no plans to implement it?

Nope. Actually issues like this were the reason to deprecate it. There barely has been a FPC version without changes to the quoting, and every usage could possibly break something else again.

Users also seemed to be unable to handle the difference between api and shell, which also caused constant confusion.

Show quoted text 6 lines
> concatenate arguments (and thus split them again). So in time it is > urgently recommended to follow that. does not explain the lack of a working command line property. For code that has already individual params, the new Parameters[] property could live together with a fully implemented commandline.

Define fully. What do you do when stuff conflicts between platforms?

How many escapes is still reasonable?

Moreover, if this is a crucial interface, how do you make sure it is stable in every release? Actually the debugger interface in Lazarus and its critical importance was one of the reasons behind this alternate course.

For code as critical as the debugger interface in Lazarus you might want to do your own parsing and then pass it to the mostly invariant (and thus hopefully stable) arguments like interface of FPC.

But of course more logical is to eliminate the dangerous parsing entirely.

Assuming, that there are many apps that have a single string, IMHO it would be a good idea to add this functionality in fpc.

Nothing has been removed. It only has been deprecated.

Reply by email

Unknown author
to Marco van de Voort
Marco van de Voort wrote 16 lines
In our previous episode, Martin said: >> function RunCommand(const cmdline:string;var >> outputstring:string):boolean; deprecated; > > Sorry seen to late, it is deprecated... > > Seems that FPC is missing the functionality for "commandline" (which is > a property that existed for very long). Seen that it is now deprecated > probably means there are no plans to implement it? Nope. Actually issues like this were the reason to deprecate it. There barely has been a FPC version without changes to the quoting, and every usage could possibly break something else again. Users also seemed to be unable to handle the difference between api and shell, which also caused constant confusion.

Exactly.

Michael.

Reply by email