Search code examples
bashshellwildcardsudo

why wildcard doesn't work in `sudo rm` statement?


I was trying to delete all files in log directory and using default bash shell on CentOS 6.5

[lei@ids7gueywjZ /]$ sudo ls -al /var/log/jenkins/
total 1541512
drwxr-x---   2 jenkins jenkins       4096 Jul 22 09:52 .
drwxr-xr-x. 10 root    root          4096 Jul 14 21:27 ..
-rw-r--r--   1 jenkins jenkins      31483 Jul 22 17:07 jenkins.log
-rw-r--r--   1 jenkins jenkins 1073606656 Jul 18 03:16 jenkins.log-20150718
-rw-r--r--   1 jenkins jenkins  504815011 Jul 19 03:30 jenkins.log-20150719.gz
[lei@ids7gueywjZ /]$ sudo rm -r /var/log/jenkins/*
rm: cannot remove `/var/log/jenkins/*': No such file or directory

I don't understand why rm -r /var/log/jenkins/* doesn't work? Is there some default shell configuration I was missing?


Solution

  • The wildcard expansion is done by the shell, prior to actually calling sudo. And the shell itself does not have (or get) sudo rights, so it cannot read the contents of /var/log/jenkins/.

    By the time rm (now bestowed with sudo rights) sees its arguments, wildcard expansion has already happened -- or rather, it has not, because there was nothing (readable by the shell) to match that *.

    So rm attempts to delete the file (not the wildcard) /var/log/jenkins/* -- which does not exist:

    rm: cannot remove `/var/log/jenkins/*': No such file or directory

    To get around this, you need a shell with sudo rights executing your rm:

    sudo sh -c 'rm /var/log/jenkins/*'
    

    Now the shell itself gets sudoed, and can do the expansion prior to calling rm.