diff --git a/man/standard-options.xml b/man/standard-options.xml index 75e91862f4..eb27f5cb65 100644 --- a/man/standard-options.xml +++ b/man/standard-options.xml @@ -74,6 +74,16 @@ + + + + + Copy the contents of config files to standard output. Only the "interesting" parts of the + configuration files are printed, comments and empty lines are skipped. Before each file, the filename + is printed as a comment. + + + MODE diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml index d3a1de9a91..5b7f22c87c 100644 --- a/man/systemd-analyze.xml +++ b/man/systemd-analyze.xml @@ -1470,6 +1470,16 @@ NR NAME SHA256 + + + + With cat-config, only print the "interesting" parts of the + configuration files, skipping comments and empty lines and section headers followed only by + comments and empty lines. + + + + diff --git a/man/systemd-binfmt.service.xml b/man/systemd-binfmt.service.xml index b52b58494e..15453fae29 100644 --- a/man/systemd-binfmt.service.xml +++ b/man/systemd-binfmt.service.xml @@ -52,6 +52,7 @@ + diff --git a/man/systemd-sysctl.service.xml b/man/systemd-sysctl.service.xml index 7a66e59e6e..4c63ed1723 100644 --- a/man/systemd-sysctl.service.xml +++ b/man/systemd-sysctl.service.xml @@ -78,6 +78,7 @@ + diff --git a/man/systemd-sysusers.xml b/man/systemd-sysusers.xml index b8b811bb5e..3dfe8c006a 100644 --- a/man/systemd-sysusers.xml +++ b/man/systemd-sysusers.xml @@ -139,6 +139,7 @@ + diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index c048927882..95e1e2951c 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -250,6 +250,7 @@ + diff --git a/src/analyze/analyze-cat-config.c b/src/analyze/analyze-cat-config.c index 08184cedfe..66bbbc1102 100644 --- a/src/analyze/analyze-cat-config.c +++ b/src/analyze/analyze-cat-config.c @@ -35,7 +35,7 @@ int verb_cat_config(int argc, char *argv[], void *userdata) { } else t = *arg; - r = conf_files_cat(arg_root, t); + r = conf_files_cat(arg_root, t, arg_cat_flags); if (r < 0) return r; } diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index b7c852a08c..1b96e8b69a 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -91,6 +91,7 @@ DotMode arg_dot = DEP_ALL; char **arg_dot_from_patterns = NULL, **arg_dot_to_patterns = NULL; usec_t arg_fuzz = 0; PagerFlags arg_pager_flags = 0; +CatFlags arg_cat_flags = 0; BusTransport arg_transport = BUS_TRANSPORT_LOCAL; const char *arg_host = NULL; RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM; @@ -270,6 +271,7 @@ static int help(int argc, char *argv[], void *userdata) { " -h --help Show this help\n" " --version Show package version\n" " -q --quiet Do not emit hints\n" + " --tldr Skip comments and empty lines\n" " --root=PATH Operate on an alternate filesystem root\n" " --image=PATH Operate on disk image as filesystem root\n" " --image-policy=POLICY Specify disk image dissection policy\n" @@ -313,6 +315,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_PROFILE, ARG_TABLE, ARG_NO_LEGEND, + ARG_TLDR, }; static const struct option options[] = { @@ -346,6 +349,7 @@ static int parse_argv(int argc, char *argv[]) { { "profile", required_argument, NULL, ARG_PROFILE }, { "table", optional_argument, NULL, ARG_TABLE }, { "no-legend", optional_argument, NULL, ARG_NO_LEGEND }, + { "tldr", no_argument, NULL, ARG_TLDR }, {} }; @@ -535,6 +539,10 @@ static int parse_argv(int argc, char *argv[]) { arg_legend = false; break; + case ARG_TLDR: + arg_cat_flags = CAT_TLDR; + break; + case '?': return -EINVAL; diff --git a/src/analyze/analyze.h b/src/analyze/analyze.h index 84575cd9a9..8a9528c0d3 100644 --- a/src/analyze/analyze.h +++ b/src/analyze/analyze.h @@ -7,6 +7,7 @@ #include "bus-util.h" #include "json.h" #include "pager.h" +#include "pretty-print.h" #include "time-util.h" #include "unit-file.h" @@ -20,6 +21,7 @@ extern DotMode arg_dot; extern char **arg_dot_from_patterns, **arg_dot_to_patterns; extern usec_t arg_fuzz; extern PagerFlags arg_pager_flags; +extern CatFlags arg_cat_flags; extern BusTransport arg_transport; extern const char *arg_host; extern RuntimeScope arg_runtime_scope; diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c index 817d593c23..d21f3f79ff 100644 --- a/src/binfmt/binfmt.c +++ b/src/binfmt/binfmt.c @@ -24,7 +24,7 @@ #include "string-util.h" #include "strv.h" -static bool arg_cat_config = false; +static CatFlags arg_cat_flags = CAT_CONFIG_OFF; static PagerFlags arg_pager_flags = 0; static bool arg_unregister = false; @@ -104,6 +104,12 @@ static int apply_file(const char *filename, bool ignore_enoent) { return r; } +static int cat_config(char **files) { + pager_open(arg_pager_flags); + + return cat_files(NULL, files, arg_cat_flags); +} + static int help(void) { _cleanup_free_ char *link = NULL; int r; @@ -117,6 +123,7 @@ static int help(void) { " -h --help Show this help\n" " --version Show package version\n" " --cat-config Show configuration files\n" + " --tldr Show non-comment parts of configuration\n" " --no-pager Do not pipe output into a pager\n" " --unregister Unregister all existing entries\n" "\nSee the %s for details.\n", @@ -130,6 +137,7 @@ static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_CAT_CONFIG, + ARG_TLDR, ARG_NO_PAGER, ARG_UNREGISTER, }; @@ -138,6 +146,7 @@ static int parse_argv(int argc, char *argv[]) { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "cat-config", no_argument, NULL, ARG_CAT_CONFIG }, + { "tldr", no_argument, NULL, ARG_TLDR }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "unregister", no_argument, NULL, ARG_UNREGISTER }, {} @@ -159,7 +168,11 @@ static int parse_argv(int argc, char *argv[]) { return version(); case ARG_CAT_CONFIG: - arg_cat_config = true; + arg_cat_flags = CAT_CONFIG_ON; + break; + + case ARG_TLDR: + arg_cat_flags = CAT_TLDR; break; case ARG_NO_PAGER: @@ -177,9 +190,9 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached(); } - if ((arg_unregister || arg_cat_config) && argc > optind) + if ((arg_unregister || arg_cat_flags != CAT_CONFIG_OFF) && argc > optind) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Positional arguments are not allowed with --cat-config or --unregister"); + "Positional arguments are not allowed with --cat-config/--tldr or --unregister."); return 1; } @@ -227,11 +240,8 @@ static int run(int argc, char *argv[]) { if (r < 0) return log_error_errno(r, "Failed to enumerate binfmt.d files: %m"); - if (arg_cat_config) { - pager_open(arg_pager_flags); - - return cat_files(NULL, files, 0); - } + if (arg_cat_flags != CAT_CONFIG_OFF) + return cat_config(files); r = binfmt_mounted_warn(); if (r <= 0) diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index c9800282a5..3eadb5f4e7 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -1537,7 +1537,7 @@ static int cat_settings(int argc, char *argv[], void *userdata) { "Invalid settings file path '%s'.", *name); - q = cat_files(*name, /* dropins = */ NULL, /* flags = */ 0); + q = cat_files(*name, /* dropins = */ NULL, /* flags = */ CAT_FORMAT_HAS_SECTIONS); if (q < 0) return r < 0 ? r : q; continue; @@ -1558,7 +1558,7 @@ static int cat_settings(int argc, char *argv[], void *userdata) { return r < 0 ? r : q; } - q = cat_files(path, /* dropins = */ NULL, /* flags = */ 0); + q = cat_files(path, /* dropins = */ NULL, /* flags = */ CAT_FORMAT_HAS_SECTIONS); if (q < 0) return r < 0 ? r : q; } diff --git a/src/network/networkctl.c b/src/network/networkctl.c index 5d961b6c83..48b0f2eca0 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -3298,7 +3298,7 @@ static int verb_cat(int argc, char *argv[], void *userdata) { } } - r = cat_files(path, dropins, /* flags = */ 0); + r = cat_files(path, dropins, /* flags = */ CAT_FORMAT_HAS_SECTIONS); if (r < 0) return ret < 0 ? ret : r; } diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c index a354ae4983..e31edb88b0 100644 --- a/src/shared/pretty-print.c +++ b/src/shared/pretty-print.c @@ -131,9 +131,25 @@ int terminal_urlify_man(const char *page, const char *section, char **ret) { return terminal_urlify(url, text, ret); } -static int cat_file(const char *filename, bool newline) { +typedef enum { + LINE_SECTION, + LINE_COMMENT, + LINE_NORMAL, +} LineType; + +static LineType classify_line_type(const char *line, CatFlags flags) { + const char *t = skip_leading_chars(line, WHITESPACE); + + if ((flags & CAT_FORMAT_HAS_SECTIONS) && *t == '[') + return LINE_SECTION; + if (IN_SET(*t, '#', ';', '\0')) + return LINE_COMMENT; + return LINE_NORMAL; +} + +static int cat_file(const char *filename, bool newline, CatFlags flags) { _cleanup_fclose_ FILE *f = NULL; - _cleanup_free_ char *urlified = NULL; + _cleanup_free_ char *urlified = NULL, *section = NULL, *old_section = NULL; int r; f = fopen(filename, "re"); @@ -160,7 +176,36 @@ static int cat_file(const char *filename, bool newline) { if (r == 0) break; - puts(line); + LineType line_type = classify_line_type(line, flags); + if (flags & CAT_TLDR) { + if (line_type == LINE_SECTION) { + /* The start of a section, let's not print it yet. */ + free_and_replace(section, line); + continue; + } + + if (line_type == LINE_COMMENT) + continue; + + /* Before we print the actual line, print the last section header */ + if (section) { + /* Do not print redundant section headers */ + if (!streq_ptr(section, old_section)) + printf("%s%s%s\n", + ansi_highlight_cyan(), + section, + ansi_normal()); + + free_and_replace(old_section, section); + } + } + + printf("%s%s%s\n", + line_type == LINE_SECTION ? ansi_highlight_cyan() : + line_type == LINE_COMMENT ? ansi_highlight_grey() : + "", + line, + line_type != LINE_NORMAL ? ansi_normal() : ""); } return 0; @@ -170,18 +215,13 @@ int cat_files(const char *file, char **dropins, CatFlags flags) { int r; if (file) { - r = cat_file(file, false); - if (r == -ENOENT && (flags & CAT_FLAGS_MAIN_FILE_OPTIONAL)) - printf("%s# Configuration file %s not found%s\n", - ansi_highlight_magenta(), - file, - ansi_normal()); - else if (r < 0) + r = cat_file(file, /* newline= */ false, flags); + if (r < 0) return log_warning_errno(r, "Failed to cat %s: %m", file); } STRV_FOREACH(path, dropins) { - r = cat_file(*path, file || path != dropins); + r = cat_file(*path, /* newline= */ file || path != dropins, flags); if (r < 0) return log_warning_errno(r, "Failed to cat %s: %m", *path); } @@ -213,7 +253,10 @@ void print_separator(void) { static int guess_type(const char **name, char ***prefixes, bool *is_collection, const char **extension) { /* Try to figure out if name is like tmpfiles.d/ or systemd/system-presets/, - * i.e. a collection of directories without a main config file. */ + * i.e. a collection of directories without a main config file. + * Incidentally, all those formats don't use sections. So we return a single + * is_collection boolean, which also means that the format doesn't use sections. + */ _cleanup_free_ char *n = NULL; bool usr = false, run = false, coll = false; @@ -279,7 +322,7 @@ static int guess_type(const char **name, char ***prefixes, bool *is_collection, return 0; } -int conf_files_cat(const char *root, const char *name) { +int conf_files_cat(const char *root, const char *name, CatFlags flags) { _cleanup_strv_free_ char **dirs = NULL, **files = NULL; _cleanup_free_ char *path = NULL; char **prefixes = NULL; /* explicit initialization to appease gcc */ @@ -335,5 +378,8 @@ int conf_files_cat(const char *root, const char *name) { return log_error_errno(r, "Failed to query file list: %m"); /* Show */ - return cat_files(path, files, 0); + if (is_collection) + flags |= CAT_FORMAT_HAS_SECTIONS; + + return cat_files(path, files, flags); } diff --git a/src/shared/pretty-print.h b/src/shared/pretty-print.h index 45644da67d..b25684aaa6 100644 --- a/src/shared/pretty-print.h +++ b/src/shared/pretty-print.h @@ -15,11 +15,14 @@ int terminal_urlify_path(const char *path, const char *text, char **ret); int terminal_urlify_man(const char *page, const char *section, char **ret); typedef enum CatFlags { - CAT_FLAGS_MAIN_FILE_OPTIONAL = 1 << 0, + CAT_CONFIG_OFF = 0, + CAT_CONFIG_ON = 1 << 0, + CAT_FORMAT_HAS_SECTIONS = 1 << 1, /* Sections are meaningful for this file format */ + CAT_TLDR = 1 << 2, /* Only print comments and relevant section headers */ } CatFlags; int cat_files(const char *file, char **dropins, CatFlags flags); -int conf_files_cat(const char *root, const char *name); +int conf_files_cat(const char *root, const char *name, CatFlags flags); #define RED_CROSS_MARK_MAX (STRLEN(ANSI_HIGHLIGHT_RED) + STRLEN("✗") + STRLEN(ANSI_NORMAL) + 1) #define GREEN_CHECK_MARK_MAX (STRLEN(ANSI_HIGHLIGHT_GREEN) + STRLEN("✓") + STRLEN(ANSI_NORMAL) + 1) diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c index 3e1f79887d..aac965f5de 100644 --- a/src/sysctl/sysctl.c +++ b/src/sysctl/sysctl.c @@ -28,7 +28,7 @@ #include "sysctl-util.h" static char **arg_prefixes = NULL; -static bool arg_cat_config = false; +static CatFlags arg_cat_flags = CAT_CONFIG_OFF; static bool arg_strict = false; static PagerFlags arg_pager_flags = 0; @@ -331,6 +331,12 @@ static int read_credential_lines(OrderedHashmap **sysctl_options) { return 0; } +static int cat_config(char **files) { + pager_open(arg_pager_flags); + + return cat_files(NULL, files, arg_cat_flags); +} + static int help(void) { _cleanup_free_ char *link = NULL; int r; @@ -344,6 +350,7 @@ static int help(void) { " -h --help Show this help\n" " --version Show package version\n" " --cat-config Show configuration files\n" + " --tldr Show non-comment parts of configuration\n" " --prefix=PATH Only apply rules with the specified prefix\n" " --no-pager Do not pipe output into a pager\n" "\nSee the %s for details.\n", @@ -358,6 +365,7 @@ static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_CAT_CONFIG, + ARG_TLDR, ARG_PREFIX, ARG_NO_PAGER, ARG_STRICT, @@ -367,6 +375,7 @@ static int parse_argv(int argc, char *argv[]) { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "cat-config", no_argument, NULL, ARG_CAT_CONFIG }, + { "tldr", no_argument, NULL, ARG_TLDR }, { "prefix", required_argument, NULL, ARG_PREFIX }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "strict", no_argument, NULL, ARG_STRICT }, @@ -389,7 +398,11 @@ static int parse_argv(int argc, char *argv[]) { return version(); case ARG_CAT_CONFIG: - arg_cat_config = true; + arg_cat_flags = CAT_CONFIG_ON; + break; + + case ARG_TLDR: + arg_cat_flags = CAT_TLDR; break; case ARG_PREFIX: { @@ -428,9 +441,9 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached(); } - if (arg_cat_config && argc > optind) + if (arg_cat_flags != CAT_CONFIG_OFF && argc > optind) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Positional arguments are not allowed with --cat-config"); + "Positional arguments are not allowed with --cat-config/--tldr."); return 1; } @@ -460,11 +473,8 @@ static int run(int argc, char *argv[]) { if (r < 0) return log_error_errno(r, "Failed to enumerate sysctl.d files: %m"); - if (arg_cat_config) { - pager_open(arg_pager_flags); - - return cat_files(NULL, files, 0); - } + if (arg_cat_flags != CAT_CONFIG_OFF) + return cat_config(files); STRV_FOREACH(f, files) RET_GATHER(r, parse_file(&sysctl_options, *f, true)); diff --git a/src/systemctl/systemctl-edit.c b/src/systemctl/systemctl-edit.c index ac0bbb4542..367afa20f7 100644 --- a/src/systemctl/systemctl-edit.c +++ b/src/systemctl/systemctl-edit.c @@ -93,7 +93,7 @@ int verb_cat(int argc, char *argv[], void *userdata) { arg_runtime_scope == RUNTIME_SCOPE_SYSTEM ? "" : " --user", ansi_normal()); - r = cat_files(fragment_path, dropin_paths, 0); + r = cat_files(fragment_path, dropin_paths, /* flags= */ CAT_FORMAT_HAS_SECTIONS); if (r < 0) return r; } diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index c0deae1165..8376868136 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -94,7 +94,7 @@ typedef struct Item { static char *arg_root = NULL; static char *arg_image = NULL; -static bool arg_cat_config = false; +static CatFlags arg_cat_flags = CAT_CONFIG_OFF; static const char *arg_replace = NULL; static bool arg_dry_run = false; static bool arg_inline = false; @@ -2042,7 +2042,7 @@ static int cat_config(void) { pager_open(arg_pager_flags); - return cat_files(NULL, files, 0); + return cat_files(NULL, files, arg_cat_flags); } static int help(void) { @@ -2058,6 +2058,7 @@ static int help(void) { " -h --help Show this help\n" " --version Show package version\n" " --cat-config Show configuration files\n" + " --tldr Show non-comment parts of configuration\n" " --root=PATH Operate on an alternate filesystem root\n" " --image=PATH Operate on disk image as filesystem root\n" " --image-policy=POLICY Specify disk image dissection policy\n" @@ -2077,6 +2078,7 @@ static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_CAT_CONFIG, + ARG_TLDR, ARG_ROOT, ARG_IMAGE, ARG_IMAGE_POLICY, @@ -2090,6 +2092,7 @@ static int parse_argv(int argc, char *argv[]) { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "cat-config", no_argument, NULL, ARG_CAT_CONFIG }, + { "tldr", no_argument, NULL, ARG_TLDR }, { "root", required_argument, NULL, ARG_ROOT }, { "image", required_argument, NULL, ARG_IMAGE }, { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY }, @@ -2116,7 +2119,11 @@ static int parse_argv(int argc, char *argv[]) { return version(); case ARG_CAT_CONFIG: - arg_cat_config = true; + arg_cat_flags = CAT_CONFIG_ON; + break; + + case ARG_TLDR: + arg_cat_flags = CAT_TLDR; break; case ARG_ROOT: @@ -2170,16 +2177,17 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached(); } - if (arg_replace && arg_cat_config) + if (arg_replace && arg_cat_flags != CAT_CONFIG_OFF) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Option --replace= is not supported with --cat-config"); + "Option --replace= is not supported with --cat-config/--tldr."); if (arg_replace && optind >= argc) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "When --replace= is given, some configuration items must be specified"); + "When --replace= is given, some configuration items must be specified."); if (arg_image && arg_root) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported."); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Use either --root= or --image=, the combination of both is not supported."); return 1; } @@ -2273,7 +2281,7 @@ static int run(int argc, char *argv[]) { log_setup(); - if (arg_cat_config) + if (arg_cat_flags != CAT_CONFIG_OFF) return cat_config(); umask(0022); diff --git a/src/test/test-pretty-print.c b/src/test/test-pretty-print.c index 7c6c6c7ad1..ece1a161e4 100644 --- a/src/test/test-pretty-print.c +++ b/src/test/test-pretty-print.c @@ -25,7 +25,7 @@ TEST(terminal_urlify) { TEST(cat_files) { assert_se(cat_files("/no/such/file", NULL, 0) == -ENOENT); - assert_se(cat_files("/no/such/file", NULL, CAT_FLAGS_MAIN_FILE_OPTIONAL) == 0); + assert_se(cat_files(NULL, NULL, 0) == 0); if (access("/etc/fstab", R_OK) >= 0) assert_se(cat_files("/etc/fstab", STRV_MAKE("/etc/fstab", "/etc/fstab"), 0) == 0); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 93ac53792f..e1416b2ceb 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -196,7 +196,7 @@ typedef enum { _CREATION_MODE_INVALID = -EINVAL, } CreationMode; -static bool arg_cat_config = false; +static CatFlags arg_cat_flags = CAT_CONFIG_OFF; static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM; static OperationMask arg_operation = 0; static bool arg_boot = false; @@ -3936,7 +3936,9 @@ static int cat_config(char **config_dirs, char **args) { if (r < 0) return r; - return cat_files(NULL, files, 0); + pager_open(arg_pager_flags); + + return cat_files(NULL, files, arg_cat_flags); } static int exclude_default_prefixes(void) { @@ -3974,6 +3976,7 @@ static int help(void) { " --user Execute user configuration\n" " --version Show package version\n" " --cat-config Show configuration files\n" + " --tldr Show non-comment parts of configuration\n" " --create Create marked files/directories\n" " --clean Clean up marked directories\n" " --remove Remove marked files/directories\n" @@ -4001,6 +4004,7 @@ static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_CAT_CONFIG, + ARG_TLDR, ARG_USER, ARG_CREATE, ARG_CLEAN, @@ -4021,6 +4025,7 @@ static int parse_argv(int argc, char *argv[]) { { "user", no_argument, NULL, ARG_USER }, { "version", no_argument, NULL, ARG_VERSION }, { "cat-config", no_argument, NULL, ARG_CAT_CONFIG }, + { "tldr", no_argument, NULL, ARG_TLDR }, { "create", no_argument, NULL, ARG_CREATE }, { "clean", no_argument, NULL, ARG_CLEAN }, { "remove", no_argument, NULL, ARG_REMOVE }, @@ -4052,7 +4057,11 @@ static int parse_argv(int argc, char *argv[]) { return version(); case ARG_CAT_CONFIG: - arg_cat_config = true; + arg_cat_flags = CAT_CONFIG_ON; + break; + + case ARG_TLDR: + arg_cat_flags = CAT_TLDR; break; case ARG_USER: @@ -4140,17 +4149,17 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached(); } - if (arg_operation == 0 && !arg_cat_config) + if (arg_operation == 0 && arg_cat_flags == CAT_CONFIG_OFF) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "You need to specify at least one of --clean, --create or --remove."); + "You need to specify at least one of --clean, --create, or --remove."); - if (arg_replace && arg_cat_config) + if (arg_replace && arg_cat_flags != CAT_CONFIG_OFF) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Option --replace= is not supported with --cat-config"); + "Option --replace= is not supported with --cat-config/--tldr."); if (arg_replace && optind >= argc) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "When --replace= is given, some configuration items must be specified"); + "When --replace= is given, some configuration items must be specified."); if (arg_root && arg_runtime_scope == RUNTIME_SCOPE_USER) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -4453,11 +4462,8 @@ static int run(int argc, char *argv[]) { log_debug("Looking for configuration files in (higher priority first):%s", t); } - if (arg_cat_config) { - pager_open(arg_pager_flags); - + if (arg_cat_flags != CAT_CONFIG_OFF) return cat_config(config_dirs, argv + optind); - } umask(0022); diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh index 6202b38660..d76eb1a2eb 100755 --- a/test/units/testsuite-65.sh +++ b/test/units/testsuite-65.sh @@ -165,6 +165,11 @@ systemd-analyze cat-config /etc/systemd/system.conf >/dev/null systemd-analyze cat-config systemd/system.conf systemd/journald.conf >/dev/null systemd-analyze cat-config systemd/system.conf foo/bar systemd/journald.conf >/dev/null systemd-analyze cat-config foo/bar +systemd-analyze cat-config --tldr systemd/system.conf >/dev/null +systemd-analyze cat-config --tldr /etc/systemd/system.conf >/dev/null +systemd-analyze cat-config --tldr systemd/system.conf systemd/journald.conf >/dev/null +systemd-analyze cat-config --tldr systemd/system.conf foo/bar systemd/journald.conf >/dev/null +systemd-analyze cat-config --tldr foo/bar # security systemd-analyze security systemd-analyze security --json=off