Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm trying to get every user using dscl and reading each of their records using xargs and dscl. I'm not sure what I'm doing wrong, though, because I would expect this command to take each line of output and place it where {} is.

2rs2ts:~/ $ dscl . -list /Users | xargs -n1I'{}' dscl -plist . -read /Users/{}
<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)
<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)
<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)
<dscl_cmd> DS Error: -14136 (eDSRecordNotFound)
... and so forth

The output of the first command seems just fine...

2rs2ts:~/ $ dscl . -list /Users
... and so forth

I even pipe that to xargs -n1 echo and it seems fine. I echo something else first and it works as expected. I've also tried using -L1 instead, but to no avail. What am I missing?

I am aware I can use -readall for this, but, I was just trying to use xargs for fun.

share|improve this question
up vote 1 down vote accepted

The problem is -n1I'{}'. You want to split those two options, otherwise xargs can't parse them correctly. Basically, after each option-argument (1 and '{}' in your case), you need a whitespace separator:

dscl . -list /Users | xargs -n1 -I'{}' dscl -plist . -read /Users/{}

Or, if you just want to use a simple loop:

for user in $(dscl . -list /Users); do dscl -plist . -read /Users/"$user"; done

With while read, you can use process substitution:

while read user; do dscl -plist . -read /Users/"$user"; done < <(dscl . -list /Users)

… or you pipe it:

dscl . -list /Users | while read user; do dscl -plist . -read /Users/"$user"; done
share|improve this answer
Weird. I guess in all the combinations I tried I never did the right thing, and I must have excluded possibilities because I thought they'd be redundant. Thanks! By the way, your second answer also works and it's very similar to this answer on Unix.stackexchange but it actually works whereas that one did not. – 2rs2ts Jul 17 '13 at 19:13
The < only works for files. If you want it to use arbitrary input from a command, you need process substitution (see my updated answer). – slhck Jul 17 '13 at 19:26
That user gave an example with a pipe, though. I'm confused. – 2rs2ts Jul 17 '13 at 20:00
Sorry, I only looked at the second example. First one works as well, I appended it to my answer. – slhck Jul 17 '13 at 20:09
I must have been doing something wrong without noticing it earlier, because that pipe example (except for calling it line instead as per the linked example) didn't work for me before! Thank you nonetheless. – 2rs2ts Jul 17 '13 at 20:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .