System and processes
Single-page view · as markdown
System and processes
Peios / Using Peios / Peiosutils / System and processes
This topic gathers the commands that deal with the running system rather than with files: reading the time, asking what hardware and system you are on, launching another command under some constraint, signalling a process, working with the terminal.
The commands #
Time
| Command | Purpose |
|---|---|
date | Print — or set — the system date and time. |
sleep | Pause for a given length of time. |
uptime | Show how long the system has been running. |
Running a command under a constraint
| Command | Purpose |
|---|---|
timeout | Run a command, and kill it if it runs too long. |
nohup | Run a command so it survives the terminal closing. |
nice | Run a command at an adjusted scheduling priority. |
stdbuf | Run a command with altered stream buffering. |
chroot | Run a command with a different directory as its root. |
Signalling processes
| Command | Purpose |
|---|---|
kill | Send a signal to a process. |
System identity and capacity
| Command | Purpose |
|---|---|
uname | Print system information — the OS, the kernel, the machine. |
arch | Print the machine's hardware architecture. |
hostname | Display — or set — the system's host name. |
hostid | Print the host's numeric identifier. |
nproc | Print how many processor cores are available. |
Who you are
| Command | Purpose |
|---|---|
whoami | Print the name of the user a process is running as. |
id | Print the user and group identity of a process, or of a named user. |
groups | Print the groups a user belongs to. |
logname | Print the login name of the user a process is running as. |
These report the projection of a token onto POSIX user and group numbers, which is what Linux programs see. The numbers grant nothing on their own — id explains what they can and cannot say, and token shows the identity underneath them.
Storage and terminal
| Command | Purpose |
|---|---|
sync | Flush cached writes out to persistent storage. |
tty | Print the name of the terminal on standard input. |
stty | Display or change terminal settings. |
A note on changing the system #
Most commands here only report. A few can change the running system — date can set the clock, hostname can set the host name. Changing system-wide state is a privileged operation: it succeeds only for a caller whose token holds the right to do it, and is refused otherwise. The pages for those commands say so where it applies, and Privileges is the full picture.
Where to start #
uname answers "what am I running on?". kill is the one to read carefully — sending the wrong signal to the wrong process is a quick way to lose work.
date
Peios / Using Peios / Peiosutils / System and processes
date prints the current date and time. With the right option, it can also set the system clock, display some other moment, or format a date however you need.
date [options] [+format]
$ date
Sun 17 May 2026 14:32:08 BST
$ date +%Y-%m-%d
2026-05-17
Formatting the output #
A +format argument controls the output. The format string is printed literally, except for % sequences, each of which is replaced by a piece of the date. The common ones:
| Sequence | Is replaced by |
|---|---|
%Y %m %d | Year, month, day. |
%H %M %S | Hour, minute, second. |
%F | The full date — same as %Y-%m-%d. |
%T | The time — same as %H:%M:%S. |
%A %a | Weekday name, full and abbreviated. |
%B %b | Month name, full and abbreviated. |
%j | Day of the year. |
%s | Seconds since 1970-01-01 UTC. |
%z %Z | Numeric and named time zone. |
%% | A literal %. |
The full set is long; date --help lists every sequence with an example.
Displaying a different moment #
| Option | Effect |
|---|---|
-d, --date=STRING | Show the time described by STRING — "yesterday", "next Friday", "@1615432800" — instead of now. |
-r, --reference=FILE | Show FILE's last modification time. |
-f, --file=DATEFILE | Like -d, but once for each line of DATEFILE. |
-u, --universal | Work in Coordinated Universal Time (UTC) rather than the local zone. |
Standard formats #
| Option | Output |
|---|---|
-I, --iso-8601[=FMT] | ISO 8601 — FMT is date, hours, minutes, seconds, or ns. |
-R, --rfc-email | The format used in email headers. |
--rfc-3339=FMT | RFC 3339 — FMT is date, seconds, or ns. |
Setting the clock #
| Option | Effect |
|---|---|
-s, --set=STRING | Set the system clock to the time described by STRING. |
Setting the clock changes state for the whole system, so it is a privileged operation — it succeeds only for a caller whose token carries the right to set the time, and is refused otherwise. See Privileges.
Exit status #
| Code | Meaning |
|---|---|
0 | The date was printed or set. |
1 | An invalid date or format, or the clock could not be set. |
sleep
Peios / Using Peios / Peiosutils / System and processes
sleep does nothing for a given length of time, then exits.
sleep number[suffix]...
$ sleep 5 # pause for five seconds
$ sleep 1.5h # pause for an hour and a half
It is used to space things out — a pause between the steps of a script, a delay before a retry.
Specifying the duration #
number may be a whole number or a fraction. A suffix gives the unit:
| Suffix | Unit |
|---|---|
s | Seconds. This is the default if no suffix is given. |
m | Minutes. |
h | Hours. |
d | Days. |
Given more than one argument, sleep waits for the sum of them — sleep 1m 30s pauses for ninety seconds.
Exit status #
| Code | Meaning |
|---|---|
0 | The full time elapsed. |
1 | A bad argument, or sleep was interrupted before the time was up. |
timeout
Peios / Using Peios / Peiosutils / System and processes
timeout runs a command with a time limit. If the command finishes in time, nothing special happens. If it is still running when the limit is reached, timeout kills it.
timeout [options] duration command...
$ timeout 30s slow-fetch https://example.com
It is the guard against a command that might hang — a network fetch, a script that could loop forever.
The duration #
duration is a number with an optional unit suffix: s for seconds (the default), m for minutes, h for hours, d for days. A duration of 0 disables the limit.
How the command is stopped #
When the limit is reached, timeout sends the command a TERM signal — a request to shut down cleanly. A well-behaved command stops there. A command that ignores TERM keeps running, which is what -k is for.
| Option | Effect |
|---|---|
-s, --signal=SIGNAL | Send SIGNAL instead of TERM when the limit is reached. |
-k, --kill-after=DURATION | If the command is still running DURATION after the first signal, send it a KILL signal — which cannot be ignored. |
--preserve-status | Exit with the command's own status even when it timed out. |
--foreground | Allow the command to keep reading from the terminal; do not time out the command's own children. |
-v, --verbose | Report to standard error whenever a signal is sent. |
Exit status #
timeout passes through the command's exit status when the command finishes on its own. Otherwise:
| Code | Meaning |
|---|---|
| (command's own) | The command finished within the limit. |
124 | The command timed out. |
125 | timeout itself failed. |
126 | The command was found but could not be run. |
127 | The command was not found. |
137 | The command was ended by a KILL signal. |
nohup
Peios / Using Peios / Peiosutils / System and processes
nohup runs a command so that it survives the terminal closing. Normally, when a terminal session ends, the system sends a hangup signal to the commands running under it, and they stop. A command started with nohup ignores that signal and keeps running.
nohup [options] command [arg]...
$ nohup long-build &
It is how you start something that needs to outlast your session — a long build, a background job — without it being killed the moment you disconnect.
Where the output goes #
A command run with nohup is meant to outlive the terminal, so nohup cannot leave its streams attached to one. It redirects any stream that is still connected to a terminal:
- Standard input, if it is a terminal, is replaced with an empty source — the command reads nothing.
- Standard output, if it is a terminal, is appended to a file named
nohup.outin the current directory. If that file cannot be opened there,nohupfalls back tonohup.outin your home directory. - Standard error, if it is a terminal, is sent to wherever standard output now goes.
Streams that you have already redirected yourself — to a file, or a pipe — are left as they are.
How nohup.out is secured #
When nohup has to create nohup.out, that file is a new file and needs a security descriptor. nohup does not let it inherit one from the directory. It creates nohup.out with a deliberate, locked descriptor: full access for the owner, and no one else.
The reasoning is that nohup.out captures whatever the command writes, which the person running it has not chosen to share. A file that appears as a side effect should not be more open than its creator intended — so nohup gives it the safe default of owner-only, rather than whatever the surrounding directory would have handed down.
| Option | Effect |
|---|---|
--sddl=SDDL | Create nohup.out with the security descriptor given as an SDDL string, instead of the owner-only default. |
--sddl only matters when nohup actually creates the file. If nohup.out already exists, nohup appends to it and leaves its existing security alone.
Exit status #
When nohup runs a command, it exits with that command's status once it finishes. The exception is a failure in nohup itself:
| Code | Meaning |
|---|---|
| (command's own) | The command ran; this is its exit status. |
125 | nohup could not set things up — it could not detach from the terminal, or could not open nohup.out anywhere. The command was not run. |
nice
Peios / Using Peios / Peiosutils / System and processes
nice runs a command at an adjusted scheduling priority — making it more, or less, willing to give the processor up to other work.
nice [options] [command [arg]...]
$ nice -n 15 big-batch-job
With no command, nice prints the current niceness.
Niceness #
A process has a niceness — a number from -20 to 19:
- A high niceness (toward 19) means the process is "nicer" to others — it yields the processor readily. Good for background work that should not get in the way.
- A low niceness (toward -20) means the process is favoured — it gets the processor more often.
By default nice adds 10 to the niceness, making the command run in the background more gracefully.
| Option | Effect |
|---|---|
-n, --adjustment=N | Add N to the niceness instead of 10. N may be negative. |
Raising a command's niceness — running it lower priority — is always allowed. Lowering the niceness, to claim a higher priority than normal, is a privileged request and may be refused; when it is, nice warns and runs the command at the priority it was permitted.
Exit status #
When nice runs a command, it exits with that command's status. The exception is a failure in nice itself:
| Code | Meaning |
|---|---|
| (command's own) | The command ran; this is its exit status. |
0 | No command was given; the niceness was printed. |
125 | nice itself failed — for example, a bad adjustment value. |
126 | The command was found but could not be run. |
127 | The command was not found. |
kill
Peios / Using Peios / Peiosutils / System and processes
kill sends a signal to a process. Despite the name, a signal is not always fatal — it is a message, and some signals ask a process to do something other than stop.
kill [options] pid...
$ kill 4821 # ask process 4821 to terminate
$ kill -KILL 4821 # force it to stop
A pid is a process identifier — the number a running process is known by.
Signals #
With no option, kill sends TERM — a polite request to shut down, which a well-behaved process honours by cleaning up and exiting. The signals you will use most:
| Signal | Meaning |
|---|---|
TERM | Terminate. The default — a request to stop cleanly. |
KILL | Stop immediately. Cannot be caught or ignored, so it cannot be refused — but the process gets no chance to clean up. The last resort. |
HUP | Hang up. Conventionally tells a long-running service to reload its configuration. |
INT | Interrupt — the signal a terminal sends on Ctrl-C. |
STOP / CONT | Suspend the process / resume a suspended one. |
| Option | Effect |
|---|---|
-s, --signal=SIGNAL | Send SIGNAL instead of TERM. |
-SIGNAL | A shorthand — -KILL or -9 both send KILL. |
-l, --list | List the signal names. |
-L, --table | List the signals as a table of numbers and names. |
Use KILL only when TERM has failed. A process killed outright cannot save its work or release what it holds.
Exit status #
| Code | Meaning |
|---|---|
0 | Every signal was sent. |
1 | A signal could not be sent — a process that does not exist, or one you are not permitted to signal. |
uname
Peios / Using Peios / Peiosutils / System and processes
uname prints information about the system you are running on.
uname [options]
$ uname
Peios
$ uname -a
Peios host-01 1.4.0 #1 SMP 2026-05-10 x86_64 Peios
With no option, uname prints the operating-system name — Peios.
What each option prints #
| Option | Prints |
|---|---|
-s | The kernel name. |
-o | The operating-system name — Peios. |
-n | The node name — the name this system is known by on the network. |
-r | The kernel release. |
-v | The kernel version. |
-m | The machine's hardware name (its architecture). |
-p | The processor type. |
-i | The hardware platform. |
-a | Everything — equivalent to -mnrsvo. |
Give several options and uname prints those fields, in a fixed order, on one line.
The operating system is Peios #
uname -o, and the operating-system field of uname -a, report Peios. This is the field a script should check when it wants to confirm what system it is on.
For the machine architecture alone, arch is the shorter command — it prints exactly what uname -m prints.
Exit status #
| Code | Meaning |
|---|---|
0 | The requested information was printed. |
1 | The system information could not be read. |
arch
Peios / Using Peios / Peiosutils / System and processes
arch prints the machine's hardware architecture — the kind of processor the system runs on.
arch
$ arch
x86_64
That is the whole command. It takes no options and prints a single name.
arch prints exactly what uname -m prints. It exists as a short, obvious name for the one question "what architecture is this?" — convenient in a script that picks an architecture-specific path.
Exit status #
| Code | Meaning |
|---|---|
0 | The architecture was printed. |
1 | The architecture could not be determined. |
hostname
Peios / Using Peios / Peiosutils / System and processes
hostname displays the system's host name — the name the system is known by.
hostname [options] [name]
$ hostname
host-01.example.com
What is displayed #
By default hostname prints the fully qualified name. These options narrow or change what is shown:
| Option | Prints |
|---|---|
-f, --fqdn | The fully qualified domain name — the full host.domain form. This is the default. |
-s, --short | The short host name only — the part before the first dot. |
-d, --domain | The DNS domain part only. |
-i, --ip-address | The network address (or addresses) the host name resolves to. |
Setting the host name #
Given a name argument, hostname sets the system's host name to it.
$ hostname host-02
Changing the host name changes state for the whole system, so it is a privileged operation — it succeeds only for a caller whose token carries the right to do it, and is refused otherwise. See Privileges.
Exit status #
| Code | Meaning |
|---|---|
0 | The host name was displayed or set. |
1 | A failure — the name could not be read, set, or resolved. |
hostid
Peios / Using Peios / Peiosutils / System and processes
hostid prints the host's numeric identifier, in hexadecimal.
hostid
$ hostid
007f0100
The host id is a number associated with the system. It takes no options and prints one value.
Where hostname gives the system's name — meant to be read by people — hostid gives a numeric value, used by software that wants a machine identifier in a fixed numeric form.
Exit status #
| Code | Meaning |
|---|---|
0 | The host id was printed. |
nproc
Peios / Using Peios / Peiosutils / System and processes
nproc prints the number of processor cores available.
nproc [options]
$ nproc
8
By default it prints the number of cores available to the current process — which can be fewer than the machine has, if the process has been restricted to a subset. It is most often used to decide how many parallel jobs to run.
Options #
| Option | Effect |
|---|---|
--all | Print the number of cores the whole system has, ignoring any restriction on the current process. |
--ignore=N | Subtract N from the count — for leaving some cores free rather than using every one. |
The environment variables OMP_NUM_THREADS and OMP_THREAD_LIMIT, if set, also bound the number nproc reports.
Exit status #
| Code | Meaning |
|---|---|
0 | The count was printed. |
1 | An option value was invalid. |
uptime
Peios / Using Peios / Peiosutils / System and processes
uptime shows how long the system has been running, along with a few related figures.
uptime [options]
$ uptime
14:32:08 up 6 days, 3:21, load average: 0.18, 0.24, 0.21
The default line packs in three things:
- the current time;
- how long the system has been up;
- the load average — a rough measure of how busy the system has been over the last 1, 5, and 15 minutes.
If you know uptime from other systems you may be expecting a count of logged-in users between the uptime and the load average. Peios does not print one. That count comes from a login database (utmp) that Peios does not keep — logon sessions are a KACS concept, and the tooling to report them is not built yet. Rather than print a figure that would always read 0 users, the field is left out until it can be answered honestly.
Options #
| Option | Effect |
|---|---|
-p, --pretty | Show just the uptime, in a readable phrase — up 6 days, 3 hours, 21 minutes. |
-s, --since | Show the date and time the system started, rather than how long ago that was. |
Exit status #
| Code | Meaning |
|---|---|
0 | The uptime was printed. |
1 | The boot time could not be read. |
sync
Peios / Using Peios / Peiosutils / System and processes
sync flushes cached writes to persistent storage.
sync [options] [file...]
$ sync
When a program writes to a file, the data does not always reach the physical device immediately — for speed, the system holds recent writes in memory and writes them out a little later. sync forces that pending data out now, so that what is on the device matches what programs have written.
It is the command to run before doing something that should not lose recent writes — before powering off by hand, or before removing storage.
Options #
With no argument, sync flushes everything. The options narrow it:
| Option | Effect |
|---|---|
file... | Flush only the given files, rather than everything. |
-d, --data | For the given files, flush only the file data, not metadata that does not need it. |
-f, --file-system | Flush the entire file system that contains each given file. |
Exit status #
| Code | Meaning |
|---|---|
0 | The flush completed. |
1 | A named file could not be reached. |
tty
Peios / Using Peios / Peiosutils / System and processes
tty prints the name of the terminal connected to standard input.
tty [options]
$ tty
/dev/pts/3
If standard input is not a terminal — because it has been redirected from a file or a pipe — tty prints not a tty instead.
That second behaviour is the useful one: a script can run tty to find out whether it is being run interactively or as part of a pipeline, and behave accordingly.
Options #
| Option | Effect |
|---|---|
-s, --silent | Print nothing; report the answer only through the exit status. |
Exit status #
| Code | Meaning |
|---|---|
0 | Standard input is a terminal. |
1 | Standard input is not a terminal. |
2 | A usage error. |
stty
Peios / Using Peios / Peiosutils / System and processes
stty displays and changes the settings of a terminal — how it handles input, output, and special keys.
stty [options] [setting...]
$ stty
speed 38400 baud; line = 0;
-brkint -imaxbel iutf8
Run with no arguments, stty prints the settings that differ from the usual defaults. Given setting arguments, it changes them.
Viewing the settings #
| Option | Effect |
|---|---|
-a, --all | Print every setting, in a readable layout. |
-g, --save | Print every setting in a single compact line — a form that can be fed straight back to stty to restore them. |
The -g form is how you save and restore a terminal's state:
$ saved=$(stty -g) # capture the current state
$ stty -echo # ...change something...
$ stty "$saved" # restore exactly what was saved
Changing the settings #
A setting argument turns something on or off, or assigns a value. A few common ones:
| Setting | Effect |
|---|---|
echo / -echo | Show / hide typed characters — -echo is how a password prompt hides input. |
rows N / cols N | Tell the terminal its size. |
| A number | Set the connection speed (baud rate). |
stty has a large catalog of settings; stty -a shows them all with their current values.
Choosing the terminal #
| Option | Effect |
|---|---|
-F, --file=DEVICE | Operate on DEVICE instead of the terminal on standard input. |
Exit status #
| Code | Meaning |
|---|---|
0 | The settings were printed or changed. |
1 | A setting was invalid, or the terminal could not be accessed. |
stdbuf
Peios / Using Peios / Peiosutils / System and processes
stdbuf runs a command with altered buffering on its standard streams.
stdbuf [options] command...
$ slow-producer | stdbuf -oL grep error
What buffering is, and why change it #
A program usually does not write each piece of output the instant it is produced — it collects output in a buffer and writes it in batches, which is faster. The cost is delay: when a program's output feeds a pipe, that batching can hold lines back for a long time, which is unhelpful when you are watching a pipeline live.
stdbuf lets you override that batching for a command, so its output appears sooner.
Setting the buffering #
| Option | Stream |
|---|---|
-i, --input=MODE | Standard input. |
-o, --output=MODE | Standard output. |
-e, --error=MODE | Standard error. |
MODE is one of:
| MODE | Buffering |
|---|---|
0 | Unbuffered — every write goes out immediately. |
L | Line-buffered — output is flushed at the end of each line. Not valid for input. |
| a size | Fully buffered with a buffer of that many bytes. Accepts suffixes — K, M, and so on. |
-oL — line-buffered output — is the common case: it makes a command in a pipeline emit each line as it is finished.
A limitation #
stdbuf adjusts the default buffering. A command that manages its own stream buffering will override what stdbuf sets, and some commands do not use buffered streams at all — for those, stdbuf has no effect.
Exit status #
When stdbuf runs a command, it exits with that command's status. The exception is a failure in stdbuf itself:
| Code | Meaning |
|---|---|
| (command's own) | The command ran; this is its exit status. |
(a stdbuf-level error code) | The command could not be started. |
chroot
Peios / Using Peios / Peiosutils / System and processes
chroot runs a command with a different directory as its root — its /. Inside that command, the chosen directory is the top of the file system, and nothing above it can be named or reached.
chroot newroot [command [arg]...]
$ chroot /mnt/system /bin/sh
With a command, chroot changes the root to newroot and runs the command there. With no command, it starts an interactive shell.
What it does #
A process normally sees the whole file system, rooted at the real /. After chroot, the named directory becomes that process's /: a path like /etc/config inside the command resolves to newroot/etc/config, and there is no path that reaches outside newroot at all.
It is used to work inside another installed system — repairing or configuring a system image by entering it — and to run a command confined to a known subtree.
For the command to be usable, newroot must already contain what the command needs: the command's own executable, and whatever libraries and files it depends on, all present under newroot.
Options #
| Option | Effect |
|---|---|
--skip-chdir | Do not change the working directory to / after changing the root. Permitted only when newroot is the current /. |
A privileged operation #
Changing a process's root directory is a privileged operation. chroot succeeds only for a caller whose token carries the right to do it, and is refused otherwise — the ability to redraw a process's view of the file system is not something every principal holds. See Privileges.
Exit status #
chroot exits with the command's own status once it finishes. Otherwise:
| Code | Meaning |
|---|---|
125 | chroot itself failed — for example, newroot is not a directory. |
126 | The command was found but could not be run. |
127 | The command was not found. |
whoami
Peios / Using Peios / Peiosutils / System and processes
whoami prints the name of the user the calling process is running as.
whoami
$ whoami
jack
It takes no arguments. It is the same answer as id -un, which is all it has ever been.
Where the name comes from #
The name is resolved from the process's effective user ID, which is a projection of the token's user SID. The lookup goes to the authority — there is no /etc/passwd to read — and comes back as the principal's canonical name. Resolving names is the full picture.
The name is the principal's; the number it was looked up by is not what grants anything. If you want the identity access is actually decided against, id -Z prints the SID.
Exit status #
| Code | Meaning |
|---|---|
0 | The name was printed. |
1 | The user ID could not be resolved to a name. |
A failure here usually means the authority could not be reached rather than that the account is missing — identity does not resolve before the authority is running, which is the correct answer rather than a gap.
id
Peios / Using Peios / Peiosutils / System and processes
id prints who a process is: its user, its primary group, the groups it belongs to, and its security context.
id [options] [USER]...
$ id
uid=5001000(jack) gid=5000513(Users) groups=5000513(Users),100(Everyone),101(Authenticated Users),1544(Administrators) context=S-1-5-21-1004336348-1177238915-682003330-1000:High
With no argument it reports the calling process. Given one or more users, it reports on those instead.
The numbers are projections #
This is the thing to understand before reading id's output on Peios.
The uid= and gid= numbers are projections of the token's SIDs. They are real, stable, and exactly what Linux programs see and what filesystems store — but nothing is decided by them. Access is decided against the SID the number was projected from, by the access check. A number here grants nothing.
That distinction is not academic, because the projection cannot carry everything a token holds:
- Groups whose SIDs are deliberately unnumbered —
Interactive,Network,Batch,Service— cannot appear at all. They are what make a rule like "network logons cap at Low" expressible, and they have no gid by design. - A group's attributes have nowhere to go. A deny-only group, which can block access through a deny entry but grant nothing through an allow entry, appears in
groups=looking exactly like an ordinary membership. - The integrity level and the logon session have no number either.
So two tokens can project to identical numbers and mean different things. The clearest case is a filtered token: it carries the same user SID and the same group numbers as the token it came from, and differs only in attributes the projection cannot express.
That is why the default line ends with a context= field.
The context field #
context= is the authoritative half: the user SID access is actually decided against, and the integrity level.
context=S-1-5-21-1004336348-1177238915-682003330-1000:High
The integrity level is part of it precisely because the SID alone does not separate an elevated token from its filtered counterpart — both carry the same user SID, and the level is what differs.
If you know id from another Unix, this is the field that carries the SELinux context there. Peios has no SELinux; its security context is the token, so that is what the field holds.
context= is omitted when a user is named rather than the calling process — a named user has no token here to read — and when POSIXLY_CORRECT is set, so a caller that asked for the POSIX shape still gets it.
For the whole token rather than this summary, use token.
Options #
| Option | Effect |
|---|---|
-u, --user | Print only the effective user ID. |
-g, --group | Print only the effective group ID. |
-G, --groups | Print only the group IDs, space-separated. |
-n, --name | With -u, -g or -G, print names instead of numbers. |
-r, --real | With -u, -g or -G, print the real ID rather than the effective one. |
-z, --zero | Separate entries with NUL rather than whitespace. Not allowed in the default format. |
-Z, --context | Print only the security context. |
-p | A readable, multi-line form. |
-P | Print as a password-file entry. |
-a | Ignored; accepted for compatibility. |
-A | Not applicable on Peios — see below. |
-n and -r need one of -u, -g or -G; they do not change the default format.
-r means something different here #
On other Unixes the real/effective split is the setuid boundary. On Peios a setuid bit does not change a token, so that boundary does not exist. What the split tracks instead is impersonation: the real IDs come from the process's own token, the effective ones from whatever token is in force.
id never impersonates, so in practice it reports the same either way and the euid=/egid= fields never appear. That is not a fault — there is genuinely nothing differing to report.
-A is not applicable #
-A reports BSD audit session properties. Peios audits through its own event system and keeps no BSM session, so -A says so rather than silently succeeding at nothing.
id -G and id -G <yourself> differ #
Asking about yourself and asking about your name are two different questions here, and they give different answers:
id -Greads your process's credential — the projection of your token's group set, which includes the groups the authority added when the token was minted:Everyone,Authenticated Users, and anyAdministrators-style aliases.id -G jacklooks the name up through the principal store, which returns recorded memberships only. The stapled groups are not recorded anywhere, because membership in them is a rule rather than a stored fact — so they do not come back.
On other systems these two differ only in the order they print. Here the second list is genuinely shorter, and neither is wrong.
Exit status #
| Code | Meaning |
|---|---|
0 | The identity was printed. |
1 | A user could not be found, an option combination was rejected, or the context could not be read. |
groups
Peios / Using Peios / Peiosutils / System and processes
groups prints the groups a user belongs to.
groups [USERNAME]...
$ groups
Users Everyone Authenticated Users Administrators
$ groups jack
jack : Users Administrators
With no argument it reports the calling process. Given names, it reports on those.
Those two answers are both correct #
The example above is not a mistake, and it is the thing worth knowing about this command on Peios.
groups reads the calling process's credential — the projection of its token's group set. That set includes the groups the authority stapled on when the token was minted: Everyone, Authenticated Users, and the like.
groups jack looks the name up through the principal store, which returns recorded memberships — the ones something actually wrote down.
The stapled groups are not recorded anywhere, because membership in them is a rule, not a stored fact. Everyone is in Everyone; nothing needs to record it, and nothing can enumerate it. So they appear in the first answer and not the second.
On other Unixes these two forms differ only in the order they print.
What cannot appear #
Both forms are lossy in the same way, and unavoidably so — a group can only be listed if it has a group ID, and some deliberately do not:
Interactive,Network,BatchandServiceare unnumbered on purpose. They describe how you signed in rather than who you are, which is what lets a rule like "network logons cap at Low" be written at all. You are inInteractiveat the console and not over the network, so there is no static answer to record.- A group's attributes are not representable. A deny-only group — one that can block access through a deny entry but grant nothing through an allow entry — is printed exactly like an ordinary membership.
token groups is the lossless view, with every SID and its attributes.
Exit status #
| Code | Meaning |
|---|---|
0 | The groups were printed. |
1 | A named user could not be found, or the group list could not be read. |
A group ID with no name is printed as the bare number and sets the exit status, rather than stopping the listing.
logname
Peios / Using Peios / Peiosutils / System and processes
logname prints the login name the calling process runs under.
logname
$ logname
jack
It takes no arguments.
Login name, not current name #
logname and whoami look like the same command and answer slightly different questions.
whoami reports the effective identity — whoever the process is acting as right now. logname reports the login identity: the principal the process's own token is for, regardless of any token it has since taken on. When a process is impersonating a client, whoami follows the impersonation and logname does not.
Most of the time nothing is impersonating and the two agree.
If you know logname from another Unix, note that it answers this from the token rather than from a login-record file. There is no utmp on Peios — nothing writes one — so the traditional source does not exist. The token is the record of who a process is, and it is a better one: it cannot drift from the identity access is actually checked against, because it is that identity.
Exit status #
| Code | Meaning |
|---|---|
0 | The login name was printed. |
1 | No login name could be determined. |
token
Peios / Using Peios / Peiosutils / System and processes
token is the command-line tool for working with tokens directly. It reads a token's contents, adjusts it, produces derived tokens, and drives impersonation — the low-level operations this topic describes, exposed at a shell.
token subcommand [target] [arguments]
$ token # one-line summary of your own token
$ token show --all # every field of your own token
$ token privs --pid 4821 # the privileges on process 4821's token
token is a direct, debug-level tool. Day to day you do not inspect tokens by hand — the system does. token is for diagnosing an access problem, for understanding what identity a process is really running under, and for building and testing identity setups. Run with no subcommand, it prints a one-line summary of your own token.
Choosing which token #
Almost every subcommand operates on a token, and these flags choose which one. With none, the target is your own.
| Flag | Target |
|---|---|
--self | Your own token. The default. |
--real | Your primary token specifically, rather than the effective one — relevant when your thread is impersonating. |
--pid PID | The primary token of process PID. |
--tid TID | The impersonation token of thread TID (used with --pid). |
--peer SOCK_FD | The peer's captured token on a connected socket — see Peer tokens. |
Reading another process's token is itself access-controlled: it succeeds only with the right authority over that process.
Inspecting a token #
show #
token show prints a token's contents. It is the default — bare token is token show --short.
| Flag | Effect |
|---|---|
--short | A one-line summary. |
--all | Every query class — the fullest dump. |
Field accessors #
Each of these prints one part of a token, for when you want just that piece:
| Subcommand | Prints |
|---|---|
user | The user SID — who the token is. |
owner | The default owner SID. |
group | The primary group SID. |
groups | The group list. |
privs | The privileges, with their enabled state. |
caps | The capabilities. |
claims | The user and device claims. |
integrity | The integrity level. |
logon | The logon type and logon SID. |
source | What minted the token. |
origin | The originating session for a derived token. |
stats | Token statistics — IDs, timestamps, the modification counter. |
default-dacl | The token's default DACL. |
query #
token query CLASS performs a raw read of a single named token-info class and prints the result as JSON — the lowest-level inspection route, for tooling.
Changing a token #
adjust #
token adjust mutates a token in place:
| Form | Changes |
|---|---|
adjust privs NAME=STATE … | Enable, disable, or remove privileges. STATE is enabled, disabled, or removed. |
adjust groups IDX=STATE … | Enable or disable groups by their list index. |
adjust default --dacl SDDL | Replace the token's default DACL. Also --owner-idx / --group-idx. |
adjust session ID | Replace the token's session id. |
restrict #
token restrict produces a restricted token — a more limited variant of a token.
| Flag | Effect |
|---|---|
--drop-privs MASK|NAMES | Privileges to drop. |
--deny IDX,… | Group indices to mark deny-only. |
--restrict SID,… | The restricting SIDs to apply. |
duplicate #
token duplicate (alias dup) copies a token, optionally changing its --type (primary or impersonation), its impersonation --level, or its --access mask.
link and linked #
token link joins two tokens as an elevation pair — a full token and its filtered counterpart — given their file descriptors and a session id. token linked shows a token's elevation-linked counterpart, if it has one. See Elevation.
Impersonation #
| Subcommand | Effect |
|---|---|
impersonate | Begin impersonating the target token on the calling thread. With a trailing -- command …, run that command under the impersonating token. |
revert | Drop any active impersonation on the calling thread. |
See Impersonation for the model these drive.
Creating tokens #
| Subcommand | Effect |
|---|---|
create SPEC | Create a token from a binary token-spec (SPEC is a file, or - for standard input). |
install SPEC | Create a token from a spec and install it as the caller's primary token. |
Creating and installing tokens is a privileged operation, reserved for the components that legitimately mint identity.
Output options #
| Flag | Effect |
|---|---|
--raw | Render SIDs in raw S-1-… form only. |
--label | Render SIDs as their labels where known, falling back to raw. |
--json | Emit JSON instead of human-readable output. |
token and the inspection surfaces #
token is the convenient front-end. Underneath, it reads the same kernel surfaces and rules described in Inspecting tokens — that page covers the query mechanism, the access rules for reading another process's token, and what cannot be inspected.
Exit status #
| Code | Meaning |
|---|---|
0 | The operation succeeded. |
1 | A usage error. |
| non-zero | The operation failed — no such target, an access denial, or a bad spec. |
logonse
Peios / Using Peios / Peiosutils / System and processes
logonse is the command-line tool for logon sessions — the kernel's records of authentication events that this topic describes. It lists the active sessions, shows which processes belong to one, creates and destroys sessions, and (as a related low-level job) sets a process's mitigation flags.
logonse subcommand [arguments]
$ logonse list
$ logonse show 4711
logonse is a low-level administrative and debugging tool. It requires a subcommand: list, show, create, destroy, or psb.
Listing sessions #
logonse list #
Enumerates the active logon sessions, and the process IDs in each.
$ logonse list
session 0 pids: [1, 2, 14, 22]
session 4711 pids: [820, 844, 901]
logonse show #
Shows the process IDs that belong to one session.
$ logonse show 4711
A caveat on list and show #
There is no syscall that enumerates logon sessions, and logonse does not read the kernel's sessions file (whose SD restricts it to Administrators and SYSTEM). logonse list and logonse show work by walking the running processes and reading each one's token to find which session it belongs to. That has two consequences worth knowing:
- It is best-effort. A session that has no running process — held alive only by a token file descriptor somewhere — will not appear, because there is no process to find it through.
- It is a snapshot under change. Processes start and exit while the walk runs, so the result is a close approximation of the moment, not a locked one.
For routine "who is signed in" use this is fine. For an authoritative listing, the kernel's own sessions surface — described in Inspecting sessions — is the source of record.
Creating and destroying sessions #
logonse create #
Creates a new logon session for a user, described by a logon type, an authentication-package name, and the user's SID.
$ logonse create --logon-type interactive --auth-package Negotiate --user-sid S-1-5-21-...-1001
| Flag | Meaning |
|---|---|
--logon-type TYPE | The kind of logon: interactive, network, batch, service, network-cleartext, or new-credentials. |
--auth-package STR | The name of the authentication package that vouched for the logon. |
--user-sid SID | The user the session belongs to, as an S-1-… SID or an SDDL alias such as BA. |
On success logonse prints the new session's id. Creating a session is a privileged operation — minting authentication records is reserved for the components that legitimately do so.
logonse destroy #
Destroys a session — but only an empty one, with no tokens still referencing it.
$ logonse destroy 4711
A session with live tokens cannot be destroyed this way; its tokens must go first. See Session lifecycle.
Setting process mitigation flags #
logonse psb #
logonse psb sets the mitigation flags in a process's Process Security Block.
$ logonse psb --pid 4821 --mitigations 0x1c0
| Flag | Meaning |
|---|---|
--pid PID | The process to act on. |
--mitigations MASK | The mitigation bitmask to apply, in hexadecimal or decimal. |
This subcommand is about process hardening rather than logon sessions — it lives in logonse because both deal with low-level per-process kernel state. For what the mitigation flags mean and how they behave, see Process mitigations.
Output options #
| Flag | Effect |
|---|---|
--json | Emit JSON instead of human-readable output. Accepted by every subcommand. |
Exit status #
| Code | Meaning |
|---|---|
0 | The operation succeeded. |
1 | A usage error, or the operation failed. |