Como posso saber se dois arquivos estão vinculados na linha de comando? por exemplo, algo vincula isso:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Como posso saber se dois arquivos estão vinculados na linha de comando? por exemplo, algo vincula isso:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
Respostas:
Na maioria dos sistemas de arquivos¹, um arquivo é determinado exclusivamente por seu número de inode ; portanto, tudo que você precisa verificar é se os dois arquivos têm o mesmo número de inode e se estão no mesmo sistema de arquivos.
Ash, ksh, bash e zsh têm uma construção que faz a verificação para você: o operador de igualdade de arquivos -ef
.
[ fileA -ef fileB ] && ! [ fileA -ef fileC ]
Para casos mais avançados, ls -i /path/to/file
lista o número do inode de um arquivo. df -P /path/to/file
mostra em que sistema de arquivos o arquivo está (se dois arquivos estiverem no mesmo diretório, eles estão no mesmo sistema de arquivos). Se o seu sistema possuir o stat
comando, provavelmente poderá mostrar os números do inode e do sistema de arquivos ( stat
varia de sistema para sistema, verifique sua documentação). Se você quiser ver rapidamente os links físicos dentro de um diretório, tente ls -i | sort
(possivelmente direcionado para o awk ).
¹ Todos os sistemas de arquivos unix nativos e alguns outros como NTFS, mas possivelmente não casos exóticos como o CramFS.
fileA -ef fileB
também retorna 0
(êxito) se fileA
for um link simbólico para fileB
, ou vice-versa, ou ambos os links para o mesmo arquivo.
[ .bashrc -ef .bash/.bashrc ]
está correto. Sem contexto, é claro, não tenho idéia do por que "realmente não funcionou" - você pode comparar os arquivos errados, não verificar o resultado corretamente, usar um shell sem -ef
, ...
[
e é sinônimo de test
. Mas man [
ou man test
fornecerá a página de manual do comando externo, enquanto quase todos os shell existentes têm um comando interno com opções ligeiramente diferentes, portanto, você deve procurar este no manual do shell.
function is-hardlinked() {
r=yes
[ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
echo $r
}
stat -c %d
). E se você estiver no Linux (dado seu stat
comando), seu shell deve [ fileA -ef fileB ]
fazer tudo isso diretamente. Além disso, seu comando quebra gratuitamente com nomes de arquivos que contenham espaços em branco ou \[?*
, ou começa com -
: sempre coloque aspas duplas em torno do comando susbtitutions ( "$(stat -c %i -- "$1")"
).
function
palavra - chave extremamente portátil, com um nome de função que (por conter um traço) viola as convenções POSIX em nomes permitidos?
$1
e $2
. Você também pode usar a $()
sintaxe em vez de backticks, porque os colchetes deixam claro onde o comando começa e onde termina e o aninhamento é mais simples.
Como o primeiro pôster sugere, você pode escrever um script baseado em algo como isto no Linux:
stat -c '%i' fileA fileB fileC
stat -c %d
). E se você estiver no Linux (dado seu stat
comando), seu shell deve [ fileA -ef fileB ]
fazer tudo isso diretamente.
Com o GNU find(1)
versão 4.2.11 ou mais recente, você também pode usar este:
if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
echo yes
else
echo no
fi
Se fileA
for o mesmo arquivo fileB
, find
ele imprimirá "yes" e a condição se tornará verdadeira.
Ao contrário do uso do operador de igualdade de arquivos, -ef
isso gerará um novo processo.