Shell Variables

We need some shell variables, environment variables, etc. set up when we start. For some of these, notably, environment variables, we should be good to go as we pick up on, duh, the values in our environment noting there are possibly some that we require. We can’t assume there is a PATH, for example.

Just out of interest let’s give bash an empty environment and then get it to print out its (created) environment:

$ env - bash -c env
PWD=/home/idf
SHLVL=0
_=/usr/bin/env

Hmm, less than I thought. Not even an exported PATH. Interesting. Of course, if we print out the shell variables with set, it’s something more expected:

$ env - bash -c set
BASH=/usr/bin/bash
...
IFS=$' \t\n'
PATH=/usr/local/bin:/usr/bin
PWD=/home/idf
SHELL=/bin/bash
...

Hmm, what are the semantics of process behaviour, here, with regard to environment variables? Should we intervene or be invisible?

Another consideration is how we choose to intervene. We have a model which uses distinct dynamic and environ variables. Can we switch between the two? (Currently, no!)

*

There’s also a subtlety regarding whether arguments are for us, Idio, or the script we are intending to run.

Problems, problems!

main

In C, of course, we are given argc and argv. We’re going to follow in the style of Bash and propose:

.../idio [Idio-args] [script-name [script-args]]

where arguments to Idio must come before any script name or arguments to the script as, both in essence and in practice, the first argument that isn’t recognised as an Idio argument will be treated as the name of a script. --hlep beware!

Another, slightly less obvious, issue is that there is no mechanism to load multiple libraries/scripts in one as I had been doing until “normalizing” argument handling. .../idio test test would run the test suite twice.

Of course, this merely forces us to implement a --load name argument so nothing ostensibly difficult there. Except we need to be cautious about handling any errors.

Variables

What variables, in addition to a potential IDIOLIB (see Where Are We?), should we be looking at creating? There’s potential complications here between “shell” and environment variables and what POSIX thinks of them.

Here, we’re don’t particular feel bound by POSIX but we do want to be good neighbours. We might be able to handle environment variable names with “non-portable” characters in them, notably hyphens -, U+002D (HYPHEN-MINUS), but other users of the environment might not.

POSIX’s list of “avoid conflict with” environment variables is somewhat dubious appearing to be someone typing env | sort and dumping it in the specification. RANDOM and SECONDS are environment variables?

*

From our declaration of argument handling we should be able to derive:

SHELL

(environment variable)

I originally had this down as the full pathname of .../idio however POSIX thinks of it as the user’s preferred command interpreter

Bash says:

expands to the full pathname to the shell. If it is not set when the shell starts, bash assigns to it the full pathname of the current user’s login shell.

Do as Bash does!

IDIO_CMD

(shell variable)

This is argv[0] as Idio sees it. It probably isn’t useful but maybe someone wants to know how the command was invoked.

IDIO_EXE

(shell variable)

This is the kernel or argv[0] derived full pathname of the running executable.

I see Bash has both:

  • _ being variously the “pathname used to invoke the shell or shell script being executed” – before becoming other things

  • BASH being “the full filename used to invoke this instance of bash”

ARGV0

(shell variable)

This is either the name of the running script or is identical to IDIO_CMD.

This is more similar to Bash’s $0 (and BASH_ARGV0) which is the name of the shell script or shell if running interactively.

ARGC

(shell variable)

This is the number of arguments to the script.

Clearly, if no arguments are passed to the script then ARGC is 0. What if no script is being run, ie. we are in an interactive shell? Arguably, ARGC should be 0 again but currently it is -1 to distinguish that case.

ARGV

(shell variable)

This is the arguments to the script.

IDIOLIB

(environment variable)

calculated as described above

*

Other values can be calculated and some are computed.

Note

Most of the following are actually defined in src/libc-wrap.c as they interact with the C standard library.

GROUPS

(shell variable)

type:

array of libc/gid_t

An array of the current user’s supplementary group IDs as given by getgroups(2).

HOME

(environment variable)

the current user’s home directory

HOSTNAME

(shell variable)

the nodename field of a struct utsname from uname(3)

See also libc/idio-uname.

IDIO_PID

(shell variable)

type:

libc/pid_t

the result of getpid(2)

This value is not updated, see PID.

IFS

(dynamic variable)

I’ve always called this the Input Field Separator, after awk, but I see I am completely wrong. awk never(?) had an IFS but only an FS which was “blank and tab” but separately has RS the (input) Record Separator which is the newline you expect.

Bash merged FS and RS into IFS (Internal Field Separator) partly, I suppose, as it meant a single value would be used to split the entire multi-line output from Command Substitution whereas awk would be expecting to (generally) process line by line.

awk does have distinct OFS and ORS when outputting whereas Bash uses the first character of IFS in various expansion rules.

There’s no such output mangling in Idio – we’d need to figure out something similar to Interpolated Strings – so we’ll hold off there.

In the meanwhile, we can use the standard SPACE TAB NEWLINE for IFS.

Notice IFS is a dynamic variable meaning you can redefine it for the duration of a block (rather than redefine it for everyone globally).

PID

(shell variable)

type:

libc/pid_t

the result of getpid(2)

This value is updated when Idio forks. Compare with IDIO_PID.

PPID

(shell variable; POSIX says environment variable)

type:

libc/pid_t

the result of getppid(2)

This value is updated when Idio forks.

PWD

(environment variable)

type:

libc/pid_t

the result of getppid(2)

Computed Variables

UID

(shell variable)

type:

libc/uid_t

  • accessing calls getuid(2)

  • setting calls setuid(2)

EUID

(shell variable)

type:

libc/uid_t

  • accessing calls geteuid(2)

  • setting calls seteuid(2)

GID

(shell variable)

type:

libc/gid_t

  • accessing calls getgid(2)

  • setting calls setgid(2)

EGID

(shell variable)

type:

libc/gid_t

  • accessing calls getegid(2)

  • setting calls setegid(2)

SECONDS

(shell variable)

type:

integer

The number of seconds since the VM was started.

Note

There is no set method for this variable.

Last built at 2024-09-07T06:11:26Z+0000 from 463152b (dev)