¿Cómo puedo verificar si /my/dir
está en la misma partición que /
?
Esto es para la integración dentro de un script. Los montajes de unión deben manejarse correctamente. Las soluciones compatibles con POSIX son bienvenidas.
¿Cómo puedo verificar si /my/dir
está en la misma partición que /
?
Esto es para la integración dentro de un script. Los montajes de unión deben manejarse correctamente. Las soluciones compatibles con POSIX son bienvenidas.
Respuestas:
Puede verificar esto con stat:
$ stat -c '%d %m' /proc/sys/
3 /proc
Muestra el número de dispositivo y dónde se montó su directorio.
stat
comando de shell no es POSIX ...
El siguiente comando proporciona un nombre único para el punto de montaje que contiene el archivo $file
:
df -P -- "$file" | awk 'NR==2 {print $1}'
Esto funciona en cualquier sistema POSIX . La -P
opción impone un formato predecible; El primer campo de la segunda línea es el "nombre del sistema de archivos". Por lo tanto, para verificar dos archivos están bajo el mismo punto de montaje:
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
O, para guardar un par de invocaciones de procesos:
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
Algunos sistemas operativos pueden tener espacios en los nombres de volumen. No hay una forma completamente confiable de analizar la df
salida en este caso.
Debajo del capó, puede identificar el sistema de archivos que contiene un archivo por el st_dev
campo devuelto por stat
. No hay una forma portátil de hacer esto desde un script de shell. Algunos sistemas tienen una stat
utilidad, pero su sintaxis varía:
stat
informa el st_dev
campo cuando se invoca como stat -c %D -- "$file"
.stat
que es compatible con GNU coreutils. Otros tienen stat
sin la %c
opción; puede usarlo, stat -t -- "$file" | awk '{print $8}'
pero esto solo funciona si el nombre del archivo no contiene espacios en blanco, o si stat -t -- "$file" | awk 'END {print $(NF-8)}'
hace frente a nombres de archivo arbitrarios pero no a futuras adiciones de campos a la stat
salida.stat
utilidad diferente que requiere stat -f %d -- "$file"
.stat
utilidad.Si Perl está disponible, puede usar
perl -e 'print ((stat($ARGV[0]))[0])' -- "$file"
y para hacer la comparación:
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- "$file1" "$file2"
Tenga en cuenta que hay algunos casos de esquina donde el resultado deseado no está claro. Por ejemplo, con los montajes de enlace de Linux, after mount --bind /foo /bar
, /foo
y /bar
se consideran el mismo sistema de archivos. Siempre es posible que los dos archivos estén ubicados en el mismo dispositivo, pero nunca lo sabrá: por ejemplo, si los archivos están en dos montajes de red diferentes, el cliente no tiene forma de saber si el servidor está exportando diferentes sistemas de archivos.
Si los archivos son directorios y puede escribir en ellos, otro método es crear un archivo temporal e intentar crear un enlace rígido. Este informa un resultado negativo en los montajes de enlace de 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"
df
no siempre da el nombre del dispositivo, pero en algún momento un enlace simbólico a ella como /dev/disk/by-uuid/ca09b761-ae1b-450f-8a46-583327b48fb4
lo que df
no es fiable. La única opción confiable hasta ahora es utilizar una stat
solución basada en.
df
informe para el dispositivo, es coherente entre las dos invocaciones, por lo que está bien para una comparación.
df
informe /dev/sda6
y /dev/disk/by-uuid/ca09b...
, ambos se refieren al mismo dispositivo, pero diferentes puntos de montaje. La prueba de comparación de cadenas obviamente falla al intentar con archivos de cada punto de montaje.
mount /dev/sda6 /mnt1
seguido de mount /dev/sda6 /mnt2
trabajos como un encanto. cat /proc/mounts
está bien con eso. Sin embargo, solo desde Wheezy /dev/disk/by-uuid/ca09b...
se muestra df
como el dispositivo para el sistema de archivos raíz. Los intentos adicionales de montarlo usando este enlace simbólico o la UUID=ca09b...
sintaxis de montaje no terminan mostrando nada más que /dev/sda6
en df
(no sé cómo reproducir lo que hizo durante el proceso de arranque, pero esa no es la preocupación aquí).
test $(df -P $path1 $path2 | awk '{if (NR!=1) {print $6}}' | uniq | wc -l) -eq 1
Funciona con cualquier número de caminos.
df
es no siempre una buena idea .
$6
), no el nombre del dispositivo ( $1
), por lo que no debería ser un problema.
La mejor solución infalible disponible en POSIX es la comparación de las ID de dispositivo de los archivos proporcionadas por la función stat (2) .
Perl tiene una función estadística similar a la que Gilles señaló :
perl -e 'exit((stat($ARGV[0]))[0] != (stat($ARGV[1]))[0])' -- file1 file2
pero la "forma POSIX" es usar un programa en C como:
./checksamedev file1 file2
cuyo código fuente es el siguiente:
#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 las ID de dispositivo de ambos archivos son iguales, se alojan en el mismo sistema de archivos, en cuyo caso, los comandos anteriores devuelven 0 (de lo contrario, otro valor). Consulte con echo $?
.
Esto funciona bien con los montajes de enlace, pero probablemente no lo hará con los montajes de red.