find * procura por um arquivo chamado “*” no Debian mas não no RHEL

0

Onde está a diferença? Essas distribuições lidam com algo diferente? Ou a configuração varia? O que eu tenho para comparar e ajustar? Eu preferiria que find * não correspondesse ao curinga em si.

  • Os resultados diferem porque um host combina * também: Em contraste com RedHatHost , o DebianHost também procura por * . Mas não há nenhum arquivo chamado * .
  • Plataformas: Debian Wheezy 7, Red Hat Enterprise Linux 7. O Bash sempre é usado.
  • grep deve procurar o nome do host em todos os arquivos em /etc . Poderia haver apenas uma correspondência para cada host: /etc/hostname em DebianHost e cat /etc/sysconfig/network em RedHatHost .
DebianHost# cat $(find /etc/ *) 2>/dev/null | grep $(hostname)
find: '*': No such file or directory
DebianHost
DebianHost# 
DebianHost# 
DebianHost# 
DebianHost# hostname
DebianHost
DebianHost# 
DebianHost# 
DebianHost# 
DebianHost# pwd
/root
DebianHost# 
DebianHost# 
DebianHost# 
DebianHost# ls -1 .
DebianHost# 
DebianHost# 
DebianHost# 
DebianHost# grep -r $(hostname) /etc
/etc/hostname:DebianHost
DebianHost# 
DebianHost# 
DebianHost# 
DebianHost# find /etc/ * | grep -e "*"
find: '*': No such file or directory
DebianHost# 

RedHatHost# cat $(find /etc/ *) 2>/dev/null | grep $(hostname)
HOSTNAME=RedHatHost
RedHatHost# 
RedHatHost# 
RedHatHost# 
RedHatHost# hostname
RedHatHost
RedHatHost# 
RedHatHost#
RedHatHost#  
RedHatHost# pwd
/root
RedHatHost# 
RedHatHost# 
RedHatHost# 
RedHatHost# ls -1 .
anaconda-ks.cfg
install.log
install.log.syslog
RedHatHost#
RedHatHost# 
RedHatHost# 
RedHatHost# grep -r $(hostname) /etc/
/etc/sysconfig/network:HOSTNAME=RedHatHost
RedHatHost# 
RedHatHost#
RedHatHost# 
RedHatHost# 
RedHatHost# find /etc/ * | grep -e "*"
RedHatHost# 
    
por user2964971 09.06.2014 / 13:19

3 respostas

3

* contendo um caractere curinga não citado (sendo ele próprio um caractere curinga), é considerado como glob e expandido pelo shell na lista de arquivos que correspondem a esse padrão.

Esse padrão específico ( * ), corresponde a qualquer nome de arquivo não oculto, portanto, antes de chamar find , o shell o expandirá para a lista de arquivos não ocultos no diretório atual, portanto, se o diretório atual contém um arquivo chamado foo e outro chamado foo bar , ele chamará find com esses argumentos:

"find", "/etc/", "foo", "foo bar"

Se não houver nenhum arquivo não oculto no diretório atual, o comportamento varia entre os shells. csh , tcsh , fish , zsh emitirá uma mensagem de erro no match e não executará o comando, enquanto as shells POSIX ainda chamarão find mas com o padrão não expandido . Então, naqueles, find será chamado com esses argumentos:

"find", "/etc/", "*"

(que está pedindo para o find encontrar todos os arquivos em /etc/ e em * (que neste caso não existe)). Muito provavelmente, no RedHat, você está chamando esse comando de um diretório que contém arquivos não ocultos, enquanto no Debian, você está chamando de que contém apenas arquivos ocultos.

A propósito

cat $(find /etc/ *) 2>/dev/null | grep $(hostname)

está errado.

Você deve escrever:

find /etc -type f -exec cat {} + | grep -Fe "$(hostname)"

Ou provavelmente mais útil:

find /etc -type f -exec grep -Fe "$(hostname)" {} +

Ou porque tanto o Debian quanto o RedHat possuem o GNU grep:

grep -rFe "$(hostname)" /etc
    
por 09.06.2014 / 13:31
4

O * em ambos os casos está sendo expandido pelo shell. Você provavelmente está vindo do Windows, onde o shell nunca expande curingas, apenas os passa literalmente para o programa. Unix shells não funcionam assim.

A melhor maneira de ver isso é dizer echo * em ambas as máquinas. Em sua máquina Debian, ele irá imprimir * porque você está rodando em um diretório sem arquivos, então o * é passado para o programa. (Eu estou supondo que você está executando o Bash, que passa o curinga para o programa chamado quando não corresponde a nada.) Na sua caixa Red Hat, ele dirá

anaconda-ks.cfg install.log install.log.syslog

Ou seja, os três nomes de arquivos no diretório em que você está sendo executado são passados para echo , que os imprime com um único espaço separando seus argumentos.

Não tenho certeza do efeito que você está tentando com find /etc/ * , porque esse não é um comando find sensato. Se você quiser apenas listar todos os arquivos na árvore /etc , find /etc será suficiente.

    
por 09.06.2014 / 13:31
2

find /etc * não procura por um arquivo chamado * . A maneira como se comporta depende de o diretório atual estar vazio¹.

  • Se estiver vazio, o shell expandirá find /etc * para si mesmo; find vê que é instruído a percorrer os dois diretórios /etc e * e reclama que * não existe (além de listar todos os arquivos em /etc ). Isto é o que você está vendo no Debian.
  • Se não estiver vazio, o shell expandirá find /etc * para find /etc seguido pela lista de arquivos no diretório atual. Portanto, find lista todos os arquivos em /etc e também todos os arquivos no diretório atual, exceto o próprio diretório atual. Isso é o que você está vendo no RHEL.

A diferença não tem nada a ver com a distribuição, você está conduzindo o teste em diferentes contextos nas duas máquinas.

Nada disso tem nada a ver com a procura de um arquivo chamado * . Se você quiser procurar um arquivo por nome, precisará usar o predicado -name : find /etc -name somename . O argumento para -name é um padrão curinga como os do shell. Como o caractere * é um curinga, para procurar um arquivo chamado * , é necessário proteger o curinga com uma barra invertida: find -name '\*' . Observe os dois níveis de cotação: as aspas simples para impedir a expansão dos caracteres \ e * pelo shell (você poderia usar find -name "\*" ou find -name \\* ), para que find veja o padrão \* , e a barra invertida para que o padrão seja "literal * " em vez de "qualquer seqüência de caracteres".

* é um caractere válido, mas incomum, em nomes de arquivos. Se você não quisesse realmente corresponder a um caractere cujo nome é * , mas qualquer arquivo, então você pode escrever find /etc -name '*' (novamente, você precisa citar o * para que ele não seja expandido pelo shell) , mas isso é exatamente equivalente a apenas find /etc .

¹ Mais precisamente, se o diretório atual contém arquivos diferentes de arquivos de ponto, ou seja, se contém arquivos cujo nome não comece com . .

    
por 09.06.2014 / 13:48