
Much hair-pulling resulted today when I attempted to perform a small task. The System.Process module provides the runCommand function. This takes a complete command line and returns a ProcessHandle. No problem there. The module also provides the runProcess function, which enables you to set environment variables and so forth. However... this doesn't take a complete command line. It takes a path to an executable and a list of parsed arguments. Herein lies the problem: I have a program that accepts complete commands from a file and executes them. It works perfectly. And now I'd just like to set an environment variable while each command runs... But alas no, the only way to do that is with runProcess, which expects me to parse the command line first. (Before anybody remarks that "words" will do this, consider the "echo" command, which treats whitespace meaningfully.) In the end I resorted to reading the source code for the module. After about 30 minutes of hacking, I got something which typechecks but throws a runtime exception. It appears that runCommand looks for binaries in the system search path, but the code I've concocted doesn't. (Despite being cut and pasted from the definition of runCommand.) The only thing I can think of is that the source code I'm looking at (GHC 6.8.3) is different from the version of the library I have (GHC 6.8.1). Anyway, the point I'm trying to get to is... would it be hard for however maintains this library to add a little more flexibility in what it can do please?

On Sep 29, 2008, at 15:49 , Andrew Coppin wrote:
Herein lies the problem: I have a program that accepts complete commands from a file and executes them. It works perfectly. And now I'd just like to set an environment variable while each command runs... But alas no, the only way to do that is with runProcess, which expects me to parse the command line first. (Before anybody remarks that "words" will do this, consider the "echo" command, which treats whitespace meaningfully.)
env FOO=bar mycommand ... -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

Brandon S. Allbery KF8NH wrote:
On Sep 29, 2008, at 15:49 , Andrew Coppin wrote:
Herein lies the problem: I have a program that accepts complete commands from a file and executes them. It works perfectly. And now I'd just like to set an environment variable while each command runs... But alas no, the only way to do that is with runProcess, which expects me to parse the command line first. (Before anybody remarks that "words" will do this, consider the "echo" command, which treats whitespace meaningfully.)
env FOO=bar mycommand ...
Does that work for Windows?

On Sep 29, 2008, at 15:59 , Andrew Coppin wrote:
Brandon S. Allbery KF8NH wrote:
On Sep 29, 2008, at 15:49 , Andrew Coppin wrote:
Herein lies the problem: I have a program that accepts complete commands from a file and executes them. It works perfectly. And now I'd just like to set an environment variable while each command runs... But alas no, the only way to do that is with runProcess, which expects me to parse the command line first. (Before anybody remarks that "words" will do this, consider the "echo" command, which treats whitespace meaningfully.)
env FOO=bar mycommand ...
Does that work for Windows?
Only if on of the unix-simulation environments is installed. I wouldn't want to bet on such things working reliably cross-platform anyway; even if it works something like the same way, the variable names are usually different. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Tue, 30 Sep 2008 08:49:44 Andrew Coppin wrote:
Before anybody remarks that "words" will do this, consider the "echo" command, which treats whitespace meaningfully.)
tim@florida:~/$ echo foo bar baz foo bar baz Echo doesn't receive special treatment. It joins its arguments with spaces.

On Tue, Sep 30, 2008 at 2:32 AM, Timothy Goddard
On Tue, 30 Sep 2008 08:49:44 Andrew Coppin wrote:
Before anybody remarks that "words" will do this, consider the "echo" command, which treats whitespace meaningfully.)
tim@florida:~/$ echo foo bar baz foo bar baz
Echo doesn't receive special treatment. It joins its arguments with spaces.
To clarify, the shell is what's responsible for splitting the argument line; the argument array you'd pass to runProcess is what the process would literally get, but if you use runCommand it gets passed to the shell for splitting first. All programs want argument arrays, not un-split lines, and if you don't have the shell split it you'll have to do it yourself. words works fine.

"Svein Ove Aas"
All programs want argument arrays, not un-split lines, and if you don't have the shell split it you'll have to do it yourself. words works fine.
...as long as the words don't contain quotes, or wildcard/globbing characters, or $, ! and probably other things I can't think of right now? -k -- If I haven't seen further, it is by standing in the footprints of giants

On Tue, Sep 30, 2008 at 10:14:38AM +0200, Ketil Malde wrote:
"Svein Ove Aas"
writes: All programs want argument arrays, not un-split lines, and if you don't have the shell split it you'll have to do it yourself. words works fine.
...as long as the words don't contain quotes, or wildcard/globbing characters, or $, ! and probably other things I can't think of right now?
Actually, it's no problem having any of those characters in your arguments, it's just that they'll be passed literally (which may or may not be what your user wants--sometimes it's really convenient to avoid multiple layers of escapes). The one constraint that using words makes is that it doesn't allow you to specify arguments that contain a space. David

