User Tools

Site Tools


k21:k21.2:start

21.2 Instructions SHELL and EXEC

The following sections present and explain the syntax for the two instructions SHELL and EXEC and provide comparative considerations for these instructions.

21.2.1 Syntax SHELL

There are two variants for the SHELL instruction - a version with many different options and a simple variant to start a process:

[ ProzessVariable = ] SHELL Command [WAIT] [FOR {{READ|INPUT}|{WRITE|OUTPUT}}] [AS PEventName]

Notes:

  • You do not necessarily have to declare a process variable. Only if you use WRITE or OUTPUT is it mandatory.
  • SHELL is the name of the instruction used.
  • Command is a string and describes the shell command with programme name, options, parameters and redirections as well as pipes.
  • The shell command is executed in a system shell and a process object is created.
  • Use WAIT, then the interpreter waits for the process end.
  • FOR READ indicates that the process should be opened for reading. The standard output of the process is redirected to the running Gambas programme. You can alternatively use FOR INPUT.
  • Use FOR WRITE or FOR OUTPUT , if you want to pass user input to the process! The standard input of the process is redirected to the programme.
  • You can also use FOR READ WRITE or FOR INPUT OUTPUT to read the output of the shell command and pass input from the user to the process.
  • FOR INPUT OUTPUT makes the internal stream object work in a line-oriented way. Everything is processed in units of “lines” as is usual in a shell.
  • The FOR READ or FOR INPUT or FOR READ WRITE or FOR INPUT OUTPUT must be followed by 'AS PEventName' as of Gambas 3. PEventName is of type string.
  • The specification 'AS PEventName' declares the process - created with SHELL - as a process to be monitored and provides a symbol for the event monitor of Gambas. The event supervisor calls functions of the programme when a special process event occurs. The function that is triggered is called an event handler. For example, if data is available on the redirected standard output of the process, the event supervisor triggers the event handler PEventName_Read() to handle this event. It could consist of processing the read-in data and outputting the relevant data formatted or changing the programme flow depending on the data. There are two further event handlers for the process: PEventName_Kill() and PEventName_Errror(..). These are triggered when the process has terminated or there is data at the redirected standard error output of the process.

The following calls are correct:

SHELL "firefox www.gambas-buch.de"
SHELL "dmesg | grep ttyS | grep 00: > /tmp/schnittstellenliste.liste" WAIT
SHELL "dmesg | grep ttyUSB >> /tmp/schnittstellenliste.liste" WAIT

Private $hProcess As Process

aCommand = ["ping", "www.fewo-kellermann.de", "-c", "4"]
$hProcess = EXEC aCommand For Read As "myPingProcess"

aCommand = ["wget", "www.gambas-buch.de", "-O-", "--directory-prefix=" & User.Home]
$hProcess = EXEC aCommand For Read As "myProcess"

sCommand = "mysql -f -n -vvv -u root -pYourMySQLPassword4MySQLRoot"
$hProcess = SHELL sCommand For Input Output As "myProcess"

The 2nd syntax (quick syntax) is simple:

SHELL sCommand TO String-Variable   #   sCommand ist ein String

The output of the process started in the background is stored in the (string) variable.

Attention: You have no control over the blocking executed process! If the process could not be started, then you can catch this error.

21.2.2 Syntax EXEC

There are also two variants for the EXEC instruction to start a process:

[ ProzessVariable = ] EXEC Command [WAIT] [FOR {{READ|INPUT}|{WRITE|OUTPUT}}] [AS PEventName]
  • Only the changes from the SHELL instruction are described.
  • Command is an array. The first element in the array, which can also be an inline array, is the name of the command and the other elements are the command parameters - if any were passed.
  • The Exec command is executed directly as an execve() system call and a process object is created, which can be used to control the output of the command as well as necessary input from the user or to detect process errors.

The following calls are correct:

Private $hCommand As Process
$hCommand = Exec [...] For Read Write As "MyCommand"

Second variant of the EXEC instruction:

EXEC aCommand TO String-Variable   #   aCommand ist ein String-Array

