]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: teach udevadm --property=NAME and --value options 20871/head
authorFrantisek Sumsal <frantisek@sumsal.cz>
Tue, 28 Sep 2021 19:18:08 +0000 (21:18 +0200)
committerFrantisek Sumsal <frantisek@sumsal.cz>
Wed, 29 Sep 2021 11:32:25 +0000 (13:32 +0200)
which allows limiting the properties listed by the `--query=property` option
(and optionally listing only the respective values).

man/udevadm.xml
shell-completion/bash/udevadm
shell-completion/zsh/_udevadm
src/udev/udevadm-info.c

index 2704156840c384bb9a28af3907db32a70f87cf01..6091a3421ff2cf3ae8217a8b1e3cb82b57170079 100644 (file)
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><option>--property=<replaceable>NAME</replaceable></option></term>
+          <listitem>
+            <para>When showing device properties using the <option>--query=property</option>
+            option, limit display to properties specified in the argument. The argument should
+            be a comma-separated list of property names. If not specified, all known properties
+            are shown.</para>
+          </listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--value</option></term>
+          <listitem>
+            <para>When showing device properties using the <option>--query=property</option>
+            option, print only their values, and skip the property name and <literal>=</literal>.</para>
+            <para>Cannot be used together with <option>-x/--export</option> or
+            <option>-P/--export-prefix</option>.</para>
+          </listitem>
+        </varlistentry>
         <varlistentry>
           <term><option>-p</option></term>
           <term><option>--path=<replaceable>DEVPATH</replaceable></option></term>
