0

I've just found this command:

upower -e 

that displays a list of files that can be used with upower -i to display plugged device status.

So my first try was using:

upower -e | xargs upower -i 

but it doesn't work. So I've tried:

$ upower -e | xargs echo /org/freedesktop/UPower/devices/line_power_AC /org/freedesktop/UPower/devices/battery_BAT0 /org/freedesktop/UPower/devices/line_power_ucsi_source_psy_USBC000o001 /org/freedesktop/UPower/devices/DisplayDevice 

and it display all files in single line. So I've used:

$ upower -e | xargs -0 echo /org/freedesktop/UPower/devices/line_power_AC /org/freedesktop/UPower/devices/battery_BAT0 /org/freedesktop/UPower/devices/line_power_ucsi_source_psy_USBC000o001 /org/freedesktop/UPower/devices/DisplayDevice 

it works but displays one empty line, but this doesn't work:

$ upower -e | xargs -0 upower -i failed to set path: Object path invalid: /org/freedesktop/UPower/devices/line_power_AC /org/freedesktop/UPower/devices/battery_BAT0 /org/freedesktop/UPower/devices/line_power_ucsi_source_psy_USBC000o001 /org/freedesktop/UPower/devices/DisplayDevice 

Why upower -e | xargs upower -i doesn't work? I'm using Bash on Fedora.

Is there something I'm missing here?

EDIT:

This seems to work:

upower -e | xargs -I {} upower -i "{}" 

But I'm wondering: why a quote is needed if the filename doesn't have spaces?

7
  • Possibly upower -i can only handle a single object path at a time? Try upower -e | xargs -L 1 upower -i Commented Apr 10, 2022 at 18:36
  • @steeldriver got an answer on Twitter from the original author that posted this command, and it shows xargs -I {} works, but the files don't have spaces, then why this is needed? Commented Apr 10, 2022 at 18:38
  • -I isn't really needed, but it implies -L1 as a side effect - that's what's really making the difference here I think Commented Apr 10, 2022 at 18:40
  • ... because the LHS should be upower -e presumably? upower -i needs an input path Commented Apr 10, 2022 at 18:45
  • @steeldriver Yes it was my mistake that I've just noticed, I've deleted that from my edit and comment. Commented Apr 10, 2022 at 18:46

1 Answer 1

2

upower -e produces a newline-separated list of object paths.

When you used upower -e | xargs upower -i, the xargs command tokenized that on whitespace and passed all the paths to a single invocation of upower -i, which it was unable to handle.

You then tried upower -e | xargs echo, and noted that the output consisted of a single line - that's down to echo though, and does not tell you how the output of upower -e was delimited.

Next you tried upower -e | xargs -0 echo, which (since the output of upower -e is not null delimited) passed a single multi-line argument to echo, which happily printed it. Similarly upower -e | xargs -0 upower -i passed a single multi-line path to upower -i, which unsurprisingly barfed.

Finally you discovered upower -e | xargs -I {} upower -i "{}". Since -I implies -L, this passed each line of the upower -e output to a separate invocation of upower -i. You could have achieved the same with

upower -e | xargs -L upower -i 

Whitespace within the paths isn't a factor here, but if it was, you should tell xargs not only to read a single line per invocation, but also to tokenize it on newlines only:

upower -e | xargs -d '\n' -L upower -i 

or equivalently

upower -e | xargs -d '\n' -n 1 upower -i 

Quoting the replacement text {} probably isn't necessary either (regardless of whether the text itself contains whitespace) - see Quoting curly braces in the shell and the linked duplicate discussing the same issue in the context of find -exec

1
  • Didn't know about xargs -d '\n', it will be useful, most of the time I process lines with xargs. Commented Apr 10, 2022 at 19:19

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.