If you use the second syntax, the specified Exec command is executed and the interpreter waits for it to finish. Afterwards, the complete output of the process started in the background is written into the specified string variable. Also in this case, the following applies with all consequences: You have no control over the executed process!

21.2.3 Syntax extension - environment variables

You can set environment variables selected for the process to be started to new values by specifying the keyword WITH after the shell or Exec command Cmd, which is followed by an array of environment variable value pairs with Environment:

[Process=] EXEC Cmd WITH Environment …
[Process=] EXEC Cmd WITH Env_Array [WAIT] [FOR {{READ|INPUT}|{WRITE|OUTPUT}}] [AS PEventName]
[Process=] SHELL Cmd WITH Environment …
[Process=] SHELL Cmd WITH Env_Array [WAIT] [FOR {{READ|INPUT}|{WRITE|OUTPUT}}] [AS PEventName]

This call in a console :

hans@linux:~$ LC_ALL=en_GB.utf8 gambas3

can be replicated in a Gambas program to use the SHELL instruction or the EXEC instruction to start Gambas 3 temporarily in the English version, for example:

Public Sub btnStartGambas3EN_Click()
 SHELL "gambas3" With ["LC_ALL=en_GB.utf8"] Wait
 EXEC ["gambas3"] With ["LC_ALL=de_DE.utf8"] Wait ' Alternative: EXEC-Instruktion
End

21.2.4 Comparative considerations of the SHELL and EXEC instructions

Whether you use the SHELL instruction or the EXEC instruction is determined primarily by the task at hand. First, differences between the SHELL and EXEC instructions are described and then similarities are highlighted. This will help you decide more confidently whether to use the SHELL instruction or the EXEC instruction to work successfully.

21.2.4.1 Differences SHELL - EXEC

There is a significant difference in the way the command passed (Command) is executed and in the type of command:

  • For example, SHELL uses the /bin/sh shell and EXEC directly uses the execve system call, which is also why EXEC takes its arguments as an array and SHELL as a string. For details on the system call, see $ man 2 execve in the man pages.
  • The execve system call takes the programme path, argument array and environment variable array and starts the programme accordingly. However, only an external programme can be started in this way.
  • Constructs such as: “prog1; prog2” or “prg1 | prg2” or “program 2>file” are functionalities of a shell and are not available when using EXEC.
  • EXEC is faster, however, because the SHELL instruction must first start a shell, then evaluate the (optionally) passed parameters and only then start the (external) programme.
  • Unlike SHELL, EXEC is an interface to the kernel. This offers fewer possibilities than using a shell, but is much safer - and external programmes can be started with it in any case.

The advantages that are available in a shell speak for the use of the SHELL instruction:

  • substitutions via wildcards like '*.txt' .
  • Redirects and pipes like '> ~/output.txt' or '< ~/input.dat' or ' 2>&1 | command' or similar.
  • Use of special variables such as $HOME or $PATH or $UID or $#.

Quoting

Starting with Gambas 3, you can use the Shell$(shell command string) function to implement a safe passing to the shell so that certain characters in the shell command string are not interpreted by the shell used - in Ubuntu this is '/bin/dash'. For EXEC, masking of selected characters is not necessary. Under the following URL you will find well-prepared information on quoting: http://wiki.ubuntuusers.de/Shell/Bash-Skripting-Guide_für_Anfänger .

21.2.4.2 Similarities SHELL - EXEC

The SHELL instruction and the EXEC instruction both start an external programme - a process is created. Essential properties, methods and events as well as selected constants of the class 'Process' have been described in chapter 21.1. In the following chapter 21.3, the use of the event handlers PEventName_Read(), PEventName_Kill() and PEventName_Error(..) are described first. In order to pass inputs to the process, corresponding procedures are presented for this purpose. These descriptions apply to the two instructions SHELL and EXEC in the same way.

The website uses a temporary session cookie. This technically necessary cookie is deleted when the browser is closed. You can find information on cookies in our privacy policy.
k21/k21.2/start.txt · Last modified: 18.05.2022 (external edit)

Page Tools