Skip to content
Xi Software

Setting Up and Managing Xi-Batch Command Interpreters

What an interpreter record contains, when a change reaches the scheduler, and why the list is restored before startup

Xi-BatchXi-Batchconfigurationjob-controlschedulerbtcichangebtcilist

You need an interpreter for a language other than the shell, or a job is running under the wrong one. This article covers reading the list, adding and changing entries, what becomes of a job whose interpreter is absent, and how to back the list up.

What a command interpreter is

Every Xi-Batch job runs under a command interpreter: a named entry that records the program the scheduler runs on the job's behalf, the arguments that program is given first, and two defaults a new job inherits. The scheduler pipes the text of the job to that program's standard input, so any program that reads its instructions from standard input can be one.

The entries live in a single file, cifile, in the batch spool directory - by default /var/spool/xi/batch. It holds one fixed-length binary record per interpreter. It is a binary file, and the way to read or change it is through the product's own commands: btcilist, btcichange, and the interpreter screen in btq.

The first entry is the standard shell. It cannot be deleted, and it is what a job falls back to whenever the interpreter it names cannot be found. On a new installation the scheduler creates the file with that one entry:

  • Name: sh
  • Program: the SHELL setting from /etc/xi/batchconfig, which the installation sets to the shell found on the machine, usually /bin/sh
  • Arguments: -s
  • Nice: 24
  • Load level: the batch account's special create load level, 1000 unless it has been changed

When a change takes effect

An interpreter added or altered while the scheduler is running takes effect without a restart and without a signal.

The scheduler opens cifile once, when it starts. After that it re-reads the whole file whenever it has to resolve an interpreter name and the file's modification time has moved on - once for every job it starts, and on every pass over the queue for jobs owned by another host. btcichange and the btq screen write the changed record back into the same file, so the next job to start sees the new value.

Two limits:

The re-read follows the file the scheduler opened, not the path. If cifile is replaced rather than edited - restored from a backup by moving a file into place, or written by any tool that creates a new file and renames it over the old one - the running scheduler and its execution processes go on reading the file they already had, indefinitely, and nothing reports it. Restore through btcichange, or through the script xb-ciconv produces, or stop the scheduler first.

The modification time is recorded to the second. A second change made within the same second as the previous read is not seen until some later change moves the time on again. This shows up only in scripts that make several changes in quick succession.

cifile must be in place before the scheduler starts

The scheduler reads cifile before it reads the saved job file, and it checks every job it loads against the list. A job whose interpreter name is absent at that moment is reassigned to the first entry, keeping its own load level, and the reassignment is saved with the job. Nothing is written to any log.

If cifile is missing, or its length is not a whole number of records, the scheduler recreates it with the single sh entry described above - and then reassigns every job to it.

So on a restore or a migration cifile must be back in place before btstart is run. Putting it back afterwards restores the list but not the jobs' interpreter assignments; those have to be reapplied one job at a time with btjchange -i.

The fields of an entry

Name
How jobs refer to the interpreter, and how it is identified on the command line.

Up to 15 characters, and unique within the file. A longer name given to btcichange -n is truncated without a message.

Program
The full path of the program to run, up to 75 characters. It must begin with a slash: the scheduler runs it directly, no search path applies, and no environment variable or ~ construct is expanded.

The job's script arrives on the program's standard input.

Arguments
A predefined argument list, up to 27 characters in total, placed before any arguments the job itself supplies.

Arguments are separated by white space, and a backslash escapes the next character, so a space or a quote can be carried inside one argument.

-s is the usual value for a shell. It stops the shell treating the job's first argument as the name of a script file.

Load level
The load level given to a job created under this interpreter, in the range 1 to 65535. A user without the special create privilege gets this value and cannot alter it.

See the load levels article for what the number controls.

Nice
A number from 0 to 39; 24 by default.

The scheduler runs at the most favourable priority the system will give it and adds this number, so the value behaves as a position on the traditional 0-to-39 scale on which 20 is an ordinary interactive process. 24 is therefore four steps below interactive, and lower numbers mean higher priority.

The same value is applied to any process the job starts through an input or output redirection.

Argument 0
Off, the default: argument 0 of the interpreter is the interpreter's name, which is what ps shows for the job.

On: argument 0 is the job's title instead, when the job has one. Some programs behave differently when argument 0 differs from their own name.

Expand args
Off, the default: the job's arguments are passed to the interpreter on its command line, and the interpreter's own rules for \$1, \$2 and so on apply inside the script.

On: Xi-Batch substitutes \$1 to \$n, \$* and \$@ in the text of the script as it feeds the script to the interpreter, and the arguments are not placed on the command line at all. This exists for interpreters that have no positional parameters of their own.

