Como posso identificar quais diretórios estão em um sistema de arquivos diferente?

1

Imagine que estou em um diretório (por exemplo, /mnt ) em que alguns dos diretórios são pontos de montagem de outro sistema de arquivos, e outros diretórios são diretórios legítimos no mesmo sistema de arquivos. Posso emitir um comando simples para listar o conteúdo do diretório atual de uma maneira que me permita distinguir esses dois tipos de diretórios?

Uma possibilidade seria tree -L 1 -x , que expandirá apenas as pastas que estão no mesmo sistema de arquivos, mas isso não funciona caso todas essas pastas estejam vazias (por exemplo, sistemas de arquivos vazios são montados nos pontos de montagem e os diretórios legítimos são diretórios vazios).

(Meu caso de uso real aqui é os sistemas de arquivos btrfs, para poder identificar facilmente quais diretórios são subvolumes e quais não são.)

Edit: Eu recebi a sugestão dos amigos para usar df para obter o ponto de montagem de cada arquivo, então é possível listar todas as pastas em um sistema de arquivos diferente executando o seguinte:

comm -1 -3 \
  <(df --output=target . | sort) \
  <(df --output=target * | sort | uniq) |
  xargs basename -a

O comando executa df em todos os arquivos para obter seu ponto de montagem e remove a saída de df no diretório atual (que também remove o cabeçalho) e, em seguida, recupera o nome base de cada arquivo. No entanto, isso não é especialmente elegante e é frágil (pelo menos por causa de novas linhas, talvez por causa de coisas que eu negligenciei). Existe uma maneira melhor?

    
por a3nm 17.07.2016 / 17:29

3 respostas

1

Eu usaria df para isso.

$ cd /usr

$ ls
X11R6       include     libexec     mdec        sbin        xobj
bin         lib         local       obj         share       xsrc
games       libdata     lost+found  ports       src

$ for d in *; do test -d "$d" && df -P "$d" | awk -v d="$d" 'FNR>1{print d,$NF}'; done 
X11R6 /usr
bin /usr
games /usr
include /usr
lib /usr
libdata /usr
libexec /usr
local /usr/local
lost+found /usr
mdec /usr
obj /usr
ports /usr/ports
sbin /usr
share /usr
src /usr
xobj /usr
xsrc /usr
    
por 17.07.2016 / 17:41
1

Com stat (pode estourar ARG_MAX se * expandir para algo extremamente grande):

stat -c '%D %n' */ | awk -v no=$(stat -c %D /) ' $1 != no { print $2 }'

Com encontre :

find . -mindepth 1 -maxdepth 1 -type d -printf '%D\t%P\n'  |grep -v "^$(stat -c%d /)" |cut -f2
    
por 17.07.2016 / 22:57
1

No Linux, você pode usar stat para listar um identificador exclusivo associado para cada sistema de arquivos montado:

stat -f -c %i somefile

Por exemplo, para listar os pontos de montagem no diretório atual (assumindo que não há novas linhas nos nomes dos arquivos), você pode executar

stat -f -c '%i %n' * | grep -v "^$(stat -f -c %i .)"

No zsh, você pode usar o zsh/stat module . Carregue com zmodload zsh/stat e, em seguida,

zstat +device *

Para listar pontos de montagem no diretório atual:

zstat +device * | grep -v " $(zstat +device .)"

ou

print -rl -- *(e\''[[ $(zstat +device $REPLY) == '$(zstat +device .)' ]]'\')

Observe que o identificador do sistema de arquivos é o mesmo para diferentes exibições do mesmo sistema de arquivos, por exemplo, se você montar o mesmo compartilhamento de rede em diferentes locais, ou com montagens de ligação do Linux. No entanto, os subvolumes do btrfs recebem seu próprio identificador. Analisar a saída de df é mais complicado, mas não tem essa limitação.

    
por 18.07.2016 / 03:04