Commit Graph
20 Commits
Author SHA1 Message Date
Frantisek Sumsal 7d1b6b7b96 profile: bail out early if promptvars is disabled
We need promptvars, otherwise the prompt strings won't undergo parameter
expansion and we'd print them literally:

$ shopt -u promptvars
$ echo foo
$(__systemd_osc_context_ps0)foo

Resolves: #40620
2026-05-14 23:17:40 +09:00
Chris Lindee 2d738a0aee profile/systemd-osc-context: Enforce length limits
UAPI.15 limits the length of fields; adhere to them.

References:
 [0] https://uapi-group.org/specifications/specs/osc_context/#syntax-in-abnf
2026-02-16 03:15:53 -06:00
Chris Lindee 72e71897f9 profile/systemd-osc-context: Remove invalid octets
UAPI.15 requires:
* No C0 Control Characters (`\x00-\x1f`)
* No DEL character (`\x7f`)

The following would be nice, but requires a `sed` implementation that is
aware of UTF-8: `-e $'y/\x00-\x1f\x7f/␀-␟␡/'`.

References:
 [0] https://uapi-group.org/specifications/specs/osc_context/#general-syntax
2026-02-16 03:15:53 -06:00
Chris Lindee 6a46846871 profile/systemd-osc-context: Bring escape up to spec
UAPI.15 requires:
* `\` to be replaced with `\x5c`
* `;` to be replaced with `\x3b`

References:
 [0] https://uapi-group.org/specifications/specs/osc_context/#general-syntax
2026-02-16 03:15:53 -06:00
Chris Lindee b88ab1c2dd profile/systemd-osc-context: Acknowledge uncertainty
Bash does not provide an easy way to discern if an exit status came from
a signal, or was a legitimate non-zero exit (i.e. a failure).  It can be
done, by using job control or by invoking another program; however, such
approaches require modifying the command entered by a user and are, thus,
invasive and risky.

Since an exit status of 129 on a command could either indicate it exited
cleanly with `exit(129)` or was interrupted by `SIGHUP`, the osc context
should report both possibilities, to acknowledge our uncertainty.  Given
we have no idea what happened, besides an unsuccessful exit, the exit is
described as `exit=failure`.

Moreover, discerning between an `interrupt` and a `crash` with a command
likely involves categorizing every signal.  It is fairly obvious `SIGINT`
is an interrupt and also obvious, IMO, that `SIGSEGV` is a crash.  Avoid
the complication (and potential disagreements) by using the encompassing,
generic value — one that remains true if no signal occurred.

References:
 [0] https://stackoverflow.com/a/66431355
2026-02-16 03:15:51 -06:00
Chris Lindee 3de092fad7 profile/systemd-osc-context: Bring exit up to spec
The exit status should be compared against 128 — not 127 — as the Bash
manual, under the EXIT STATUS section, states [0]:

    When a command terminates on a fatal signal N, bash uses the value
    of 128+N as the exit status.

    If a command is not found, the child process created to execute it
    returns a status of 127.  If a command is found but is not
    executable, the return status is 126.

Furthermore, UAPI.15 specifies the `signal` value must be the symbolic
signal name, not a numerical value [1].  Luckily, POSIX.1-2008 ensures
the shell must supply `kill -l`, which must be able to convert `$?` to
the signal that could cause such an exit in that shell [2].  It should
be noted that only a select handful of signals have a standard numeric
value; all others are implementation-defined [3].  This is why UAPI.15
requires the symbolic name, as the value may differ across systems.

Notably, not every value above 128 needs to correspond to a signal; on
my Linux system, only exit codes 129–192 indicate a signal.  Again, we
can use `kill -l`, which will exit non-zero when an exit code does not
come from a signal (plus 128) [4].

Signal 0 (which would correspond to exit code 128) is reserved for the
null signal, per POSIX.1-2008 [5], and therefore will never be an exit
signal.

This change brings the implementation into compliance.

References:
 [0] https://www.man7.org/linux/man-pages//man1/bash.1.html#EXIT_STATUS
 [1] https://uapi-group.org/specifications/specs/osc_context/
 [2] https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/kill.html#:~:text=The%20letter%20ell
 [3] https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/utilities/kill.html#:~:text=The%20effects%20of%20specifying%20any%20signal_number
 [4] https://www.man7.org/linux/man-pages//man1/bash.1.html#:~:text=false%20if%20an%20error%20occurs%20or%20an%20invalid%20option%20is%20encountered
 [5] https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/basedefs/signal.h.html#:~:text=The%20value%200%20is%20reserved%20for%20use%20as%20the%20null%20signal
2026-02-16 03:14:43 -06:00
nikstur 14519d7dfa meson: guard symlinks in sysconfdir behind install_sysconfidr
Symlinks to files inside sysconfdir are now only installed if
ìnstall_sysconfdir=true (which is the default).

If sshconfdir,sshdconfdir,shellprofiledir are not inside sysconfdir and
install_sysconfidr=false, these symlinks are still installed to the
configured directory.
2026-02-09 16:52:53 +01:00
Lennart Poettering 18d90c1628 bash: clarfiy what 80-systemd-osc-context.sh is about in the spec 2025-12-18 10:50:23 +01:00
Yu Watanabe 97ad10c9aa profile: skip setting PS0 when PROMPT_COMMAND= is cleared
Fixes #39639.
2025-11-10 06:05:15 +09:00
Zbigniew Jędrzejewski-Szmek 705e2ef194 profile/osc-context: move and extend check for TERM=dumb
Let's do the check early and skip most of the file if appropriate. Also, treat
missing $TERM same as "dumb". We're almost certainly at a dump terminal in that
case.
2025-11-07 14:47:49 +01:00
Zbigniew Jędrzejewski-Szmek dd20ba74e3 profile/systemd-osc-context: fix overriding of PROMPT_COMMAND
In https://github.com/systemd/systemd/issues/39114 users are reporting
that our script overrides PROMPT_COMMAND that they had. After looking
at /etc/bashrc in Fedora, I see that it only sets PROMPT_COMMAND if
[ -z "$PROMPT_COMMAND" ]. Let's adjust the script so this continues to
work.

Fixes https://github.com/systemd/systemd/issues/39114.
(This is a bit of a stretch. 39114 was originally about SecureCRT,
but that was resolved in SecureCRT. But there was a lot of dicussion
about the prompt being overriden, which this commit should fix.)
2025-11-06 12:21:27 +01:00
Justin Kromlinger 0fe45b98dd Drop machine-id OSC event field if /etc/machine-id doesn't exist
While we can safely assume that `/proc/sys/kernel/random/boot_id`
exists, the same can't be said for `/etc/machine-id` in environments
where systemd is installed, but not running. An example would be OCI
containers like with the official Arch Linux image, see [0].

Without this check the prompt would constantly output `/etc/machine-id:
no such file or directory` with the OSC events introduced in dadbb34
(v258).

[0] https://gitlab.archlinux.org/archlinux/archlinux-docker/-/issues/107
2025-10-09 09:08:13 +02:00
Yu Watanabe 3b6288f6be osc-context: fix typo: 8003 -> 3008
Follow-up for dadbb34919 (v258).
2025-09-26 05:42:04 +09:00
Yu Watanabe f79f89c202 profile: do not prompt OSC sequences when running on a dumb terminal 2025-08-13 23:43:51 +09:00
Yu Watanabe 0dc0bf4caf profile: replace default bash prompt with more informative one
The default bash PS1 provides mostly no information.
Let's replace it.

Before:
```
[watanabe@thinkpad-x280:~] $ run0
🦸 bash-5.2# echo $PS1
🦸 \s-\v\$
```

After:
```
[watanabe@thinkpad-x280:~] $ run0
🦸 [root@thinkpad-x280 watanabe]# echo $PS1
🦸 [\u@\h \W]\$
```

Fixes #38494.
2025-08-06 14:24:19 +01:00
Yu Watanabe c0cc01de8a meson: use install_symlink() where applicable
Now our baseline of meson is 0.62, hence install_symlink() can be used.

Note, install_symlink() implies install_emptydir() for specified
install_dir. Hence, this also drops several unnecessary
install_emptydir() calls.

Note, the function currently does not support 'relative' and 'force' flags,
so several 'ln -frsT' inline calls cannot be replaced.
2025-03-10 02:41:40 +09:00
Yu Watanabe 649c63d6ac profile: return earlier if it is loaded from non-bash shell
Follow-up for dadbb34919.
2025-02-28 21:24:06 +09:00
Lennart Poettering dadbb34919 profile: generate shell + command OSC events 2025-02-27 15:13:15 +01:00
Tobias Klauser 12e33d332b profile.d: don't bail if $SHELL_* variables are unset
If - for whatever reason - a script uses set -u (nounset) and includes
/etc/profile.d/70-systemd-shell-extra.sh (e.g. transitively via
/etc/profile) the script would fail with:

    /etc/profile.d/70-systemd-shell-extra.sh: line 15: SHELL_PROMPT_PREFIX: unbound variable

For example:

    $ cat > foo.sh <<EOF
    #!/bin/sh
    set -u

    source /etc/profile
    EOF
    $ chmod 700 foo.sh
    $ ./foo.sh
    /etc/profile.d/70-systemd-shell-extra.sh: line 15: SHELL_PROMPT_PREFIX: unbound variable

Fix this by using shell parameter substitution[^1] (which is a POSIX
shell concept) to set the $SHELL_* variables to the empty string if
undefined.

[^1]: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/V3_chap02.html
2024-12-11 18:33:41 +00:00
Lennart Poettering 229d4a9806 shell: define three system credentials we can propagate into shell prompts and welcome messages 2024-09-09 19:03:48 +02:00