Estou usando uma expressão curinga para corresponder a um nome de arquivo.
Isso é o que acontece com um usuário normal não root:
debian@MiWiFi-R3-srv:~$ sudo ls /var/log/apache2/*[0-9].gz
ls: cannot access '/var/log/apache2/*[0-9].gz': No such file or directory
E é isso que acontece depois que eu mudo para o usuário root sudo su
e tento o mesmo comando:
root@MiWiFi-R3-srv:/home/debian# ls /var/log/apache2/*[0-9].gz
/var/log/apache2/access.log.10.gz /var/log/apache2/error.log.10.gz
/var/log/apache2/access.log.11.gz /var/log/apache2/error.log.11.gz
/var/log/apache2/access.log.12.gz /var/log/apache2/error.log.12.gz
Por que essa expressão curinga pode ser usada como root
, mas não como um usuário normal não raiz?
A
/var/log/apache2/*[0-9].gz
substring*[0-9]
é manipulada pelo mecanismo de expansão do nome do caminho do shell. Não desudo
nemls
. Da casca . Isso acontece antessudo
ouls
mesmo começa.Para expandir
/var/log/apache2/*[0-9].gz
o shell, é necessário examinar o conteúdo do arquivo/var/log/apache2/
. No meu Debian 10 as permissões sãorwxr-x---
, a propriedade éroot:adm
. Na verdade, o shell do root pode examinar o conteúdo, mas o shell de um usuário comum não pode.Portanto, o padrão é expandido para root, mas permanece textualmente para um usuário regular. Nem expanda o padrão e, eventualmente, o usuário regular (elevado)
sudo
tenta listar informações sobre exatamente; não existe tal arquivo ou diretório.ls
ls
/var/log/apache2/*[0-9].gz
Isso deve funcionar para um usuário comum:
Nesse caso
sudo
, será executado elevadosh
e esse shell expandirá o padrão com sucesso.(No começo eu pensei
sudo -s …
que faria isso, mas não .)Ao contrário do Windows/DOS, globs são expandidos pelo shell antes de executar o comando em sistemas Unix. O shell, neste caso, está sendo executado com seu UID, não root, portanto, não pode ler esse diretório.
O comportamento padrão no caso de não correspondência é passar a expressão glob literalmente. por exemplo, se você executar
ls xyz*xyz
em seu shell normal, veráls: cannot access 'xyz*xyz': No such file or directory
fromls
, porque recebeu essa string como um argumento.Assim como se você corresse
ls '*'
para passar*
como uma string literal parals
. (A remoção de aspas também é tarefa do shell, portanto, um comando não pode dizer se seu argumento foi citado ou não.)Você pode alterar esse comportamento no bash, por exemplo,
shopt -s failglob
significa que o mesmols xyz*xyz
comando será fornecidobash: no match: xyz*xyz
sem invocarls
nada. (Se você tivesse usadosudo
, teria notado que ele não solicitou uma senha antes de receber essa mensagem de erro.)failglob
produz o mesmo erro "sem correspondência" ao tentar ler um diretório no qual você não tem permissão de leitura, infelizmente não avisando sobre o erro EPERM que o bash vai quando fez umaopen
chamada de sistema no diretório.bash: no match: /var/log/private/*
(Há também
shopt -s nullglob
, onde uma expressão glob não correspondente é removida em vez de transmitida literalmente. Então, seusudo ls /...*
comando teria sido executado de forma confusa comosudo ls
. Isso talvez seja útil para scripts em que você pode querer fazer*.gz *.tgz *.tar
ou algo assim, e não obter erros do falha na expansão. Provavelmente não é algo que você normalmente deseja para uso interativo.)Você pode usar
shopt -u failglob
ou qualquer outra coisa para desativar essas opções em um shell, se configurá-las para experimentá-las.