Estou tentando encontrar alguns arquivos grandes em um local específico:
Este comando funciona e retorna alguns resultados:
admin@tyrell:~$ sudo find /nfshome/*/.local/ -type f -size +1G -exec ls -lh {} \;
-rw-r--r-- 1 9917183 students 5.2G Jun 5 2017 /nfshome/9917183/.local/share/Trash/files/result_25.zip
-rw-r--r-- 1 9918178 students 4.0G Sep 6 2018 /nfshome/9918178/.local/share/unity3d/Asset Store-5.x/Unity Technologies/Unity EssentialsSample Projects/3D Game Kit.unitypackage
-rw-r--r-- 1 9919185 students 2.1G Mar 6 2018 /nfshome/9919185/.local/share/Trash/files/agggg.avi
-rw-r--r-- 1 9919382 students 1.7G Jan 17 2017 /nfshome/9919382/.local/share/Trash/files/MageWar.avi
-rw-r--r-- 1 9921459 students 1.8G Apr 12 11:58 /nfshome/9921459/.local/share/Trash/files/takeout-20190412T182950Z-001(1).zip
-rw-r--r-- 1 9921459 students 1.8G Apr 12 11:58 /nfshome/9921459/.local/share/Trash/files/takeout-20190412T182950Z-001.zip
-rw-r--r-- 1 9921459 students 1.4G Apr 12 11:56 /nfshome/9921459/.local/share/Trash/files/takeout-20190412T182950Z-003.zip
-rw-r--r-- 1 9921459 students 1.4G Apr 12 11:58 /nfshome/9921459/.local/share/Trash/files/takeout-20190412T182950Z-003(1).zip
mas se eu tentar restringir a pesquisa adicionando mais um subdiretório, share/
, não recebo nada, onde esperaria obter exatamente o mesmo resultado, porque tudo acima está em share/
:
admin@tyrell:~$ sudo find /nfshome/*/.local/share/ -type f -size +1G -exec ls -lh {} \;
admin@tyrell:~$
Por que find não retorna o mesmo resultado que o primeiro comando?
No seu comando, o
sudo
único dá privilégios extras aofind
comando, não ao shell. Portanto, se você iniciar alto,find
poderá descer na árvore de arquivos e mostrar o conteúdo.Mas seu shell está tentando expandir o
*
. Se seu usuário não tiver privilégios para inspecionar o conteúdo de/nfshome/*/.local
, ele não poderá corresponder a nenhum arquivo dentro (como/nfshome/*/.local/share
). Sem uma correspondência, nada é passado parafind
.Você pode ver isso examinando a saída de
echo /nfshome/*/.local
eecho /nfshome/*/.local/share
. O segundo provavelmente estará vazio.Não está claro por que você deseja executar o segundo comando quando o primeiro parece funcionar. Você pode executar o comando inteiro em um subshell e executá-lo com
sudo
. Tal comosudo -c "find ..."
A razão pela qual isso falha tem a ver com permissões e o
*
caractere curinga. Podemos reproduzir isso em um sistema de arquivos local como este:Configure o cenário, uma árvore de diretórios em
/tmp/top
:Observe que não temos permissão como usuário comum para seguir abaixo
/tmp/top/*/dir
:Tente descer com privilégios de root de um diretório que não podemos acessar como um usuário comum:
Lembre-se de que a avaliação dos curingas do shell acontece antes que o comando seja executado. Então, o que está acontecendo aqui é que o caminho que contém o curinga
*
é expandido. Sua conta de usuário comum não pode verificar a existência desub
e, portanto, todo o caminho não pode ser verificado. O curinga permanece como um asterisco (o comportamento padrão quando uma correspondência falha) e a raiz privilegiadafind
recebe o caminho literal/tmp/top/*/dir/sub
para descer. Este caminho não existe, daí o erro.Tente descer com privilégios de root de um diretório que podemos acessar como um usuário comum:
O que acontece aqui é semelhante, mas com consequências mais úteis. O caminho
/tmp/top/*/dir
pode ser avaliado completamente como seu usuário comum, resultando em dois caminhos/tmp/top/a/dir
e/tmp/top/b/dir
. Eles são passados para o root privilegiadofind
e, posteriormente, pode descê-los - através do subdiretório somente raiz - e listar os arquivos que descobrir.Na sua situação, é altamente provável que os
.local
diretórios em seu caminho curinga não possam ser acessados sem privilégios de root, mas os diretórios de nível superior são bastante acessíveis. Enquanto você especifica um caminho que pode ser avaliado como sua conta de usuário comum, ofind
pode prosseguir com o conjunto expandido de caminhos. Assim que você especifica um caminho que não pode ser avaliado no contexto de sua conta de usuário comum, a expansão falha efind
recebe um caminho que contém um*
caractere literal. Isso, obviamente, não corresponde e asfind
falhas.Para resolver o problema, basta adiar a avaliação do caminho até que seu comando esteja sendo executado como root: