Plasma GitLab Archive
Projects Blog Knowledge


Jump to: ‍ ‍OMake Home • Guide Home • Guide (single-page) • Contents (short) • Contents (long)
Index: ‍ ‍All • Variables • Functions • Objects • Targets • Options

Chapter ‍11 Shell commands

11.1 What is considered a shell command?

Syntactically, shell commands are any line starting with

  • The name of an executable, which is looked up along PATH[] if it is not specified with a relative or an absolute path,
  • A builtin, or
  • An alias (see the documentation for the Shell object for more information),

but not one of the following:

  • A variable definition of the form VAR=string,
  • A function call f(...) or method call o.f(...),
  • A rule definition containing a colon string: ..., or
  • A special command, including the following:
    • if ...
    • switch ...
    • match ...
    • section ...
    • return ...

The syntax of shell commands is similar but not identical to the syntax used by the Un*x-shell ‍bash(1).

Note: The syntax and shell usage is identical on all platforms, including Win32. To avoid portability problems on Win32, it is recommended to avoid the use of the native shell interpreter ‍cmd(1).

Commands can be freely mixed with other code, for example

    LIB = $(dir lib)
    println(The contents of the $(LIB) directory is:)
    ls $(LIB)

Every command has an integer exit code, which is zero or some other integer. A command is said to succeed if its exit code is zero. If a command terminates with a non-zero exit code, osh(1) considers the execution to have failed and tells OMake to abort the current process with an error.

11.2 Simple commands

A simple command is specified with the name of an executable optionally followed by arguments passed to this executable. Here are some examples:

    ls
    ls -AF .
    echo Hello world
    /usr/local/bin/cc --version

The command is found using the current search path in the variable ‍PATH[], which should define an array of directories containing the favored executables.

A command may be prefixed by environment variable definitions with the help of the utility ‍env(1).

    # Prints "Hello world"
    env X="Hello world" Y=2 printenv X

    # Pass the include path to the Visual C++
    env include="c:\Program Files\Microsoft SDK\include" cl foo.cpp

11.3 Globbing

Commands may contain wildcard patterns. A pattern specifies a set of files through a limited kind of regular expression. Patterns are expanded before the function is executed.

   # List all files with a .c suffix
   ls *.c

   # List all files with a single character prefix, and .c suffix
   ls ?.c

   # Rename the file hello.ml to foo.ml
   mv {hello,foo}.ml

A comprehensive description of OMake ‍glob patterns is given in Section ‍10.4.

11.4 Background jobs

A command may also be placed in the background by adding an ampersand ‍(&) after the command. Control immediately returns to the shell without waiting for the job to complete. The job continues to run in the background.

    gcc -o hugeprogram *.c &

In osh(1) the ampersand acts command terminator, whereas for bash(1) it is a command separator.

See Section ‍11.11 for some built-in job-control commands.

11.5 Command sequence

Sequence commands by separating them with a semi-colon ‍(;). The commands get executed from left to right. The exit code of the whole sequence is the exit code of the last command executed. The exit codes of all other commands are ignored.

Notes:

  • In osh(1) the semicolon strictly acts as a separator.
  • Each command in a sequence is executed in its own sub-shell.
  • The property of ignoring all but the last command’s exit code can be used to simulate GNU ‍Make’s - ‍command-prefix in recipes.
    # GNU Make: ignore exit code of toposort
    tsort:
            - toposort --in-place ids.list
    
    becomes
    # OMake
    tsort:
            toposort --in-place ids.list; true
    

11.6 File redirection

The input and the output of a command can be redirected from and to files by adding redirection operators after the command.

Redirect input
command < input-file.
Redirect output
command > output-file, command >> output-file. The first form truncates output-file, the second form appends to it.
Redirect output and error messages
command >& output-file, command >>& output-file. Again, the first form truncates output-file and the second form appends to it.

