Por que o ls. * mostra arquivos diferentes de ls ./.*?

3

O arquivo branco .ignoramus no diretório atual existe.

bojan@localhost:~$ echo $GLOBIGNORE
.ignoramus
bojan@localhost:~$ ls .* | grep ignor
bojan@localhost:~$ ls ./.* | grep ignor
./.ignoramus

ferramentas usadas     ls (GNU coreutils) 8,23     GNU bash, versão 4.3.42 (1) -release (x86_64-pc-linux-gnu)

    
por Bojan Landekić 20.04.2016 / 01:25

2 respostas

4

A configuração $GLOBIGNORE é processada pelo shell quando expande o curinga em sua linha de comando. No seu primeiro caso, o shell primeiro expande .* para .ignoramus , que é correspondido por $GLOBIGNORE , por isso não é incluído nos nomes passados para ls .

No segundo caso, o shell expande ./.* para ./.ignoramus , o que não é correspondido por $GLOBIGNORE . Se você definir $GLOBIGNORE para .ignoramus:./.ignoramus , o comportamento de seu segundo comando corresponderá ao seu primeiro.

    
por 20.04.2016 / 01:44
1

Motivo curto: a string ./.ignoramus não corresponde a .ignoramus .

Solução curta: use GLOBIGNORE=*ignoramus (leia também detalhes no final).

$ GLOBIGNORE=*ignoramus
$ ls .* | grep ignor                 ### empty
$ ls ./.* | grep ignor               ### also empty

O asterisco corresponderá a qualquer coisa (até mesmo uma barra / antes do nome).
Naturalmente, isso também corresponderá a foobar.ignoramus . Para algumas soluções alternativas, leia no final.

Resposta expandida:

Isso também acontece com um arquivo normal:

$ mkdir /tmp/mytest; cd /tmp/mytest
$ touch f1 f2 filetotest
$ GLOBIGNORE=filetotest
$ ls -1
f1
f2
filetotest

$ ls -1 f*
f1
f2

$ ls -1 *
f1
f2

$ ls -1 ./f*
./f1
./f2
./filetotest

GLOBIGNORE não corresponderá a ./filetotest , mas se usarmos:

$ GLOBIGNORE="*filetotest"
$ ls -1 ./f*
./f1
./f2

$ ls -1 ./*
./f1
./f2

$ ls -1
f1
f2
filetotest

O padrão em GLOBIGNORE corresponderá a (something)filetotest .

Para o seu exemplo:

$ touch .ignoramus
$ GLOBIGNORE='*ignoramus'
ls -1a
.
..
f1
f2
filetotest
.ignoramus

$ ls .* | grep ignor
$ ls ./.* | grep ignor

Mesmo com algum caminho na frente do arquivo, funciona:

$ GLOBIGNORE='*ignoramus:*filetotest'
$ mkdir -p long/dir/to/test
$ touch long/dir/to/test/{f3,f4,.ignoramus,.other,filetotest}

$ ls -1 long/dir/to/test/f*
long/dir/to/test/f3
long/dir/to/test/f4

$ ls -1 long/dir/to/test/.[^.]*
long/dir/to/test/.other

$ shopt -s dotglob
$ ls -1 long/dir/to/test/*
long/dir/to/test/f3
long/dir/to/test/f4
long/dir/to/test/.other

$ unset GLOBIGNORE; shopt -s dotglob
$ ls -1 long/dir/to/test/*
long/dir/to/test/f3
long/dir/to/test/f4
long/dir/to/test/filetotest
long/dir/to/test/.ignoramus
long/dir/to/test/.other

Claro, isso também corresponderá a bar.ignoramus . Se isso não for desejado, use:

$ GLOBIGNORE=.ignoramus:./.ignoramus

Ou, se você quiser algum caminho incluído:

$ GLOBIGNORE=.ignoramus:*/.ignoramus
    
por 20.04.2016 / 06:54