# SPDX-License-Identifier: LGPL-2.1-or-later # shellcheck shell=bash # shellcheck disable=SC2016 # shellcheck disable=SC1003 # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # This implements the UAPI.15 "OSC 3008: Hierarchical Context Signalling" # specification for the shell prompt. For details see: # https://uapi-group.org/specifications/specs/osc_context/ # This file is "activated" through systemd-tmpfiles which links it into # /etc/profile.d/. To disable this, remove the # /etc/profile.d/80-systemd-osc-context.sh symlink and mask the # 20-systemd-osc-context.conf snippet (as root): # # test -h /etc/profile.d/80-systemd-osc-context.sh && \ # rm -v /etc/profile.d/80-systemd-osc-context.sh && \ # ln -s /dev/null /etc/tmpfiles.d/20-systemd-osc-context.conf # Not bash? [ -n "${BASH_VERSION:-}" ] || return 0 # If we're on a "dumb" terminal, do not install the prompt. # Treat missing $TERM same as "dumb". [ "${TERM:-dumb}" = "dumb" ] && return 0 # We need promptvars, otherwise the prompt strings won't undergo parameter expansion # and we'd print them literally shopt -q promptvars || return 0 __systemd_osc_context_escape() { # Escape according to the OSC 3008 spec. We'll skip it when processing # strings we are pretty sure we won't need it for, such as uuids # (originating from /proc/sys/kernel/ or /etc/machine-id) and special shell # variables such as $$ and $? that always expand to decimal numbers. local systemd_format="$1" local systemd_value="$2" systemd_value="${systemd_value//\\/\\x5c}" systemd_value="${systemd_value//;/\\x3b}" systemd_value="${systemd_value//[[:cntrl:]]/⍰}" # shellcheck disable=SC2059 # always called with fixed format strings with a single string specifier printf "$systemd_format" "$systemd_value" } __systemd_osc_context_common() { if [ -f /etc/machine-id ]; then printf ";machineid=%.36s" "$(&-); then printf "\033]3008;end=%.64s;exit=failure;status=%d;signal=SIG%s\033\\" "$systemd_osc_context_cmd_id" "$systemd_exitstatus" "$systemd_signal" elif [ "$systemd_exitstatus" -ne 0 ]; then printf "\033]3008;end=%.64s;exit=failure;status=%d\033\\" "$systemd_osc_context_cmd_id" "$systemd_exitstatus" else printf "\033]3008;end=%.64s;exit=success\033\\" "$systemd_osc_context_cmd_id" fi fi # Prepare a context ID for this shell if we have none if [ -z "${systemd_osc_context_shell_id:-}" ]; then read -r systemd_osc_context_shell_id /dev/null)" ] || PROMPT_COMMAND+=('') # Whenever a new prompt is shown, close the previous command, and prepare new command PROMPT_COMMAND+=(__systemd_osc_context_precmdline) # PS0 is shown right after a prompt completed, but before the command is executed PS0='$(__systemd_osc_context_ps0)'"${PS0:-}" fi