I have some strange behavior I don't understand. I'm just trying to list some files in a directory:

sudo find /home/vsts/work/_temp/tmp.Q8K2bSeNVV/root/home/root produces:


So I know the .gnupg directory exists, and has files in it.

sudo ls -la /home/vsts/work/_temp/tmp.Q8K2bSeNVV/root/home/root produces:

total 12
drwx------ 3 root root 4096 Sep 21 14:54 .
drwxr-xr-x 3 root root 4096 Aug 24 18:30 ..
drwxr-xr-x 3 root root 4096 Sep 21 14:54 .gnupg

So the directory itself has rwx permissions.

But the command sudo ls -la /home/vsts/work/_temp/tmp.Q8K2bSeNVV/root/home/root/.gnupg/* gives:

ls: cannot access '/home/vsts/work/_temp/tmp.Q8K2bSeNVV/root/home/root/.gnupg/*': No such file or directory

I've checked the path over and over and can't see anything wrong. I have rwx permissions and root level access. What else could stop me from listing this directory?

My ultimate goal is to do a chmod 600 /home/vsts/work/_temp/tmp.Q8K2bSeNVV/root/home/root/.gnupg/*, which also fails. But for now I'd settle for ls.

Edit: It just hit me. Does this have to do with the file globbing. Does the * expand before sudo, and therefor without root access?

  • 1
    you've already used find, why not go all the way with sudo find /home/…/.gnupg -type f -exec chmod 600 {} \;
    – Fox
    Sep 21 '20 at 16:00
  • Find was just there for debug purposes. But yeah, this is actually a fairly clean solution.
    – Dave
    Sep 21 '20 at 19:56

As you noted correctly, the expansion order is the root of your problem. The step relevant for filename globs is "filename expansion". Although it is rather late in the order of expansions (see here e.g.), it is performed before the command is actually invoked. This means that e.g. ls * in a directory containing file1.txt, file2.txt and file3.txt is actually called as ls file1.txt file2.txt file3.txt.

The problem now is that the calling user doesn't have the necessary permissions to enter the .gnupg directory. Hence, the expansion of the * filename glob will fail. In such cases, unless specific shell options are set, the * will remain literal on the command line, so that the shell would try to perform the ls command on a file literally called *. Hence the error message

cannot access '/home/vsts/work/_temp/tmp.Q8K2bSeNVV/root/home/root/.gnupg/*'

As you see, it tries to access a file called * inside /home/vsts/work/_temp/tmp.Q8K2bSeNVV/root/home/root/.gnupg/.

What you can do instead is write a shell script that does the relevant operations, which you then call as root using sudo. You would need to place the script under a path accessible from everywhere, such as /usr/local/bin.

  • 1
    I solved with sudo sh -c "ls -la /home/vsts/work/_temp/tmp.Q8K2bSeNVV/root/home/root/.gnupg/*", which is functionally equivalent to your suggestion.
    – Dave
    Sep 21 '20 at 19:53

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