GNU macro processor - 12. Running UNIX commands

Go to the first, previous, next, last section, table of contents.

# 12. Running UNIX commands

There are a few builtin macros in `m4` that allow you to run UNIX commands from within `m4`.

## 12.1 Executing simple commands

Any shell command can be executed, using `syscmd`:

    syscmd(shell-command)

which executes shell-command as a shell command.

The expansion of `syscmd` is void, not the output from shell-command! Output or error messages from shell-command are not read by `m4`. See section 12.2 Reading the output of commands if you need to process the command output.

Prior to executing the command, `m4` flushes its output buffers. The default standard input, output and error of shell-command are the same as those of `m4`.

The builtin macro `syscmd` is recognized only when given arguments.

## 12.2 Reading the output of commands

If you want `m4` to read the output of a UNIX command, use `esyscmd`:

    esyscmd(shell-command)

which expands to the standard output of the shell command shell-command.

Prior to executing the command, `m4` flushes its output buffers. The default standard input and error output of shell-command are the same as those of `m4`. The error output of shell-command is not a part of the expansion: it will appear along with the error output of `m4`.

Assume you are positioned into the ``checks'` directory of GNU `m4` distribution, then:

    define(`vice', `esyscmd(grep Vice ../COPYING)')
    =>
    vice
    =>  Ty Coon, President of Vice
    =>

Note how the expansion of `esyscmd` has a trailing newline.

The builtin macro `esyscmd` is recognized only when given arguments.

## 12.3 Exit codes

To see whether a shell command succeeded, use `sysval`:

    sysval

which expands to the exit status of the last shell command run with `syscmd` or `esyscmd`.

    syscmd(`false')
    =>
    ifelse(sysval, 0, zero, non-zero)
    =>non-zero
    syscmd(`true')
    =>
    sysval
    =>0

## 12.4 Making names for temporary files

Commands specified to `syscmd` or `esyscmd` might need a temporary file, for output or for some other purpose. There is a builtin macro, `maketemp`, for making temporary file names:

    maketemp(template)

which expands to a name of a non-existent file, made from the string template, which should end with the string ``XXXXXX'`. The six `X`'s are then replaced, usually with something that includes the process id of the `m4` process, in order to make the filename unique.

    maketemp(`/tmp/fooXXXXXX')
    =>/tmp/fooa07346
    maketemp(`/tmp/fooXXXXXX')
    =>/tmp/fooa07346

As seen in the example, several calls of `maketemp` might expand to the same string, since the selection criteria is whether the file exists or not. If a file has not been created before the next call, the two macro calls might expand to the same name.

The builtin macro `maketemp` is recognized only when given arguments.

Go to the first, previous, next, last section, table of contents.