Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm running the following command on a fairly standard Ubuntu 11.04 installation running under vSphere:

sudo cat /home/*/.ssh/authorized_keys

Basically, I am using puppet for ssh key management and wanted to ensure the keys were present. What is unusual about this simple command is that the keys are only shown for two users (the first and third user created on the user if that is relevant) when the * should catch something like 7 or 8 users' homes.

The intriguing part is that, if I run

sudo cat /home/user.name/.ssh/authorized_keys

where user.name is the name of a random user (not one of the two that already show), not only do I get the correct output from cat, but the next time I run

sudo cat /home/*/.ssh/authorized_keys

the output shows 3 key files! Two files for the two users previously shown and a third file that is the user whose key file I just manually looked at.

I can continue to play this "game", and each time I manually specify a user and then run the * command, that previously viewed user shows up in the globbed output. To me, this is unusual behavior, especially for a bog-standard Ubuntu image. Is there something I am missing? Special properties of * expansion or cat?

Edit: Forgot to mention that this behavior "resets" if I leave the ssh session to the server. By that I mean that I can logout and log back in via SSH, and I am back to the starting conditions (only two user accounts are shown with *).

share|improve this question

2 Answers 2

up vote 3 down vote accepted

Remember that the command line is parsed and wildcards are replaced BEFORE it is executed.

If you specify the username, then the sudo ... command can see the file because it's accessing it as root.

When you type '*', your USER shell expands that to the paths it can see, well... the paths which allow your current user to search the subdirectories.

You might try enclosing the path string in SINGLE quotes to prevent expansion, I'm not sure that'll work since most unix programs expect the shell to expand wildcards and thus don't perform the globbing action themselves.

EDIT: A thought about how to accomplish your goal of reading the authorized keys files for all the users:

sudo find /home -name "authorized_keys" -exec cat "{}" \; > all_the_data

Maybe crude, but it'll work since you're executing the file search as root, not your user.

I suppose another way:

sudo 'find /home -name "authorized_keys" -print0 | xargs -0 cat' > all_the_data

That one's nicer on the process count, since it accumulates all the filenames and then 'cat's them... but I like the first one, no special quoting required.

The quotes (single or otherwise) around the entire command are required because of the pipe command. both the find and xargs command MUST be executed as root. Yeah, more complicated than the first one.

share|improve this answer
    
Your explanation of the reason for the strange globbing behavior is brilliant, +1, but I'm not entirely convinced. Why does the sudo cat /home/user.name/.ssh/authorized_keys command have the lasting side effect of affecting the output of subsequent commands containing the glob, when the glob command isn't able to see the contents prior to that direct cat? Is it because the shell caches the files it sees in there? –  ÃŁŁǫǛȉЖΦΤїҪ Jul 13 '12 at 2:11
1  
Okay, the 1st solution is within my knowledge of find. And I was about to ask you why the one user would show up (using *) while others wouldn't but I just discovered that the ssh folder for that user is 755 as opposed to the others that are 700. –  Richard Martinez Jul 13 '12 at 2:14
    
Add.: It just seems odd to me that look at some files that only root can see; followed by look at files that my user can see results in the latter command "knowing" about the directory structure by virtue of the former command successfully stating that directory. Especially since the "direct" (non-globbed) method doesn't involve ANY shell expansion whatsoever, so the shell is not finding that directory; the cat command is! Within a sudo instance at that!!! –  ÃŁŁǫǛȉЖΦΤїҪ Jul 13 '12 at 2:15
    
I can't explain the lasting side effect, although since it 'resets' when you log off, it might be related to the sudo window. That period of time during which sudo will let you do things before the permissions run out again. Usually like 5 minutes or 15 minutes from the LAST valid sudo you executed. –  lornix Jul 13 '12 at 2:15
1  
Exactly. My answer did involve permissions, I just beat around the bush the long way... Thanks for the help @allquixotic –  lornix Jul 13 '12 at 2:19

I don't have a direct explanation for why the globbing is doing what it's doing, but I know how you can rewrite your script to accomplish what you want:

for i in /home/*; do if [ -d "/home/${i}" ]; then sudo cat "/home/${i}/.ssh/authorized_keys"; fi; done

I don't know of any feature of bash that would cause it to glob differently depending on past commands run, so it may either be a bug or a really deeply buried (undocumented) feature. I NEVER use globs for directories; I always use either the find command for a for loop. I don't trust globs to do the right thing with any pattern containing /*/.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.