Execute command line from Scheme (Guile)
Asked Answered
G

2

9

The question is described on the title, basically I'd like to execute a command line from scheme, let's say 'ls' and obtaining the output. So my questions are:

  • Is it possible?
  • How?

Thanks a lot in advance!

By the way I use Guille.

Gahl answered 19/10, 2015 at 9:5 Comment(0)
B
12

You need one of these system and system*.

Example: (system "ls")

From the documentation: Guile Reference

— Scheme Procedure: system [cmd]
— C Function: scm_system (cmd)
Execute cmd using the operating system's “command processor”. Under Unix this is usually the default shell sh. The value returned is cmd's exit status as returned by waitpid, which can be interpreted using the functions above.

If system is called without arguments, return a boolean indicating whether the command processor is available.

— Scheme Procedure: system* . args
— C Function: scm_system_star (args)
Execute the command indicated by args. The first element must be a string indicating the command to be executed, and the remaining items must be strings representing each of the arguments to that command.

This function returns the exit status of the command as provided by waitpid. This value can be handled with status:exit-val and the related functions.

system* is similar to system, but accepts only one string per-argument, and performs no shell interpretation. The command is executed using fork and execlp. Accordingly this function may be safer than system in situations where shell interpretation is not required.

Example: (system* "echo" "foo" "bar")
Balkin answered 19/10, 2015 at 12:25 Comment(2)
How are input, output and error streams handled by system?Carreon
I don't think they are affected - the Guile system calls the posix system more or less directly. github.com/cky/guile/blob/stable-2.0/libguile/simpos.c#L65Balkin
D
0

The other answer covered how to run programs from guile, but if you want to capture the output too, you need to use functions from the (ice-9 popen) module. It includes options for using sh -c to execute the supplied command, running a program directly without using a shell, and chaining together a pipeline of multiple commands. The output of the executed command(s) is available by reading from a returned port (Alternatively, in OPEN_WRITE mode, you can provide input to the commands via writing to the returned port). The commands run asynchronously in the background, unlike with system, and reading might block if there's no output ready, and conversely the program might block until you read its output.

A basic example (Sticking with ls for example's sake, though there are better options if you want to get the list of files in a directory that you'd use instead in real code):

(use-modules (ice-9 popen)
             (ice-9 textual-ports)) ; for get-string-all

(define ls (open-pipe* OPEN_READ "ls"))
(display (get-string-all ls))
(close-pipe ls)
Dipsomania answered 22/1 at 0:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.