Gambas Documentation
Application Repository
Code Snippets
Compilation & Installation from source code
Components
Controls pictures
Deprecated components
Developer Documentation
Development Environment Documentation
Documents
About The Best Formula In The World
Architecture details
Benchmarks
Books
By Reference Argument Passing
Compatibility between versions
Creating And Using Libraries
Database Datatype Mapping
Database Request Quoting
Date & time management
Dates and calendars
DBus and Gambas
Differences Between Shell And Exec
Differences From Visual Basic
Distributions & Operating Systems
Drag & Drop
DrawingArea Internal Behaviour
External functions datatype mapping
Frequently Asked Questions
Gambas Farm Server Protocol
Gambas Mailing List Netiquette
Gambas Markdown Syntax
Gambas Naming Conventions
Gambas Object Model
Gambas Scripting
Gambas Server Pages
Gambas Unit Testing
Gambas Wiki Markup Syntax
Getting Started With Gambas
Hall Of Fame
Housekeeping, cleaning up
Image Management In Gambas
Including Help Comments in Source Code
Installation from binary packages
Interpreter limits
Introduction
Just In Time Compiler
Just In Time Compiler (old version)
License
Localisation and Internationalization
Mailing Lists & Forums
Naming Conventions
Network Programming
ODBC Component Documentation
PCRE Pattern Syntax
Porting from Gambas 2 to Gambas 3
Previous News
Project Directory Structure
Release Notes
Reporting a problem, a bug or a crash
Rich Text Syntax
Screenshots
Text highlighting definition file syntax
The Program has stopped unexpectedly by raising signal #11
Variable Naming Convention
WebPage Syntax
Web site home page
What Is Gambas?
Window & Form Management
Window Activation & Deactivation
Window Life Cycle
XML APIs
Error Messages
Gambas Playground
How To's
Language Index
Language Overviews
Last Changes
Lexicon
README
Search the wiki
To Do
Topics
Tutorials
Wiki License
Wiki Manual

Differences Between Shell And Exec

Shell

SHELL invokes /bin/sh (or the shell defined by the System.Shell property), and passes it a single command line.

/bin/sh parses this command line exactly the same way it does in a normal shell. So,

SHELL "ls -l *.o >/tmp/list"

will do exactly the same as if you typed ls -l *.o >/tmp/list in a terminal emulator under a shell. This is a lot of things, because the shell has tremendous power. This command:

  1. Splits the command line into several parts: executable to run, parameters to pass it, other constructs...

  2. Searches for an executable named ls in the PATH environment.

  3. Substitutes *.o with all the .o files in the current directory.

  4. Prepares a redirection (the normal output of /bin/ls is redirected to /tmp/list).

To summarize, the shell can do a lot of things, and the Gambas shell command brings that power to you.

After /bin/sh is done with all this parsing/computing work, it invokes an exec() system call, which loads and executes an executable, passing it a number of parameters.

A program that is executed with the shell procedure will NOT be terminated when the Gambas program is terminated. You must either KILL the process or allow it to run until its normal termination.

Exec

The Gambas EXEC instruction calls the exec() system call, bypassing the shell. This is faster and less memory hungry, because you invoke an external command without invoking /bin/sh, but you lose all the power the shell has.

In fact, if you want to list all the .o files in the current directory and put the result into /tmp/list without using the powerful shell, you have to:

  1. Search by yourself for the files.

  2. Create an array of the names of those files.

  3. Invoke /bin/ls and pass it an array which contains the -l and all the filenames you found.

  4. Redirect its standard output to a file, or use the FOR syntax to get the output directly into a Gambas event handler.

To conclude. If you run an EXEC in gambas, you must simply supply the program name to execute and all its parameters. If you issue:

EXEC ["/bin/ls", "-l", "*.o", ">/tmp/list"]

you will invoke /bin/ls passing it the above parameters. /bin/ls will (correctly) recognize the -l as a switch; but *.o and >/tmp/list will be recognized as files to look for, and no files named *.o will exist. The >/tmp/list is a shell syntax, not a /bin/ls one, and /bin/ls will look again to for file named >/tmp/list.

A program that is executed with the EXEC procedure will be terminated when the Gambas program is terminated.

You can type man sh at the shell prompt; all of what you will read there are shell capabilities, and none of them are available in EXEC. The three most important things which are available in the shell, and not available in EXEC are:

  1. Pattern substitution. .o and the like are shell constructs.

  2. Redirections and pipes. >/foo/bar, </foo/bar, 2>&1 | command and so on.

  3. Variables like $HOME, $PATH and so on.

But EXEC has a good advantage over SHELL. If you have to invoke an external command which has (or can have) unusual characters in the command line, like

firefox http://someserver.com/doit.cgi?name=foo&reply=bar

SHELL (or, better, /bin/sh) will interpret characters like ? and &, while EXEC will not.

So, if you need some shell capability, use SHELL; otherwise use EXEC. Using SHELL saves typing, on the other hand, but ONLY if you are sure that no strange characters (?, &, $, spaces, and others) will appear in the command you are constructing.

In that last case, Gambas has a Shell$ function that quotes these "strange" characters for the SHELL instruction, so that you are sure that any file name can be used with it.

See also