REBOL
Docs Blog Get-it

REBOL Shell Interface

SDK Documentation

Contents

Overview
The Call Function
Basic Syntax
Refinements
Other Shell Details
Waiting for Commands
Redirection
Redirecting Input
Redirecting Output and Errors
Combining Redirection Refinements
Redirecting to the REBOL Console

Overview

This chapter describes how to use the REBOL Shell Interface to execute programs and shell commands and redirect command input and output.

A shell is an operating environment. It enables users to communicate with, execute, and control programs and the operating system. Shells vary widely depending on the operating system.

The Shell Interface enables REBOL to communicate with shell programs and the operating system. The Shell Interface uses the CALL function to execute built-in commands or programs. These built-in commands and programs are also known as shell commands. (In this chapter, the term shell command refers to both built-in commands and programs.)

With the Shell Interface, in Unix and Windows, input to a shell command can be redirected from a file, URL, port, string value, or the REBOL console. Both normal and error output from a shell command can be redirected to a file, URL, port, string value, or the REBOL console.

The Call Function

Basic Syntax

Use the CALL function to execute a shell command. The syntax of the CALL function is shown in the following example:

call argument

The CALL function accepts one argument, which can be a string or a block specifying a shell command and its arguments.

The following example shows a string as the CALL argument.

call "cp source.txt dest.txt"

In this example, CALL executes the Unix file copy command, cp, and passes two file arguments, source.txt and dest.txt. When CALL is evaluated, the string is translated into a shell command that calls cp and passes the two arguments. The result is the source.txt file being copied to the dest.txt file.

Use a block argument with CALL when you want to include REBOL values in the call to a shell command, as shown in the following example:

source: %source.txt
dest: %dest.txt
call reduce ["cp" source dest]

In this example, the cp command is called using a block value to pass the arguments source.txt and dest.txt. The block must be reduced for the CALL function to obtain the file names referred to by the source and dest varaibles.

The CALL function translates the file names in a block to the notation used by the shell. For example, the argument

[dir %/c/windows]

will be translated to:

{dir "c:\windows"}

for the shell call.

Refinements

The following refinements can be used with the CALL function.

Refinement Argument Datatypes Description
wait   Causes CALL to wait for a shell command's return code. The CALL function then returns the shell command's return code to the REBOL program.
input string, file name, port, URL, or none Windows and Unix only: redirects string, file, port, and URL data as input to a shell command.
output string, file name, port, URL, or none Windows and Unix only: redirects shell command output to a string, file, port, or URL.
shell   Windows Only: Forces the use of a shell. (Because in Windows, programs started with CALL are not normally run from a shell, but are launched directly from the operating system.)
error string, file name, port, URL, or none Windows and Unix only: redirects shell command errors to a string, file, port, or URL. See
console   Windows and Unix only: redirects all input and output of a shell command to the REBOL console. This enables the console to directly interact with a shell command. See

Other Shell Details

When REBOL uses a shell to execute a shell command, shell features can be used in the arguments passed by the CALL function. Shell features include redirection and expansion symbols. These symbols are the most common:

< standard input (stdin)
> standard output (stdout)
| pipe output to another command
* wildcard to match zero or more characters
? match any single character

In Unix, the REBOL language calls all commands using a shell. The most common Unix shells are bsh (Bourne Shell), csh (C Shell), ksh (Korn Shell), and bash.

The Unix SHELL environment variable determines which shell REBOL uses to execute a command. By default, the environment variable is set to the path of the shell currently in use. For example, if REBOL is started from the C shell, the SHELL environment variable is set to the path for the C shell. Because all Unix shells support the -c option, which causes the shell to exit after a command executes, REBOL automatically uses this option when calling a Unix program.

REBOL normally calls Windows programs directly, bypassing the shell. Consequently, Windows shell features, such as redirection and expansion symbols, cannot be used in the arguments passed by the CALL command. However, when executing built-in Windows shell commands or DOS programs, REBOL uses the shell. When this happens, REBOL calls the command shell command.com (Windows) or cmd.exe (Windows NT). When calling a Windows shell command, REBOL automatically uses the /c switch, which causes the shell to exit after executing a command.

Waiting for Commands

When shell commands are called, they normally run as a separate process in parallel with REBOL. They are asynchronous to REBOL.

However, there are times when you want to wait for a shell command to finish, such as when you are executing multiple shell commands. In addition, every shell command has a return code, which normally indicates the success or failure of the command. Typically, a shell command returns zero when it is successful and a non-zero value when it is unsuccessful.