Turn it on only for an interpreter that needs it. With it on, the substitution is performed by the scheduler before the job's own identity is applied. Leave it off for a shell: a shell identifies syntax before it expands variables, so pre-substituted quotes and special characters change the meaning of the script.

Listing the interpreters

btcilist prints the list. It takes no arguments and needs no privilege.

btcilist

There is no heading line. The columns are name, program, load level, nice value and predefined arguments, in that order; the load level and nice value are printed in adjacent fixed-width fields. An interpreter with expand args set is marked \$N and one with argument 0 set is marked Set a0.

sh   /bin/sh        1000 24 -s
ksh  /bin/ksh       1000 24 -s
perl /usr/bin/perl  1000 24 -
awk  /usr/bin/awk   1000 24 -f - $N

To see the list held by another host:

btcilist -Q otherhost

In btq, press X from the jobs screen for the same list in editable form, and q to return.

Adding, changing and deleting from the command line

btcichange creates, alters and deletes entries. The interpreter's name is always the last argument, and only one interpreter can be operated on at a time. The command requires the special create privilege; without it the command exits with

You need "special create" permission to update command
interpreters - sorry.
Option Effect
-A, --add Add the named interpreter. -p is required with it.
-D, --delete Delete the named interpreter.
-U, --update Change the named interpreter. This is what happens if none of the three is given.
-N n, --nice n Nice value, 0 to 39.
-L n, --load-level n Load level, 1 to 65535.
-p /path, --path /path Program path. It must start with a slash.
-a string, --args string Predefined arguments, replacing any already set. An empty string clears them; a lone colon cancels the option instead, leaving the existing arguments alone.
-n name, --new-name name Rename an existing interpreter. Meaningful only with -U.
-t, --set-arg0-title Argument 0 becomes the job title.
-i, --set-arg0-name Argument 0 is the interpreter name. This is the default.
-e, --expand-args Xi-Batch substitutes the job's arguments into the script.
-u, --no-expand-args The interpreter deals with its own arguments. This is the default.
-?, --explain Print the option summary and exit.

Add a Korn shell interpreter:

btcichange -A -p /bin/ksh -a "-s" ksh

With an explicit load level and nice value:

btcichange -A -N 25 -L 1500 -p /bin/ksh -a "-s" ksh

Change an existing one:

btcichange -L 1500 sh
btcichange -N 20 sh
btcichange -a "-s --" sh

Rename one:

btcichange -n korn ksh

Delete one:

btcichange -D old_interp

What btcichange accepts without checking:

  • It does not verify that the program path exists or is executable. A wrong path is accepted, and the failure appears only when a job tries to run.
  • A path that does not start with a slash is discarded rather than rejected. On an add the command then stops with "no path name set for new command interpreter"; on an update the option is ignored and the existing path is left alone.
  • It does not check whether any job is using an interpreter before deleting it. The btq screen does.
  • Renaming does not find or update jobs that refer to the old name. Those jobs are then in the position described under "What happens when the interpreter is not there".
  • The first entry cannot be deleted: "you cannot delete the default shell name."

If -L is omitted on an add, the new interpreter takes the load level from the special create load level in the profile of the user running the command, which btulist shows as Specll. If -N is omitted it takes 24.

Editing the list in btq

Press X from the jobs screen. The keys on that screen are:

  • A - add a new interpreter (it prompts for the name, then the path)
  • D - delete the one under the cursor
  • N - change the name
  • P - change the program path
  • a - change the predefined arguments
  • L - change the load level
  • n - change the nice value
  • 0 (zero) - toggle argument 0
  • E - toggle expand args
  • j k - move down and up, or use the arrow keys
  • ? - help, q - leave the screen

Every change is written to the file as it is made; there is no separate save step and no way to abandon a set of edits. Without the special create privilege the screen is read-only and any change key reports a permission error.

btq checks a path more thoroughly than the command line does: it must be absolute, must exist, must be a regular file, and must be executable by somebody. btq also refuses to delete an interpreter that a queued job is using.

How a job gets its interpreter

At submission:

btr -i ksh script.ksh

On a job already in the queue:

btjchange -i ksh <job_number>

Or in btq, select the job on the jobs screen and press x.

A job submitted without -i gets the first entry in the list and that entry's load level.

Order matters on the command line. -i sets the job's load level from the interpreter, so a -l given before -i is overwritten by it. Where a job needs both, put -l after -i:

btr -i heavy -l 5000 process-warehouse.sh

An unknown name is refused when the job is submitted or changed:

btr: Unknown command interp `nosuch'

What happens when the interpreter is not there

Four different things, depending on when the name is resolved.

At submission or change
The command is refused with the message above and the job is unchanged.

When the scheduler starts
Every job naming an interpreter that is not in cifile is reassigned to the first entry, keeping its own load level, with nothing written to any log.

When a local job runs
The job is selected normally, and the execution process cannot resolve the name. It exits with status 248 before the job's own output and error files are created, so nothing is written anywhere. The job is recorded as an error - progress Err - and, if it is a repeating job, it stays in that state and never runs again until btjchange -N resets its progress code.

When a job owned by another host is considered
The scheduler checks the interpreter name against its own list on every pass and skips the job if it is absent. Nothing is displayed and nothing is logged; the job never starts here.

Check what still refers to an interpreter before deleting it:

btjlist -N -F "%N|%I" | grep '|old_interp$'

Shell interpreters

The -s argument stops a shell treating the job's first argument as a script file name; it is wanted on all three.

btcichange -A -p /bin/sh  -a "-s" sh_alt
btcichange -A -p /bin/ksh -a "-s" ksh
btcichange -A -p /bin/csh -a "-s" csh

The program path differs between platforms - /usr/bin/ksh on some systems, /bin/ksh on others - so check the path on the machine before adding the entry.

Interpreters other than shells

Perl reads its program from standard input when the file argument is a single minus sign, and passes anything after that to the script:

btcichange -A -p /usr/bin/perl -a "-" perl
btr -i perl process.pl

awk reads its program from standard input with -f -, leaving the job's arguments as its data files:

btcichange -A -p /usr/bin/awk -a "-f -" awk
btr -i awk -a datafile getxi.awk

Any other program that reads instructions from standard input can be set up the same way. The one thing to establish first is how the program is told to read standard input, because that is what goes in the predefined arguments.

Several entries for one program

The same program may appear in more than one entry, with different nice values or different load levels. This is the mechanism for classifying work, because a user without the special create privilege takes the interpreter's load level and cannot override it.

btcichange -A -p /bin/sh -a "-s" -N 30 -L 1000 sh_low
btcichange -A -p /bin/sh -a "-s" -N 10 -L 1000 sh_high
btcichange -A -p /bin/sh -a "-s" -L 500  light
btcichange -A -p /bin/sh -a "-s" -L 5000 heavy
btr -i sh_low  cleanup.sh
btr -i sh_high urgent.sh
btr -i light   generate-report.sh
btr -i heavy   process-warehouse.sh

The load levels article covers what the numbers should be. Those above are placeholders.

Wrapper interpreters

A shell script that reads the job on its standard input, does something with it and hands it on is a legitimate entry, and is how sites add logging or a dry-run mode.

A wrapper is executed under the identity of the job's owner for every job that names it, so:

  • Put it in a directory that only administrators can write to - /usr/local/bin rather than a shared or group-writable working directory.
  • Own it as root or as the batch account and leave it not writable by group or other. Anyone who can rewrite the file controls what every job using that interpreter runs.
  • Give the entry a path under that directory rather than a path that resolves through a symbolic link somebody else can replace.
  • Have it pass the job's exit status through unchanged, or every job under it will be recorded as having succeeded.

The privilege to add or change an interpreter is special create, and the same privilege lets a user set a job's load level directly. Grant it to administrators only, and review the list periodically - btcilist shows every entry and its program path in one screen.

Backing up and restoring the list

cifile is a binary file and is not portable between machines. The supported way to capture it is xb-ciconv, which reads the file and writes a shell script of btcichange commands that recreates the entries:

xb-ciconv -D /var/spool/xi/batch cifile cifile.sh

The script it produces needs the special create privilege to run, and because it works through btcichange it can be run against a scheduler that is already up. That is the route to prefer over copying the binary file back, for the reason given under "When a change takes effect".

Checking a new entry

The name is the only thing a job records, and it is what appears in a listing: sh, ksh, perl, reports, updates. Each entry is another name that has to exist on every machine a job might run on, so add one when it carries a different program, nice value or load level.

Run one job of its own against a new interpreter before pointing production work at it:

btr -i new_interp test.sh

A job owned by another host is skipped, with nothing displayed, where the interpreter it names is absent here, so use the same names on every machine in a network. Keep an xb-ciconv script with the rest of the system configuration, outside the spool directory.

Running Xi-Batch on Solaris, AIX and HP-UX

Command-interpreter paths, the standard shell, accounts, service ports and startup on the non-Linux platforms

Controlling the Xi-Batch Job Start Rate with STARTLIM and STARTWAIT

Two settings that bound how many jobs the scheduler starts at once, where they live, and why a change needs a restart

Reinitialising the Xi-Batch Scheduler

Discarding the saved job queue and variables safely - which files to remove, and which you cannot get back

All articles · Release notes · Contact support