Some examples:

    # Write to the "foo" file
    echo Hello world > foo

    # Redirect input from the foo file
    cat < foo

    # Redirect standard output and errors to the foo file
    gcc -o boo *.c >& foo

11.7 Pipelines

Pipelines are sequences of commands, where the output of the command on the left-hand side of the pipe ‍operator (| and |&) is sent to the input of the command on the right-hand side. With | the output is redirected, but errors are not; with |& both output and errors are redirected. Each command in a pipeline is executed in its own sub-shell.

   # Send the output of the ls command to the printer
   ls *.c | lpr

   # Send output and errors to jyh as email
   gcc -o hugefile *.c |& mail jyh

The pipeline’s exit code is the value of the rightmost command to exit with a non-zero code, or zero if all commands exit successfully. Note that this behavior is different from ordinary command sequences (see Section ‍11.5) and from most other Un*x ‍shells (those which supply pipefail set it to false by default), but desirable inside OMake ‍recipes.

11.8 Conditional execution

Commands may also be composed though conditional evaluation using the || and && syntax. The expression command1 && command2 executes command2 only if command1 succeeds. The expression command1 || command2 executes command2 only if command1 fails.

   # Display the x/y file if possible
   cd x && cat y

   # Run foo.exe, or print an error message
   (test -x foo.exe && foo.exe) || echo "foo.exe is not executable"

11.9 Grouping

Parenthesis are used for grouping in a pipeline or conditional command. The grouped commands are executed in a separate sub-shell.

In the following expression, the test ‍function is used to test whether the foo.exe file is executable. If it is, the foo.exe file is executed. If the file is not executable (or if the foo.exe command fails), the message "foo.exe is not executable" is printed.

   # Run foo.exe, or print an error message
   (test -x foo.exe && foo.exe) || echo "foo.exe is not executable"

Currently osh(1) does not support grouping within the current shell as does Bash with curly braces ‍({}).

11.10 Basic builtin functions

11.10.1 echo

The echo function prints a string.

$(echo <args>)
echo <args>

11.10.2 cd

The cd function changes the current directory.

    cd(dir)
       dir : Dir

The cd function also supports a 2-argument form:

    $(cd dir, e)
       dir : Dir
       e : expression

In the two-argument form, expression e is evaluated in the directory dir. The current directory is not changed otherwise.

The behavior of the cd function can be changed with the CDPATH variable, which specifies a search path for directories. This is normally useful only in the osh command interpreter.

    CDPATH : Dir Sequence

For example, the following will change directory to the first directory ./foo, ~/dir1/foo, ~/dir2/foo.

    CDPATH[] =
       .
       $(HOME)/dir1
       $(HOME)/dir2
    cd foo

11.11 Job control builtin functions

11.11.1 jobs

The jobs function prints a list of jobs.

jobs

11.11.2 bg

The bg function places a job in the background.

bg <pid...>

11.11.3 fg

The fg function brings a job to the foreground.

fg <pid...>

11.11.4 stop

The stop function suspends a job.

stop <pid...>

11.11.5 wait

The wait function waits for a job to finish. If no process identifiers are given, the shell waits for all jobs to complete.

wait <pid...>

11.11.6 kill

The kill function signals a job.

kill [signal] <pid...>

11.12 Command history

11.12.1 history

    $(history-index) : Int
    $(history) : String Sequence
    history-file : File
    history-length : Int

The history variables manage the command-line history in osh. They have no effect in omake.

The history-index variable is the current index into the command-line history. The history variable is the current command-line history.

The history-file variable can be redefined if you want the command-line history to be saved. The default value is ~/.omake/osh_history.

The history-length variable can be redefined to specify the maximum number of lines in the history that you want saved. The default value is 100.

Jump to: ‍ ‍OMake Home • Guide Home • Guide (single-page) • Contents (short) • Contents (long)
Index: ‍ ‍All • Variables • Functions • Objects • Targets • Options
This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml