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);