Comment puis-je vérifier si se /my/dirtrouve sur la même partition que /?
C'est pour l'intégration dans un script. Les montures de liaison doivent être manipulées correctement. Les solutions compatibles POSIX sont les bienvenues.
Comment puis-je vérifier si se /my/dirtrouve sur la même partition que /?
C'est pour l'intégration dans un script. Les montures de liaison doivent être manipulées correctement. Les solutions compatibles POSIX sont les bienvenues.
Réponses:
Vous pouvez vérifier cela avec stat:
$ stat -c '%d %m' /proc/sys/
3 /proc
Vous indique le numéro de périphérique et l'endroit où votre répertoire a été monté.
statcommande shell n'est pas POSIX ...
La commande suivante donne un nom unique au point de montage contenant le fichier $file:
df -P -- "$file" | awk 'NR==2 {print $1}'
Cela fonctionne sur n'importe quel système POSIX . L' -Poption impose un format prévisible; le premier champ de la deuxième ligne est le «nom du système de fichiers». Ainsi, pour vérifier que deux fichiers se trouvent sous le même point de montage:
if [ "$(df -P -- "$file1" | awk 'NR==2 {print $1}')" = \
"$(df -P -- "$file2" | awk 'NR==2 {print $1}')" ]; then
echo "$file1 and $file2 are on the same filesystem" ; fi
Ou, pour enregistrer quelques appels de processus:
if df -P -- "$file1" "$file2" |
awk 'NR!=1 {dev[NR] = $1} END {exit(dev[2] != dev[3])}'; then
echo "$file1 and $file2 are on the same filesystem" ; fi
Quelques systèmes d'exploitation peuvent avoir des espaces dans les noms de volume. Il n'y a aucun moyen complètement fiable d'analyser la dfsortie dans ce cas.
Sous le capot, vous pouvez identifier le système de fichiers contenant un fichier par le st_devchamp renvoyé par stat. Il n'y a aucun moyen portable de le faire à partir d'un script shell. Certains systèmes ont un statutilitaire, mais sa syntaxe varie:
statsignale le st_devchamp lorsqu'il est appelé en tant que stat -c %D -- "$file".statqui est compatible avec GNU coreutils. D'autres ont statsans %coption; vous pouvez utiliser, stat -t -- "$file" | awk '{print $8}'mais cela ne fonctionne que si le nom de fichier ne contient pas d'espaces, ou stat -t -- "$file" | awk 'END {print $(NF-8)}'qui accepte des noms de fichiers arbitraires mais pas avec de futurs ajouts de champs à la statsortie.statutilitaire différent qui nécessite stat -f %d -- "$file".statutilitaire.Si Perl est disponible, vous pouvez utiliser
perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"
et pour faire la comparaison:
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"
Notez qu'il existe des cas d'angle où le résultat souhaité n'est pas clair. Par exemple, avec pochettes de protection se lient de Linux, après mount --bind /foo /bar, /fooet /barsont considérés comme le même système de fichiers. Il est toujours possible que les deux fichiers se trouvent réellement sur le même appareil, mais vous ne le saurez jamais: par exemple, si les fichiers se trouvent sur deux montages réseau différents, le client n'a aucun moyen de savoir si le serveur exporte des systèmes de fichiers différents.
Si les fichiers sont des répertoires et que vous pouvez y écrire, une autre méthode consiste à créer un fichier temporaire et à tenter de créer un lien dur. Celui-ci signale un résultat négatif sur les montages de liaison Linux.
tmp1=$(TMPDIR=$dir1 mktemp)
tmp2=$(TMPDIR=$dir2 mktemp)
if ln -f -- "$tmp1" "$tmp2"; then
echo "$dir1 and $dir2 are on the same filesystem, which supports hard links"
fi
rm -f "$tmp1" "$tmp2"
dfne donne pas toujours le nom de l'appareil, mais parfois un lien symbolique vers celui-ci, comme /dev/disk/by-uuid/ca09b761-ae1b-450f-8a46-583327b48fb4rendre dfnon fiable. Jusqu'à présent, la seule option fiable consiste à utiliser une statsolution basée sur.
dfsignalé pour le périphérique, il est cohérent entre les deux invocations, donc c'est correct pour une comparaison.
dfrapport /dev/sda6et /dev/disk/by-uuid/ca09b..., tous deux faisant référence au même périphérique, mais à des points de montage différents. Le test de comparaison de chaînes échoue évidemment lors de la tentative avec des fichiers de chaque point de montage.
mount /dev/sda6 /mnt1suivi par des mount /dev/sda6 /mnt2œuvres comme un charme. cat /proc/mountsest bien avec ça. Cependant, ce n'est que depuis Wheezy qui /dev/disk/by-uuid/ca09b...est affiché en dftant que périphérique pour le système de fichiers racine. D'autres tentatives de montage à l'aide de ce lien sim ou de la UUID=ca09b...syntaxe de montage ne finissent par afficher autre chose que /dev/sda6dans df(je ne sais pas comment reproduire ce qu'il a fait pendant le processus de démarrage, mais ce n'est pas le problème ici).
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1
Fonctionne avec un nombre illimité de chemins.
dfn'est pas toujours une bonne idée .
$6), pas le nom du périphérique ( $1), donc cela ne devrait pas être un problème.
La meilleure solution infaillible disponible dans POSIX est la comparaison des ID de périphérique des fichiers fournis par la fonction stat (2) .
Perl a une même fonction stat que Gilles a fait remarquer :
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2
mais la "façon POSIX" consiste à utiliser un programme C comme:
./checksamedev file1 file2
dont le code source est le suivant:
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
struct stat s1, s2;
if( argc==3 && lstat(argv[1], &s1)==0 && lstat(argv[2], &s2)==0 )
return !(s1.st_dev == s2.st_dev);
return 2;
}
Si les ID de périphérique des deux fichiers sont égaux, ils sont hébergés sur le même système de fichiers, auquel cas, les commandes ci-dessus renvoient 0 (une autre valeur sinon). Vérifiez avec echo $?.
Cela fonctionne bien avec les montages de liaison, mais probablement pas avec les montages réseau.