From: Lennart Poettering Date: Thu, 24 Oct 2024 09:36:48 +0000 (+0200) Subject: run0: optionally show superhero emoji on each shell prompt X-Git-Tag: v257-rc1~139^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=115fac3c29c80d8917158df2275d45fee118d61f;p=thirdparty%2Fsystemd.git run0: optionally show superhero emoji on each shell prompt This makes use of the infra introduced in 229d4a980607e9478cf1935793652ddd9a14618b to indicate visually on each prompt that we are in superuser mode temporarily. pick ad5de3222f userdbctl: add some basic client-side filtering --- diff --git a/man/run0.xml b/man/run0.xml index 422ca6bebbf..907222c0495 100644 --- a/man/run0.xml +++ b/man/run0.xml @@ -207,6 +207,20 @@ + + + + Set a shell prompt prefix string. This ultimately controls the + $SHELL_PROMPT_PREFIX environment variable for the invoked program, which is + typically imported into the shell prompt. By default – if emojis are supported – a superhero emoji is + shown (🦸). This default may also be changed (or turned off) by passing the + $SYSTEMD_RUN_SHELL_PROMPT_PREFIX environment variable to run0, + see below. Set to an empty string to disable shell prompt prefixing. + + + + + @@ -271,7 +285,30 @@ + + + $SHELL_PROMPT_PREFIX + By default set to the superhero emoji (if supported), but may be overriden with the + $SYSTEMD_RUN_SHELL_PROMPT_PREFIX environment variable (see below), or the + switch (see above). + + + + + The following variables may be passed to run0: + + + + $SYSTEMD_RUN_SHELL_PROMPT_PREFIX + If set, overrides the default shell prompt prefix that run0 sets + for the invoked shell (the superhero emoji). Set to an empty string to disable shell prompt + prefixing. + + + + + diff --git a/src/basic/glyph-util.c b/src/basic/glyph-util.c index 68fd3971adf..1108afdf03e 100644 --- a/src/basic/glyph-util.c +++ b/src/basic/glyph-util.c @@ -80,6 +80,7 @@ const char* special_glyph_full(SpecialGlyph code, bool force_utf) { [SPECIAL_GLYPH_YELLOW_CIRCLE] = "o", [SPECIAL_GLYPH_BLUE_CIRCLE] = "o", [SPECIAL_GLYPH_GREEN_CIRCLE] = "o", + [SPECIAL_GLYPH_SUPERHERO] = "S", }, /* UTF-8 */ @@ -149,6 +150,7 @@ const char* special_glyph_full(SpecialGlyph code, bool force_utf) { [SPECIAL_GLYPH_YELLOW_CIRCLE] = u8"🟡", [SPECIAL_GLYPH_BLUE_CIRCLE] = u8"🔵", [SPECIAL_GLYPH_GREEN_CIRCLE] = u8"🟢", + [SPECIAL_GLYPH_SUPERHERO] = u8"🦸", }, }; diff --git a/src/basic/glyph-util.h b/src/basic/glyph-util.h index 9b5c3a8d226..c31c3c18bba 100644 --- a/src/basic/glyph-util.h +++ b/src/basic/glyph-util.h @@ -55,6 +55,7 @@ typedef enum SpecialGlyph { SPECIAL_GLYPH_YELLOW_CIRCLE, SPECIAL_GLYPH_BLUE_CIRCLE, SPECIAL_GLYPH_GREEN_CIRCLE, + SPECIAL_GLYPH_SUPERHERO, _SPECIAL_GLYPH_MAX, _SPECIAL_GLYPH_INVALID = -EINVAL, } SpecialGlyph; diff --git a/src/run/run.c b/src/run/run.c index 529e9d1bcce..88fe8a0c8f7 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -85,6 +85,7 @@ static char *arg_exec_path = NULL; static bool arg_ignore_failure = false; static char *arg_background = NULL; static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF; +static char *arg_shell_prompt_prefix = NULL; STATIC_DESTRUCTOR_REGISTER(arg_description, freep); STATIC_DESTRUCTOR_REGISTER(arg_environment, strv_freep); @@ -96,6 +97,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_working_directory, freep); STATIC_DESTRUCTOR_REGISTER(arg_cmdline, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_exec_path, freep); STATIC_DESTRUCTOR_REGISTER(arg_background, freep); +STATIC_DESTRUCTOR_REGISTER(arg_shell_prompt_prefix, freep); static int help(void) { _cleanup_free_ char *link = NULL; @@ -194,6 +196,7 @@ static int help_sudo_mode(void) { " --background=COLOR Set ANSI color for background\n" " --pty Request allocation of a pseudo TTY for stdio\n" " --pipe Request direct pipe for stdio\n" + " --shell-prompt-prefix=PREFIX Set $SHELL_PROMPT_PREFIX\n" "\nSee the %s for details.\n", program_invocation_short_name, ansi_highlight(), @@ -778,29 +781,31 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) { ARG_BACKGROUND, ARG_PTY, ARG_PIPE, + ARG_SHELL_PROMPT_PREFIX, }; /* If invoked as "run0" binary, let's expose a more sudo-like interface. We add various extensions * though (but limit the extension to long options). */ static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'V' }, - { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, - { "machine", required_argument, NULL, ARG_MACHINE }, - { "unit", required_argument, NULL, ARG_UNIT }, - { "property", required_argument, NULL, ARG_PROPERTY }, - { "description", required_argument, NULL, ARG_DESCRIPTION }, - { "slice", required_argument, NULL, ARG_SLICE }, - { "slice-inherit", no_argument, NULL, ARG_SLICE_INHERIT }, - { "user", required_argument, NULL, 'u' }, - { "group", required_argument, NULL, 'g' }, - { "nice", required_argument, NULL, ARG_NICE }, - { "chdir", required_argument, NULL, 'D' }, - { "setenv", required_argument, NULL, ARG_SETENV }, - { "background", required_argument, NULL, ARG_BACKGROUND }, - { "pty", no_argument, NULL, ARG_PTY }, - { "pipe", no_argument, NULL, ARG_PIPE }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { "machine", required_argument, NULL, ARG_MACHINE }, + { "unit", required_argument, NULL, ARG_UNIT }, + { "property", required_argument, NULL, ARG_PROPERTY }, + { "description", required_argument, NULL, ARG_DESCRIPTION }, + { "slice", required_argument, NULL, ARG_SLICE }, + { "slice-inherit", no_argument, NULL, ARG_SLICE_INHERIT }, + { "user", required_argument, NULL, 'u' }, + { "group", required_argument, NULL, 'g' }, + { "nice", required_argument, NULL, ARG_NICE }, + { "chdir", required_argument, NULL, 'D' }, + { "setenv", required_argument, NULL, ARG_SETENV }, + { "background", required_argument, NULL, ARG_BACKGROUND }, + { "pty", no_argument, NULL, ARG_PTY }, + { "pipe", no_argument, NULL, ARG_PIPE }, + { "shell-prompt-prefix", required_argument, NULL, ARG_SHELL_PROMPT_PREFIX }, {}, }; @@ -907,6 +912,12 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) { arg_stdio = ARG_STDIO_DIRECT; break; + case ARG_SHELL_PROMPT_PREFIX: + r = free_and_strdup_warn(&arg_shell_prompt_prefix, optarg); + if (r < 0) + return r; + break; + case '?': return -EINVAL; @@ -1019,6 +1030,25 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) { log_debug_errno(r, "Unable to get terminal background color, not tinting background: %m"); } + if (!arg_shell_prompt_prefix) { + const char *e = secure_getenv("SYSTEMD_RUN_SHELL_PROMPT_PREFIX"); + if (e) { + arg_shell_prompt_prefix = strdup(e); + if (!arg_shell_prompt_prefix) + return log_oom(); + } else if (emoji_enabled()) { + arg_shell_prompt_prefix = strjoin(special_glyph(SPECIAL_GLYPH_SUPERHERO), " "); + if (!arg_shell_prompt_prefix) + return log_oom(); + } + } + + if (!isempty(arg_shell_prompt_prefix)) { + r = strv_env_assign(&arg_environment, "SHELL_PROMPT_PREFIX", arg_shell_prompt_prefix); + if (r < 0) + return log_error_errno(r, "Failed to set $SHELL_PROMPT_PREFIX environment variable: %m"); + } + return 1; } diff --git a/src/test/test-locale-util.c b/src/test/test-locale-util.c index ab2d1f5746c..7afa446bfb6 100644 --- a/src/test/test-locale-util.c +++ b/src/test/test-locale-util.c @@ -82,7 +82,7 @@ TEST(keymaps) { #define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x)) TEST(dump_special_glyphs) { - assert_cc(SPECIAL_GLYPH_GREEN_CIRCLE + 1 == _SPECIAL_GLYPH_MAX); + assert_cc(SPECIAL_GLYPH_SUPERHERO + 1 == _SPECIAL_GLYPH_MAX); log_info("is_locale_utf8: %s", yes_no(is_locale_utf8())); @@ -133,6 +133,7 @@ TEST(dump_special_glyphs) { dump_glyph(SPECIAL_GLYPH_YELLOW_CIRCLE); dump_glyph(SPECIAL_GLYPH_BLUE_CIRCLE); dump_glyph(SPECIAL_GLYPH_GREEN_CIRCLE); + dump_glyph(SPECIAL_GLYPH_SUPERHERO); } DEFINE_TEST_MAIN(LOG_INFO);