Todo diretório em um sistema Unix (e provavelmente todos os outros sistemas também) contém pelo menos duas entradas de diretório. Estes são .
(diretório atual) e ..
(diretório pai). No caso do diretório raiz, eles apontam para o mesmo local, mas com qualquer outro diretório, eles são diferentes. Você pode ver isso usando os comandos stat
, pwd
e cd
(no Linux):
$ cd /
$ stat . .. bin sbin | grep Inode
Device: 802h/2050d Inode: 2 Links: 27
Device: 802h/2050d Inode: 2 Links: 27
Device: 802h/2050d Inode: 548865 Links: 2
Device: 802h/2050d Inode: 2670593 Links: 2
$ pwd
/
$ cd ..
$ pwd
/
$
Observe que bin
e sbin
cada um tem dois links para ele. Uma é a entrada de diretório no diretório raiz e a outra é a entrada .
dentro desse diretório.
Usar ls
com um pipe para wc -l
é um truque simples para contar o número de linhas na saída de ls. A suposição é que cada arquivo ou diretório ocupará exatamente uma linha na saída. O GNU ls, quando a saída é um não terminal, faz isso automaticamente; outros podem precisar da opção -1
para ativar o comportamento explicitamente. wc -l
simplesmente conta e gera o número de linhas ( -l
) em sua entrada.
O problema com essa abordagem é que no Linux e nos sistemas de arquivos tradicionalmente usados no Linux, os nomes de arquivos e diretórios (eles são realmente um e o mesmo nesse sentido) são permitidos para conter caracteres de nova linha . Na presença destes, qualquer um dos métodos se desfaz - essas entradas serão contadas como duas ou mais entradas quando, na realidade, elas forem uma.
Contanto que você esteja usando o GNU ls, não tenha entradas de diretório com nomes que contenham caracteres de nova linha e não tenha aliases ímpares para ls
(por exemplo, ls -a
), ambos exibirão a contagem de arquivos e diretórios o diretório atual (ou especificado). Para a maioria das pessoas, isso é bom o suficiente, mas não é válido no caso geral .
Se você precisa manipular os caracteres incomuns (principalmente as novas linhas) nos nomes das entradas de diretórios corretamente, sugiro usar a opção -b
de ls para escapar deles. ls -1bA
imprimirá cada nome de entrada de diretório em sua própria linha, escape de caracteres incomuns (para que cada entrada de diretório seja vista como um), incluindo quaisquer arquivos de pontos e diretórios. Ligue para wc -l
para obter uma linha de comando completa de ls -1bA | wc -l
, que informará o número de arquivos e diretórios no diretório atual (mas ignore .
e ..
; essa é a diferença entre -a
e -A
) , mas não descer em nenhum subdiretório. Se você não quiser que nenhum arquivo de ponto seja contado no total, simplesmente omita o parâmetro -A
como ls
.