index 42103668084f203f4ace50fb85296dc035593a98..08b4ab43a0e6e556fa4ae0bb64d2a577bb979e1f 100644 (file)
@@ -49,8 +49,8 @@ _udevadm() {
         [COMMON]='-h --help -V --version'
         [DEBUG]='-d --debug'
         [INFO_STANDALONE]='-r --root -a --attribute-walk -x --export -e --export-db -c --cleanup-db
-                           -w --wait-for-initialization'
-        [INFO_ARG]='-q --query -p --path -n --name -P --export-prefix -d --device-id-of-file'
+                           -w --wait-for-initialization --value'
+        [INFO_ARG]='-q --query -p --path -n --name -P --export-prefix -d --device-id-of-file --property'
         [TRIGGER_STANDALONE]='-v --verbose -n --dry-run -q --quiet -w --settle --wait-daemon --uuid'
         [TRIGGER_ARG]='-t --type -c --action -s --subsystem-match -S --subsystem-nomatch
                        -a --attr-match -A --attr-nomatch -p --property-match
index 1179f81a8bfa1a30898b7de21d284ac1656518aa..eac56c704848aaf5f4f0610061f928fe821d0e7e 100644 (file)
@@ -13,7 +13,9 @@ _udevadm_info(){
         '--export-prefix=[Add a prefix to the key name of exported values.]:prefix' \
         '--device-id-of-file=[Print major/minor numbers of the underlying device, where the file lives on.]:files:_udevadm_mounts' \
         '--export-db[Export the content of the udev database.]' \
-        '--cleanup-db[Cleanup the udev database.]'
+        '--cleanup-db[Cleanup the udev database.]' \
+        '--value[When showing properties, print only their values.]' \
+        '--property=[Show only properties by this name.]'
 }
 
 (( $+functions[_udevadm_trigger] )) ||
index 85f826690ca88c627e26af80916ad972b0e2e879..84f7794e86fb7b9ae5a0b0978d4d35b8b5da23f1 100644 (file)
@@ -18,6 +18,7 @@
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "sort-util.h"
+#include "static-destruct.h"
 #include "string-table.h"
 #include "string-util.h"
 #include "udev-util.h"
@@ -38,8 +39,10 @@ typedef enum QueryType {
         QUERY_ALL,
 } QueryType;
 
+static char **arg_properties = NULL;
 static bool arg_root = false;
 static bool arg_export = false;
+static bool arg_value = false;
 static const char *arg_export_prefix = NULL;
 static usec_t arg_wait_for_initialization_timeout = 0;
 
@@ -60,6 +63,8 @@ typedef struct SysAttr {
         const char *value;
 } SysAttr;
 
+STATIC_DESTRUCTOR_REGISTER(arg_properties, strv_freep);
+
 static int sysattr_compare(const SysAttr *a, const SysAttr *b) {
         return strcmp(a->name, b->name);
 }
@@ -316,11 +321,18 @@ static int query_device(QueryType query, sd_device* device) {
         case QUERY_PROPERTY: {
                 const char *key, *value;
 
-                FOREACH_DEVICE_PROPERTY(device, key, value)
+                FOREACH_DEVICE_PROPERTY(device, key, value) {
+                        if (arg_properties && !strv_contains(arg_properties, key))
+                                continue;
+
                         if (arg_export)
                                 printf("%s%s='%s'\n", strempty(arg_export_prefix), key, value);
+                        else if (arg_value)
+                                printf("%s\n", value);
                         else
                                 printf("%s=%s\n", key, value);
+                }
+
                 return 0;
         }
 
@@ -343,6 +355,8 @@ static int help(void) {
                "       path                     sysfs device path\n"
                "       property                 The device properties\n"
                "       all                      All values\n"
+               "     --property=NAME          Show only properties by this name\n"
+               "     --value                  When showing properties, print only their values\n"
                "  -p --path=SYSPATH           sysfs device path used for query or attribute walk\n"
                "  -n --name=NAME              Node or symlink name used for query or attribute walk\n"
                "  -r --root                   Prepend dev directory to path names\n"
@@ -365,20 +379,27 @@ int info_main(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *name = NULL;
         int c, r;
 
+        enum {
+                ARG_PROPERTY = 0x100,
+                ARG_VALUE,
+        };
+
         static const struct option options[] = {
-                { "attribute-walk",          no_argument,       NULL, 'a' },
-                { "cleanup-db",              no_argument,       NULL, 'c' },
-                { "device-id-of-file",       required_argument, NULL, 'd' },
-                { "export",                  no_argument,       NULL, 'x' },
-                { "export-db",               no_argument,       NULL, 'e' },
-                { "export-prefix",           required_argument, NULL, 'P' },
-                { "help",                    no_argument,       NULL, 'h' },
-                { "name",                    required_argument, NULL, 'n' },
-                { "path",                    required_argument, NULL, 'p' },
-                { "query",                   required_argument, NULL, 'q' },
-                { "root",                    no_argument,       NULL, 'r' },
-                { "version",                 no_argument,       NULL, 'V' },
-                { "wait-for-initialization", optional_argument, NULL, 'w' },
+                { "attribute-walk",          no_argument,       NULL, 'a'          },
+                { "cleanup-db",              no_argument,       NULL, 'c'          },
+                { "device-id-of-file",       required_argument, NULL, 'd'          },
+                { "export",                  no_argument,       NULL, 'x'          },
+                { "export-db",               no_argument,       NULL, 'e'          },
+                { "export-prefix",           required_argument, NULL, 'P'          },
+                { "help",                    no_argument,       NULL, 'h'          },
+                { "name",                    required_argument, NULL, 'n'          },
+                { "path",                    required_argument, NULL, 'p'          },
+                { "property",                required_argument, NULL, ARG_PROPERTY },
+                { "query",                   required_argument, NULL, 'q'          },
+                { "root",                    no_argument,       NULL, 'r'          },
+                { "value",                   no_argument,       NULL, ARG_VALUE    },
+                { "version",                 no_argument,       NULL, 'V'          },
+                { "wait-for-initialization", optional_argument, NULL, 'w'          },
                 {}
         };
 
@@ -387,6 +408,22 @@ int info_main(int argc, char *argv[], void *userdata) {
 
         while ((c = getopt_long(argc, argv, "aced:n:p:q:rxP:w::Vh", options, NULL)) >= 0)
                 switch (c) {
+                case ARG_PROPERTY:
+                        /* Make sure that if the empty property list was specified, we won't show any
+                           properties. */
+                        if (isempty(optarg) && !arg_properties) {
+                                arg_properties = new0(char*, 1);
+                                if (!arg_properties)
+                                        return log_oom();
+                        } else {
+                                r = strv_split_and_extend(&arg_properties, optarg, ",", true);
+                                if (r < 0)
+                                        return log_oom();
+                        }
+                        break;
+                case ARG_VALUE:
+                        arg_value = true;
+                        break;
                 case 'n':
                 case 'p': {
                         const char *prefix = c == 'n' ? "/dev/" : "/sys/";
@@ -478,6 +515,10 @@ int info_main(int argc, char *argv[], void *userdata) {
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Only one device may be specified with -a/--attribute-walk");
 
+        if (arg_export && arg_value)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "-x/--export or -P/--export-prefix cannot be used with --value");
+
         char **p;
         STRV_FOREACH(p, devices) {
                 _cleanup_(sd_device_unrefp) sd_device *device = NULL;