From: Arnout Engelen Date: Mon, 6 Apr 2026 08:00:37 +0000 (+0200) Subject: run: allow setting output format X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=086707ba7957c2ccc074c1d83e27e1fdb196de4e;p=thirdparty%2Fsystemd.git run: allow setting output format This is useful when moving from `--pty` or `--pipe` to using `--verbose`: you can use `--verbose-output=cat` to get similar output on stdout while still having all of the advantages of `--verbose` over the other options. --- diff --git a/man/systemd-run.xml b/man/systemd-run.xml index d18b80faa8a..bb90f352657 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -434,6 +434,16 @@ + + + + + Controls the formatting of verbose unit log output, see journalctl1 for possible values. + + + + + diff --git a/src/run/run.c b/src/run/run.c index 88a9f41d69a..596e1282675 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -105,6 +105,7 @@ static char **arg_timer_property = NULL; static bool arg_with_timer = false; static bool arg_quiet = false; static bool arg_verbose = false; +static OutputMode arg_output = _OUTPUT_MODE_INVALID; static bool arg_aggressive_gc = false; static char *arg_working_directory = NULL; static char *arg_root_directory = NULL; @@ -182,6 +183,8 @@ static int help(void) { " -P --pipe Pass STDIN/STDOUT/STDERR directly to service\n" " -q --quiet Suppress information messages during runtime\n" " -v --verbose Show unit logs while executing operation\n" + " --output=STRING Controls formatting of verbose logs, see\n" + " journalctl for valid values\n" " --json=pretty|short|off Print unit name and invocation id as JSON\n" " -G --collect Unload unit after it ran, even when failed\n" " -S --shell Invoke a $SHELL interactively\n" @@ -318,6 +321,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_EXEC_USER, ARG_EXEC_GROUP, ARG_NICE, + ARG_OUTPUT, ARG_ON_ACTIVE, ARG_ON_BOOT, ARG_ON_STARTUP, @@ -370,6 +374,7 @@ static int parse_argv(int argc, char *argv[]) { { "pipe", no_argument, NULL, 'P' }, { "quiet", no_argument, NULL, 'q' }, { "verbose", no_argument, NULL, 'v' }, + { "output", required_argument, NULL, ARG_OUTPUT }, { "on-active", required_argument, NULL, ARG_ON_ACTIVE }, { "on-boot", required_argument, NULL, ARG_ON_BOOT }, { "on-startup", required_argument, NULL, ARG_ON_STARTUP }, @@ -542,6 +547,15 @@ static int parse_argv(int argc, char *argv[]) { arg_verbose = true; break; + case ARG_OUTPUT: + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX); + + arg_output = output_mode_from_string(optarg); + if (arg_output < 0) + return log_error_errno(arg_output, "Unknown output format '%s'.", optarg); + break; + case ARG_ON_ACTIVE: r = add_timer_property("OnActiveSec", optarg); if (r < 0) @@ -2569,7 +2583,7 @@ static int start_transient_service(sd_bus *bus) { _cleanup_(fork_notify_terminate) PidRef journal_pid = PIDREF_NULL; if (arg_verbose) - (void) journal_fork(arg_runtime_scope, STRV_MAKE(c.unit), &journal_pid); + (void) journal_fork(arg_runtime_scope, STRV_MAKE(c.unit), arg_output, &journal_pid); r = bus_call_with_hint(bus, m, "service", &reply); if (r < 0) diff --git a/src/shared/fork-notify.c b/src/shared/fork-notify.c index 6f87a2fdce2..307197ac197 100644 --- a/src/shared/fork-notify.c +++ b/src/shared/fork-notify.c @@ -205,7 +205,7 @@ void fork_notify_terminate_many(sd_event_source **array, size_t n) { free(array); } -int journal_fork(RuntimeScope scope, char * const* units, PidRef *ret_pidref) { +int journal_fork(RuntimeScope scope, char * const* units, OutputMode output, PidRef *ret_pidref) { assert(scope >= 0); assert(scope < _RUNTIME_SCOPE_MAX); @@ -228,5 +228,9 @@ int journal_fork(RuntimeScope scope, char * const* units, PidRef *ret_pidref) { *u) < 0) return log_oom_debug(); + if (output >= 0) + if (strv_extendf(&argv, "--output=%s", output_mode_to_string(output)) < 0) + return log_oom_debug(); + return fork_notify(argv, ret_pidref); } diff --git a/src/shared/fork-notify.h b/src/shared/fork-notify.h index 103ab789833..2dbfe368a46 100644 --- a/src/shared/fork-notify.h +++ b/src/shared/fork-notify.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include "output-mode.h" #include "shared-forward.h" int fork_notify(char * const *argv, PidRef *ret_pidref); @@ -9,4 +10,4 @@ void fork_notify_terminate(PidRef *pidref); void fork_notify_terminate_many(sd_event_source **array, size_t n); -int journal_fork(RuntimeScope scope, char * const *units, PidRef *ret_pidref); +int journal_fork(RuntimeScope scope, char * const *units, OutputMode output, PidRef *ret_pidref); diff --git a/src/systemctl/systemctl-start-unit.c b/src/systemctl/systemctl-start-unit.c index 0c8582bdff7..1b6dbd8b140 100644 --- a/src/systemctl/systemctl-start-unit.c +++ b/src/systemctl/systemctl-start-unit.c @@ -402,7 +402,7 @@ int verb_start(int argc, char *argv[], uintptr_t _data, void *userdata) { ret = enqueue_marked_jobs(bus, w); else { if (arg_verbose) - (void) journal_fork(arg_runtime_scope, names, &journal_pid); + (void) journal_fork(arg_runtime_scope, names, arg_output, &journal_pid); STRV_FOREACH(name, names) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;