21.3.1 Using Quick-Syntax

The simplest way to read data from a process is to use the short form of the SHELL or EXEC instruction - called quick syntax:

SHELL sCommand TO (String-)Variable		# sCommand ist ein String
EXEC  aCommand TO (String-)Variable		# aCommand ist ein (String-)Array

If you use the quick syntax, the specified command Command is executed and the interpreter waits for it to finish! Afterwards, the complete output of the data is written into the specified (string) variable - as long as no process error (!) occurred.

Example 1:

Public Sub btnExecuteInstruktion_Click()
  EXEC ["pstree", "-p"] TO TextArea.Text
End

The complete output of the process tree is displayed in a TextArea. It could hardly be quicker and more elegant.

If the process could not be started - instead of pstree, for example, there is only pstre - then you receive the error message “Cannot run child process: cannot exec program …” in the IDE. You can catch such a (start) error in the programme like this:

Public Sub btnExecuteInstruktion_Click()
  TextArea1.Clear
  Try Exec ["pstree", "-p"] TO TextArea1.Text
  If Error Then
     Message.Error("Error while executing the command!")
     Return
  Endif
End

Example 2:

It is only to be checked from a Gambas programme whether the compilation of a certain Gambas project was successful or whether an error occurred during compilation:

Public Sub btnExecuteInstruktion_Click()
  Dim sOutput As String
 
  Shell "gbc3 $HOME/color_select 2>/dev/null || echo $?" TO sOutput
 
  If Upper(Left(sOutput, 2)) <> "OK" Then
     Message.Error("An error occurred during compilation!")
  Else
     Message.Info("The compilation was successful!")
  Endif
 
End

As outputs you can expect the 'OK' from the standard output if the compilation was successful or a return value ≥ 1 in case of an error of the program 'gbc3' via the bash variable $? The standard error output was redirected into electronic nirvana in this example. If you only want to catch and display an error, dispense with the else branch.

Example 3 - Project

Example 3 presents a complete project for Quick-Syntax. The external programme is 'ping', with which you measure the signal runtimes for a certain server. Under 'man ping' or 'info ping' or 'ping -help' you will find interesting details about the console programme ping. The URL is freely selectable. The number of pings has been fixed at 4 and cannot be changed. In the Gambas programme, the quick syntax for SHELL and EXEC has been used. An LED signals the programme status or that of the started process, in which you cannot intervene!

GUI 'ping'
Figure 21.3.1.1: GUI for the 'ping' programme

Source code:

' Gambas class file
 
Private sProgrammName As String = "ping"
 
Public Sub Form_Open()
  FMain.Center
  FMain.Resizable = False
  SetLEDColor("orange")
End
 
Public Sub btnPingOverShell_Click()
  Dim sAusgabe, sCommand As String
 
  SetLEDColor("green")
  TextArea.Clear
  Wait
  FMain.Mouse = Mouse.Wait
 
  sCommand = sProgrammName & Chr(32) & TextBox1.Text & " -c 4"
  Shell sCommand To TextArea.Text
 
  FMain.Mouse = Mouse.Default
  SetLEDColor("orange")
 
End
 
Public Sub btnPingOverExec_Click()
 Dim sAusgabe As String
 Dim aCommand As New String[]
 
  SetLEDColor("green")
  TextArea.Clear
  Wait
  FMain.Mouse = Mouse.Wait
 
  aCommand = [sProgrammName, TextBox1.Text, "-c", "4"] '-- Inline-Array
  Exec aCommand To sAusgabe
 
  TextArea.Insert(gb.NewLine & sAusgabe)
  FMain.Mouse = Mouse.Default
  SetLEDColor("orange")
 
End
 
Public Sub SetLEDColor(sLEDColor As String)
  PictureBox1.Picture = Picture["LED/led_" & sLEDColor & ".svg"]
End
 
Public Sub btnClose_Click()
  FMain.Close()
End

Comments:

In the following example, on the other hand, the output is extensively processed to provide the content for a ComboBox in the main programme:

PUBLIC SUB RS232ListeGenerieren()
  DIM iCount AS Integer
  DIM sZeile, sListeV24, sListeUSB, s AS String
  DIM aSchnittstellenMatrix AS NEW String[]
  DIM aListe AS NEW String[]
 
  cmbRS232PortName.Clear() '-- Delete ComboBox content
 
'-- Ermittlung echter RS232-Schnittstellen
  SHELL "dmesg | grep ttyS | grep 00:" TO sListeV24
  IF Len(sListeV24) > 0 THEN
     aSchnittstellenMatrix = Split(sListeV24, " ")
     FOR EACH sZeile IN aSchnittstellenMatrix
         IF InStr(sZeile, "ttyS") THEN
            cmbRS232PortName.Add("/dev/" & Trim$(sZeile))
         ENDIF
     NEXT
  ENDIF
 
'-- Determining the USB-RS232 adapter interfaces
  SHELL "dmesg | grep ttyUSB" TO sListeUSB
  IF Len(sListeUSB) > 0 THEN
     aSchnittstellenMatrix = Split(sListeUSB, "\n")
     FOR EACH sZeile IN aSchnittstellenMatrix
         FOR iCount = 0 TO 7
             IF InStr(sZeile, "ttyUSB" & CInt(iCount)) THEN
                aListe.Add("ttyUSB" & CInt(iCount))
             ENDIF
         NEXT
     NEXT
  ENDIF
 
  aListe.Sort
  aListe = RemoveMultiple(aListe)
 
  FOR iCount = 0 TO aListe.Max
      PRINT aListe[iCount]
      cmbRS232PortName.Add("/dev/" & Trim$(aListe[iCount]))
  NEXT ' iCount
 
  IF cmbRS232PortName.Count = 0
     cmbRS232PortName.Background = Color.RGB(255, 191, 191)
     cmbRS232PortName.Add("No RS232 interface found!")
  ENDIF
END
 
PUBLIC FUNCTION RemoveMultiple(aStringListe AS String[]) AS String[]
 
  DIM iCount AS Integer
  DIM iIndex AS Integer
  DIM sElement AS String
 
  iIndex = 0
  WHILE iIndex < aStringListe.Count
  iCount = 0
    sElement = aStringListe[iIndex]
    WHILE aStringListe.Find(sElement) <> -1
      INC iCount
      aStringListe.Remove(aStringListe.Find(sElement))
    WEND
    IF iCount MOD 2 = 1 THEN
       aStringListe.Add(sElement, iIndex)
       INC iIndex
    ENDIF
  WEND
 
  RETURN aStringListe
 
END

Download