Peios Learn
Products
PePeios pkpekit PvProvium UDUniversal Directory TrTrail PrProject WiWispist
Using Peios Security Basics Technical Documentation Source
Using Peios Security Basics Technical Documentation Source
Peios

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

CommandPurpose
datePrint — or set — the system date and time.
sleepPause for a given length of time.
uptimeShow how long the system has been running.

Running a command under a constraint

CommandPurpose
timeoutRun a command, and kill it if it runs too long.
nohupRun a command so it survives the terminal closing.
niceRun a command at an adjusted scheduling priority.
stdbufRun a command with altered stream buffering.
chrootRun a command with a different directory as its root.

Signalling processes

CommandPurpose
killSend a signal to a process.

System identity and capacity

CommandPurpose
unamePrint system information — the OS, the kernel, the machine.
archPrint the machine's hardware architecture.
hostnameDisplay — or set — the system's host name.
hostidPrint the host's numeric identifier.
nprocPrint how many processor cores are available.

Who you are

CommandPurpose
whoamiPrint the name of the user a process is running as.
idPrint the user and group identity of a process, or of a named user.
groupsPrint the groups a user belongs to.
lognamePrint 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

CommandPurpose
syncFlush cached writes out to persistent storage.
ttyPrint the name of the terminal on standard input.
sttyDisplay 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:

SequenceIs replaced by
%Y %m %dYear, month, day.
%H %M %SHour, minute, second.
%FThe full date — same as %Y-%m-%d.
%TThe time — same as %H:%M:%S.
%A %aWeekday name, full and abbreviated.
%B %bMonth name, full and abbreviated.
%jDay of the year.
%sSeconds since 1970-01-01 UTC.
%z %ZNumeric and named time zone.
%%A literal %.

The full set is long; date --help lists every sequence with an example.

Displaying a different moment #

OptionEffect
-d, --date=STRINGShow the time described by STRING — "yesterday", "next Friday", "@1615432800" — instead of now.
-r, --reference=FILEShow FILE's last modification time.
-f, --file=DATEFILELike -d, but once for each line of DATEFILE.
-u, --universalWork in Coordinated Universal Time (UTC) rather than the local zone.

Standard formats #

OptionOutput
-I, --iso-8601[=FMT]ISO 8601 — FMT is date, hours, minutes, seconds, or ns.
-R, --rfc-emailThe format used in email headers.
--rfc-3339=FMTRFC 3339 — FMT is date, seconds, or ns.

Setting the clock #

OptionEffect
-s, --set=STRINGSet 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 #

CodeMeaning
0The date was printed or set.
1An 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:

SuffixUnit
sSeconds. This is the default if no suffix is given.
mMinutes.
hHours.
dDays.

Given more than one argument, sleep waits for the sum of them — sleep 1m 30s pauses for ninety seconds.

Exit status #

CodeMeaning
0The full time elapsed.
1A 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.

OptionEffect
-s, --signal=SIGNALSend SIGNAL instead of TERM when the limit is reached.
-k, --kill-after=DURATIONIf the command is still running DURATION after the first signal, send it a KILL signal — which cannot be ignored.
--preserve-statusExit with the command's own status even when it timed out.
--foregroundAllow the command to keep reading from the terminal; do not time out the command's own children.
-v, --verboseReport 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:

CodeMeaning
(command's own)The command finished within the limit.
124The command timed out.
125timeout itself failed.
126The command was found but could not be run.
127The command was not found.
137The 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.out in the current directory. If that file cannot be opened there, nohup falls back to nohup.out in 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.

OptionEffect
--sddl=SDDLCreate 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:

CodeMeaning
(command's own)The command ran; this is its exit status.
125nohup 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.

OptionEffect
-n, --adjustment=NAdd 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:

CodeMeaning
(command's own)The command ran; this is its exit status.
0No command was given; the niceness was printed.
125nice itself failed — for example, a bad adjustment value.
126The command was found but could not be run.
127The 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:

SignalMeaning
TERMTerminate. The default — a request to stop cleanly.
KILLStop immediately. Cannot be caught or ignored, so it cannot be refused — but the process gets no chance to clean up. The last resort.
HUPHang up. Conventionally tells a long-running service to reload its configuration.
INTInterrupt — the signal a terminal sends on Ctrl-C.
STOP / CONTSuspend the process / resume a suspended one.
OptionEffect
-s, --signal=SIGNALSend SIGNAL instead of TERM.
-SIGNALA shorthand — -KILL or -9 both send KILL.
-l, --listList the signal names.
-L, --tableList 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 #

CodeMeaning
0Every signal was sent.
1A 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 #

OptionPrints
-sThe kernel name.
-oThe operating-system name — Peios.
-nThe node name — the name this system is known by on the network.
-rThe kernel release.
-vThe kernel version.
-mThe machine's hardware name (its architecture).
-pThe processor type.
-iThe hardware platform.
-aEverything — 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 #

CodeMeaning
0The requested information was printed.
1The 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 #

CodeMeaning
0The architecture was printed.
1The 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:

OptionPrints
-f, --fqdnThe fully qualified domain name — the full host.domain form. This is the default.
-s, --shortThe short host name only — the part before the first dot.
-d, --domainThe DNS domain part only.
-i, --ip-addressThe 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 #

CodeMeaning
0The host name was displayed or set.
1A 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 #

CodeMeaning
0The 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 #

OptionEffect
--allPrint the number of cores the whole system has, ignoring any restriction on the current process.
--ignore=NSubtract 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 #

CodeMeaning
0The count was printed.
1An 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 #

OptionEffect
-p, --prettyShow just the uptime, in a readable phrase — up 6 days, 3 hours, 21 minutes.
-s, --sinceShow the date and time the system started, rather than how long ago that was.

Exit status #

CodeMeaning
0The uptime was printed.
1The 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:

OptionEffect
file...Flush only the given files, rather than everything.
-d, --dataFor the given files, flush only the file data, not metadata that does not need it.
-f, --file-systemFlush the entire file system that contains each given file.

Exit status #

CodeMeaning
0The flush completed.
1A 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 #

OptionEffect
-s, --silentPrint nothing; report the answer only through the exit status.

Exit status #

CodeMeaning
0Standard input is a terminal.
1Standard input is not a terminal.
2A 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 #

OptionEffect
-a, --allPrint every setting, in a readable layout.
-g, --savePrint 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:

SettingEffect
echo / -echoShow / hide typed characters — -echo is how a password prompt hides input.
rows N / cols NTell the terminal its size.
A numberSet the connection speed (baud rate).

stty has a large catalog of settings; stty -a shows them all with their current values.

Choosing the terminal #

OptionEffect
-F, --file=DEVICEOperate on DEVICE instead of the terminal on standard input.

Exit status #

CodeMeaning
0The settings were printed or changed.
1A 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 #

OptionStream
-i, --input=MODEStandard input.
-o, --output=MODEStandard output.
-e, --error=MODEStandard error.

MODE is one of:

MODEBuffering
0Unbuffered — every write goes out immediately.
LLine-buffered — output is flushed at the end of each line. Not valid for input.
a sizeFully 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:

CodeMeaning
(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 #

OptionEffect
--skip-chdirDo 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:

CodeMeaning
125chroot itself failed — for example, newroot is not a directory.
126The command was found but could not be run.
127The 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 #

CodeMeaning
0The name was printed.
1The 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 #

OptionEffect
-u, --userPrint only the effective user ID.
-g, --groupPrint only the effective group ID.
-G, --groupsPrint only the group IDs, space-separated.
-n, --nameWith -u, -g or -G, print names instead of numbers.
-r, --realWith -u, -g or -G, print the real ID rather than the effective one.
-z, --zeroSeparate entries with NUL rather than whitespace. Not allowed in the default format.
-Z, --contextPrint only the security context.
-pA readable, multi-line form.
-PPrint as a password-file entry.
-aIgnored; accepted for compatibility.
-ANot 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 -G reads 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 any Administrators-style aliases.
  • id -G jack looks 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 #

CodeMeaning
0The identity was printed.
1A 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, Batch and Service are 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 in Interactive at 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 #

CodeMeaning
0The groups were printed.
1A 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 #

CodeMeaning
0The login name was printed.
1No 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.

FlagTarget
--selfYour own token. The default.
--realYour primary token specifically, rather than the effective one — relevant when your thread is impersonating.
--pid PIDThe primary token of process PID.
--tid TIDThe impersonation token of thread TID (used with --pid).
--peer SOCK_FDThe 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.

FlagEffect
--shortA one-line summary.
--allEvery query class — the fullest dump.

Field accessors #

Each of these prints one part of a token, for when you want just that piece:

SubcommandPrints
userThe user SID — who the token is.
ownerThe default owner SID.
groupThe primary group SID.
groupsThe group list.
privsThe privileges, with their enabled state.
capsThe capabilities.
claimsThe user and device claims.
integrityThe integrity level.
logonThe logon type and logon SID.
sourceWhat minted the token.
originThe originating session for a derived token.
statsToken statistics — IDs, timestamps, the modification counter.
default-daclThe 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:

FormChanges
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 SDDLReplace the token's default DACL. Also --owner-idx / --group-idx.
adjust session IDReplace the token's session id.

restrict #

token restrict produces a restricted token — a more limited variant of a token.

FlagEffect
--drop-privs MASK|NAMESPrivileges 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 #

SubcommandEffect
impersonateBegin impersonating the target token on the calling thread. With a trailing -- command …, run that command under the impersonating token.
revertDrop any active impersonation on the calling thread.

See Impersonation for the model these drive.

Creating tokens #

SubcommandEffect
create SPECCreate a token from a binary token-spec (SPEC is a file, or - for standard input).
install SPECCreate 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 #

FlagEffect
--rawRender SIDs in raw S-1-… form only.
--labelRender SIDs as their labels where known, falling back to raw.
--jsonEmit 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 #

CodeMeaning
0The operation succeeded.
1A usage error.
non-zeroThe 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
FlagMeaning
--logon-type TYPEThe kind of logon: interactive, network, batch, service, network-cleartext, or new-credentials.
--auth-package STRThe name of the authentication package that vouched for the logon.
--user-sid SIDThe 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.

Note

The tool builds the kernel's binary session spec from these fields for you. The underlying wire format is unchanged; only the command-line surface is typed.

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
FlagMeaning
--pid PIDThe process to act on.
--mitigations MASKThe 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 #

FlagEffect
--jsonEmit JSON instead of human-readable output. Accepted by every subcommand.

Exit status #

CodeMeaning
0The operation succeeded.
1A usage error, or the operation failed.

Peios Learn — documentation for the Peios project.

Built with Trail.