David Roundy
Actually, it's no problem having any of those characters in your arguments,
My point is that using 'words' on the argument sting to 'runProcess' and expecting the same result as 'runCommand' implies making those assumptions:: Prelude System.Process> let args = "_* foo \"bar rab\" $$" Prelude System.Process> runProcess "echo" (words args) Nothing Nothing Nothing Nothing Nothing _* foo "bar rab" $$ Prelude System.Process> runCommand ("echo "++args) _darcs foo bar rab 2121 -k -- If I haven't seen further, it is by standing in the footprints of giants

On Tue, 2008-09-30 at 18:33 +0200, Ketil Malde wrote:
David Roundy
writes: Actually, it's no problem having any of those characters in your arguments,
My point is that using 'words' on the argument sting to 'runProcess' and expecting the same result as 'runCommand' implies making those assumptions::
Prelude System.Process> let args = "_* foo \"bar rab\" $$"
Prelude System.Process> runProcess "echo" (words args) Nothing Nothing Nothing Nothing Nothing _* foo "bar rab" $$
Prelude System.Process> runCommand ("echo "++args) _darcs foo bar rab 2121
This behavior is Windows-specific; I get the the same result in both cases on Linux. jcc

On Tue, 2008-09-30 at 09:30 -0700, Jonathan Cast wrote:
On Tue, 2008-09-30 at 18:33 +0200, Ketil Malde wrote:
David Roundy
writes: Actually, it's no problem having any of those characters in your arguments,
My point is that using 'words' on the argument sting to 'runProcess' and expecting the same result as 'runCommand' implies making those assumptions::
Prelude System.Process> let args = "_* foo \"bar rab\" $$"
Prelude System.Process> runProcess "echo" (words args) Nothing Nothing Nothing Nothing Nothing _* foo "bar rab" $$
Prelude System.Process> runCommand ("echo "++args) _darcs foo bar rab 2121
This behavior is Windows-specific;
No it's not... Never mind. jcc

On Tue, Sep 30, 2008 at 06:33:52PM +0200, Ketil Malde wrote:
David Roundy
writes: Actually, it's no problem having any of those characters in your arguments,
My point is that using 'words' on the argument sting to 'runProcess' and expecting the same result as 'runCommand' implies making those assumptions::
My point was that which of these is correct entirely depends on what your input is. It's often a huge (and security-bug-prone) chore to escape all those shell characters, and so in many cases it's much nicer to execute an external program direcly without invoking a shell. David

Timothy Goddard wrote:
On Tue, 30 Sep 2008 08:49:44 Andrew Coppin wrote:
Before anybody remarks that "words" will do this, consider the "echo" command, which treats whitespace meaningfully.)
tim@florida:~/$ echo foo bar baz foo bar baz
Echo doesn't receive special treatment. It joins its arguments with spaces.
D:\>echo foo bar baz foo bar baz

how about using a wrapper script, to which you would supply the value as parameter so you would just use runCommand "thescript <envval> <rest of parameters>" ? Herein lies the problem: I have a program that accepts complete commands
from a file and executes them. It works perfectly. And now I'd just like to set an environment variable while each command runs... But alas no, the only way to do that is with runProcess, which expects me to parse the command line first. (Before anybody remarks that "words" will do this, consider the "echo" command, which treats whitespace meaningfully.)
on windows, echo is just a shell command, not executable, so it gets special treatment.

Andrew Coppin wrote:
Anyway, the point I'm trying to get to is... would it be hard for however maintains this library to add a little more flexibility in what it can do please?
In the new System.Process, that comes with GHC 6.10.1: Prelude System.Process> createProcess (shell "echo $FOO"){ env = Just [("FOO","BAR")] } Prelude System.Process> BAR Cheers, Simon

Simon Marlow wrote:
Andrew Coppin wrote:
Anyway, the point I'm trying to get to is... would it be hard for however maintains this library to add a little more flexibility in what it can do please?
In the new System.Process, that comes with GHC 6.10.1:
Prelude System.Process> createProcess (shell "echo $FOO"){ env = Just [("FOO","BAR")] } Prelude System.Process> BAR
Ah, cool. So it's already in hand then...
participants (10)
-
Andrew Coppin
-
Brandon S. Allbery KF8NH
-
David Roundy
-
Jonathan Cast
-
Ketil Malde
-
Matti Niemenmaa
-
Simon Marlow
-
Svein Ove Aas
-
Timothy Goddard
-
wman