exec function not returning string list

Started by TedWalther, December 05, 2015, 04:13:02 AM

Previous topic - Next topic

TedWalther

Since I've had problems with (process), I tried to use (exec) instead.  When I read the documentation I was very happy; it does exactly what I need.



(exec "command") => string-list


With (exec), I would run the command, and it would return the output of the command as a list of strings.  Ok, that is almost what I need, but I need to send the command some specific input.  Great!  (exec) allows that, with usage:



(exec "command" "input to command") => ?


The documentation doesn't say that (exec cmd input) has different output than (exec cmd).  But, it doesn't return a list of strings.  Instead it returns a number.  Whether it is a process id or the exit value of the program, I don't know.



Lutz, could exec with user supplied input be updated to return the same string list I've come to expect from the simpler form?



Again, this is with newLisp 10.6.2.
Cavemen in bearskins invaded the ivory towers of Artificial Intelligence.  Nine months later, they left with a baby named newLISP.  The women of the ivory towers wept and wailed.  \"Abomination!\" they cried.

Lutz

#1
The exec function uses the C function popen() to open a process and return a pipe handle. This pipe is only unidirectional, you can call popen() either con "r" for reading in the first syntax of exec or "w" for writing for the second syntax of exec.



There is only FreeBSD and some FreeBDS derivates, where you can specify "r+" in popen() for a bidirectional pipe. On Linux and OpenBSD this would not work.



One could fake a bidirectional popen() using fork() and duplicating/creating pipe handles, but this would not work on Windows, which does not have fork.



Here is a work-around which will work on all OSs:



> (exec "wc > result" "this is a sentence") ; wc counts letters and words
true
> (exec "cat result")
("       0       4      18")


So this will give you output as if a bidirectional exec and still lets you specify the input coming from newLISP.

hds1

#2
If you want to avoid the interim file creation you could use the environment as a placeholder

i.e.



(env "willi" "<html><head></head><body>Killroy</body></html>")



(exec "echo $willi" | tidy -q 2>/dev/null)

=> ("<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">" "<html>" "<head>" "<meta name="generator" content="

 ""HTML Tidy for Linux (vers 25 March 2009), see http://www.w3.org">http://www.w3.org">" "<title></title>"

 "</head>" "<body>" "Killroy" "</body>" "</html>")



;; cleanup a bit if you like

(env "willi" "")



I used this method with success on thousands of html files upto 2MB of size (Linux 64bit system).

Limited of course to the env you are working with.