RUN
The RUN
instruction executes the command passed as argument.
Syntax
RUN command
[
IN {
FORM|
LINE}
MODE ]
[
RETURNING variable |
WITHOUT WAITING ]
- command is a string expression with the command to be executed.
- variable is an integer variable receiving the execution status of the command.
Understanding the RUN command
The RUN
instruction hands the argument command to the command interpreter.
The IN FORM MODE
or IN LINE MODE
clause can be used to define
if the command is interactive or is silent. This has an impact in TUI mode. See IN LINE MODE and IN FORM MODE.
The RETURNING
clause can be used to get the result status of the command. See
Catching the execution status
If the WITHOUT WAITING
clause is not specified with the RUN
instruction, the calling process waits for the command termination. When the WITHOUT
WAITING
clause is specified, the calling process continues just after starting the command.
See Waiting for the subprocess.
RUN and GUI resources
When executing in GUI mode, resources such as images may be sent asynchroneously by fglrun to the front-end, typically at the beginning of the program execution.
If a RUN
command is executed at this time, it will suspend the parent program
execution and block the resource transfers.
Consider starting child programs with the RUN
command, when the parent program
is alive for a couple of seconds, to make sure that all GUI resources have been transmitted to the
front-end.
RUN is not supported with mobile apps
RUN cmd
and RUN cmd WITHOUT
WAITING
instructions are not supported. To implement apps running on a server, see the
runOnServer
front
call.Defining the command execution shell
RUN
instruction uses the OS-specific
shell defined in the environment of the current user:- On UNIX™, the shell program is defined by the SHELL environment variable.
- On Windows®, the shell program is defined by COMSPEC
environment variable, and this program must support the
/c
option (hardcoded).
Passing command-line arguments
The command provided to the RUN
instruction can use arguments.
-l
option and 3 file names to the
ls command:RUN "ls -l file1 file2 file3"
RUN 'ls -l "file name with spaces" '
"
quotation marks
will be removed before executing the command string. This can lead to command execution failure,
when arguments using space characters need to be enclosed in double
quotes:RUN '"C:\\Program Files\\Tools\\bin\\cleanup.exe" "C:\\tmp\\my dir"'
Above
instruction will actually try to execute the following
command:C:\Program Files\Tools\bin\cleanup.exe" "C:\tmp\my dir
A typical
workaround (on Windows only) is to surround the whole
command again in double
quotes:RUN '" "C:\\Program Files\\Tools\\bin\\cleanup.exe" "C:\\tmp\\my dir" "'
See
MSDN documentation for CMD.EXE details.Using OS shell features
RUN
instruction can use any possibilities supported
by the OS shell, such as output redirection, chaining commands,
etc:RUN "grep -h name *.txt | sort -u > zz"
Waiting for the subprocess
By default, the RUN
instruction waits
for the end of the execution of the command, suspending the execution of the current program. After
executing the command, the display of the parent program is restored.
If you specify WITHOUT WAITING
, the command line is executed as a background
process, and must not affect the visual display. This clause can be used when the command takes some
time to execute, and the parent program does not need the result to continue. It is also typically
used in GUI mode to start another program. Do not use this clause in TUI mode when the sub-program
displays forms, otherwise both programs would run simultaneously on the same terminal.
Catching the execution status
The RETURNING
clause saves the termination status code of the command that
RUN
executes in a program variable of type SMALLINT
. Examine the
variable after execution to determine the next action to take. A status code of zero usually
indicates that the command has terminated normally. A non-zero exit status indicates an error.
RETURNING
clause is platform-dependent:- On UNIX systems, the value is composed of two bytes having
different meanings: The lower byte (x mod 256) of the return status defines the termination status
of the
RUN
command. The higher byte (x / 256) of the return status defines the execution status of the program. - On Windows platforms, the execution status is zero for success, or a non-zero value if an error occurred: The value of the return status only defines the execution status of the program.
MAIN
IF arg_val(1)=="child" THEN
DISPLAY SFMT("Child: EXIT PROGRAM %1", arg_val(2))
EXIT PROGRAM arg_val(2)
ELSE
IF arg_val(1) IS NULL THEN
CALL run_cmd("invalid-command")
ELSE
CALL run_cmd(SFMT("fglrun run child %1",arg_val(1)))
END IF
END IF
END MAIN
FUNCTION run_cmd(cmd STRING) RETURNS ()
DEFINE s, rs, cs SMALLINT
DISPLAY "\nCommand: ", cmd
RUN cmd RETURNING s
DISPLAY "RUN RETURNING result:"
DISPLAY SFMT(" s = %1", s)
LET rs = s MOD 256
DISPLAY SFMT(" s MOD 256 = %1", rs)
LET cs = s / 256
DISPLAY SFMT(" s / 256 = %1", cs)
END FUNCTION
$ fglcomp run.4gl && fglrun run
Command: invalid-command
sh: line 1: invalid-command: command not found
RUN RETURNING result:
s = 32512
s MOD 256 = 0
s / 256 = 127
$ fglcomp run.4gl && fglrun run 5
Command: fglrun run child 5
Child: EXIT PROGRAM 5
RUN RETURNING result:
s = 1280
s MOD 256 = 0
s / 256 = 5
GUI rendering of child programs
When starting a new child program in GUI mode, different rendering options can be used to show the application windows.
The windows/forms of each application can be displayed in a common window container or in a dedicated container window container. The window container is a desktop OS window frame with the desktop front-end (GDC), or a web browser tab with the Genero application server (GAS).
For more details, see Containers for program windows.
IN LINE MODE and IN FORM MODE
The IN
clause of the {
LINE|
FORM}
MODERUN
instruction defines how the dumb terminal behaves
when running the child process. This clause has no particular impact on GUI front-ends, but should
be considered when the same program can run in TUI or GUI
mode.
The concept of line mode / form mode comes from the TUI and tty terminal raw mode / cooked mode concept.
No matter if you are in TUI or GUI mode, run silent (batch) programs in form mode, and if the program to run is interactive, or displays messages to the terminal, or if you don't known what it does, use the line mode.
If no LINE/FORM MODE
clause is specified in the RUN
command, it
defaults to the last OPTIONS IN FORM/LINE
MODE
setting, which is by default IN LINE MODE
. However, as many UI
instructions (such as OPTIONS
) take the program into form mode,
typical interactive programs are actually in form mode most of the time (they start in
line mode and after the first UI instruction, they are in form mode)
Executing an interactive Genero program with RUN … IN FORM MODE WITHOUT WAITING
(or with RUN … WITHOUT WAITING
and the FORM MODE
is set by
OPTIONS
), can lead to unexpected behavior.
When the RUN
statement specifies IN FORM MODE
, the program
remains in form mode, if it is currently in form mode, but it does not enter form
mode if it is currently in line mode. When the prevailing RUN
option
specifies IN LINE MODE
, the program remains in line mode if it is currently
in line mode, and it switches to line mode, if it is currently in form mode.
This also applies to the PIPE
option of START REPORT
.
- In TUI mode, the terminal is in the same state (in terms of tty options) as when the program began. Usually the terminal input is in cooked mode, with interrupts enabled and input not becoming available until after a newline character is typed.
- In GUI mode, if the
WITHOUT WAITING
clause in used, the front-end is warned that a new interactive child program is started. If theRUN
command waits for child termination (i.e. noWITHOUT WAITING
clause is used), no particular action is taken by the parent fglrun to warn the front-end, and the new child fglrun will connect to the front-end.
- In TUI mode, the screen stays in form mode, if it was in form mode, which saves a clear / redraw of the screen. The form mode specifies the terminal raw mode, in which each character of input becomes available to the program as it is typed or read.
- In GUI mode, no particular action is taken to warn the front-end (there is no need to warn the front-end for batch program execution).
Besides RUN
, the OPTIONS
, START
REPORT
and START REPORT... TO
PIPE
instructions can explicitly specify a screen mode. With START
REPORT
using PIPE
specifications, the default screen mode is IN
FORM MODE
.
Example
MAIN
DEFINE result SMALLINT
CALL runApplication("app2 -p xxx")
CALL runBatch("ls -l", FALSE) RETURNING result
CALL runBatch("ls -l > /tmp/files", TRUE) RETURNING result
END MAIN
FUNCTION runApplication(pname)
DEFINE pname, cmd STRING
LET cmd = "fglrun " || pname
IF fgl_getenv("FGLGUI") == 0 THEN
RUN cmd
ELSE
RUN cmd WITHOUT WAITING
END IF
END FUNCTION
FUNCTION runBatch(cmd, silent)
DEFINE cmd STRING
DEFINE silent STRING
DEFINE result SMALLINT
IF silent THEN
RUN cmd IN FORM MODE RETURNING result
ELSE
RUN cmd IN LINE MODE RETURNING result
END IF
IF fgl_getenv("OS") MATCHES "Win*" THEN
RETURN result
ELSE
RETURN ( result / 256 )
END IF
END FUNCTION