The /wait refinement causes the CALL function to wait for a command's return code and return it to the REBOL program. You can then use the return code to verify that a command executed successfully, as shown in the following example:

if zero? call/wait "dir" [
    print "worked"
]

In the above example, CALL successfully executes the Windows dir command, which is indicated by the zero return value. However, in the next example, CALL is unsuccessful at executing the xcopy command, which is indicated by the return value other than zero.

if not zero? code: call/wait "xcopy" [
    print ["failed:" code]
]

When you use the /input, /output, /error, or /console refinements you automatically set the /wait refinement.

Redirection

In Windows and Unix, input to a shell command can be redirected from a file, URL, string, or port. By default, a shell command's output and errors are ignored by REBOL. However, shell command output and errors can be redirected to a file, URL, port, string, or the REBOL console.

This section describes how to redirect input, output, and errors.

In AmigaOS and BeOS input/output redirection between REBOL and shell commands is not supported. Instead temporary files have to be created which can then be piped into shell commands:

write %/tmp/infile inputdata
call/wait "sort /tmp/outfile"
print read %/tmp/outfile

Redirecting Input

In Windows and Unix, data from a file, URL, port, or string can redirected as input to a shell command using the /input refinement with CALL. The refinement argument must contain the name of the file, URL, port, or REBOL string whose data will be passed to the shell command.

The following examples show shell command input redirected from files, URLs, ports, and REBOL strings.

From a file:

call/input {grep "Name:"} %data

In this example, the %data file is redirected as input to the Unix grep command.

From a URL:

call/input {grep "REBOL"} http://data.rebol.com/

In this example, the REBOL URL is redirected as input to the Unix grep command.

From a port:

open-port: open %data
call/input "sort" open-port

In this example, data from open-port is redirected as input to the Unix or Windows sort command.

NOTE: Data from ports opened with the /direct refinement cannot be redirected to a shell command.

From a string:

str: "this is a string of text"
call/input "wc" str

In this example, the string str is redirected as input to the Unix wc command.

Redirecting Output and Errors

In Windows and Unix, shell command output and errors can be redirected to a file, URL, port, or REBOL string using the /output and /error refinements with CALL. The refinement argument must contain the name of the file, URL, port, or REBOL string to receive the output or error. When redirected to a file, port, or URL, output overwrites any existing data. When redirected to a REBOL port or string, output is inserted at the current index position.

The following examples show shell command output and errors redirected to files, URLs, ports, and REBOL strings.

To a file:

call/output "dir /a /b *.r" %output.txt
print read %output.txt
feedback.r history.r nntp.r rebol.r user.r
call/error "cp" %error.txt
print read %error.txt

cp: missing file arguments Try `cp --help' for more information.

To a URL:

call/output "ls *.r" ftp://your-ftp.com

To a port:

port: open/direct/binary %output.txt
call/output "dir /a /b *.r" port
close port
print read %output.txt

feedback.r nntp.r history.r rebol.r user.r

To a REBOL string:

err: copy ""
call/error "cp source.txt" err
print err

cp: missing destination file Try `cp --help' for more information.

Combining Redirection Refinements

The redirection refinements can be combined in a single call function. When more than one refinement is used in a single call function, the arguments must be presented in the same order as the corresponding refinements.

input-str: "data"
output-str: copy ""
error-str: copy ""
call/input/output/error "sort"
input-str output-str error-str

The following example uses the Unix wc command to count the lines in a web page and save the data to the file called line-count.txt:

call/input/output "wc -l" http://data.rebol.com/ %line-count.txt
print read %line-count.txt

247

Redirecting to the REBOL Console

In Windows and Unix the /console refinement makes the REBOL console the interface to a shell and allows the shell to take control of the REBOL console while a shell command is being executed. Shell command output and errors are printed to the console, and the console can be used to send input directly to the command.

To prevent either a command's output or errors from printing on the console, use the /output or the /error refinement with NONE as the argument. To prevent input to a command from being entered in the console, use the /input refinement with NONE as the argument.

The following example shows the output of a command being redirected to the REBOL console:

call/console "format a:"

Insert new diskette for drive A: and press ENTER when ready...
Checking existing disk format. Formatting 1.44M Format complete.
Volume label (11 characters, ENTER for none)? New_Disk
1,457,664 bytes total disk space 1,457,664 bytes available on disk
512 bytes in each allocation unit. 2,847 allocation units available.
Volume Serial Number is 1E27-16DA
Format another (Y/N)? N
About | Contact | PrivacyREBOL Technologies 2024