Cómo obtener el punto de montaje del sistema de archivos que contiene el archivo dado

13

Estoy buscando una manera rápida de encontrar el punto de montaje del sistema de archivos que contiene un ARCHIVO dado. ¿Hay algo más simple o más directo que mi solución a continuación?

df -h FILE |tail -1 | awk -F% '{print $NF}' | tr -d ' '

Una pregunta similar " ¿Hay un comando para ver dónde está montado un disco? " Utiliza el nodo del dispositivo del disco actual como entrada, y no un archivo arbitrario del disco ...

Stu
fuente
1
Puede eliminar la trllamada final usandoawk -F'% '...
Joseph R.

Respuestas:

6

Podrías hacer algo como

df -P FILE | awk 'NR==2{print $NF}'

o incluso

df -P FILE | awk 'END{print $NF}'

Dado que se awkdivide en espacios en blanco de forma predeterminada, no es necesario especificar el -Fy tampoco es necesario recortar el espacio en blanco tr. Finalmente, al especificar el número de línea de interés ( NR==2) también puede eliminarlo tail.

terdon
fuente
el segundo encantamiento funcionó de fábrica, mientras que tuve que cambiar 2 a 3 en el primero. ordenado
Stu
@Gilles, gracias por la edición. Una pregunta, la segunda debería funcionar incluso sin -Pderecho? En todos los casos, el último campo impreso por awkdebería ser el disco.
terdon
@Stu probablemente sea porque no había usado la -Popción que Gilles acaba de agregar.
terdon
1
@terdon Sí, de hecho, el último campo de la última línea es el mismo sin él -P. Sin embargo, recomiendo usar siempre -Pcuando esté analizando la salida de df, es más fácil que verificar que este uso en particular sea seguro.
Gilles 'SO- deja de ser malvado'
bonito. si necesita ahora la entrada / dev para $ {FILE} (por alguna razón)mount | grep " on $(df -P ${FILE} | awk 'END{print $NF}') type" | awk '{print $1}'
no sincronizado
16

En GNU / Linux, si tiene GNU statde coreutils 8.6 o superior, puede hacer lo siguiente:

stat -c %m -- "$file"

De otra manera:

mount_point_of() {
  f=$(readlink -e -- "$1") &&
    until mountpoint -q -- "$f"; do
      f=${f%/*}; f=${f:-/}
    done &&
    printf '%s\n' "$f"
}

Su enfoque es válido, pero supone que el punto de montaje no contiene espacios,%, nueva línea u otros caracteres no imprimibles, puede simplificarlo ligeramente con las versiones más nuevas de GNU df(8.21 o superior):

df --output=target FILE | tail -n +2
Stéphane Chazelas
fuente
Mi dfno reconoce la --outputopción.
Joseph R.
@JosephR. ¿Es la versión 8.21 o superior?
terdon
@terdon No, es la versión 8.13.
Joseph R.
2
@JosephR. Stephane explica en su respuesta que esta es una característica de GNU df> = 8.21.
terdon
@terdon Lo siento, debe haberlo perdido mientras se desnataba.
Joseph R.
8

Para Linux tenemos findmnt de util-linux hecho exactamente para esto

findmnt -n -o TARGET --target /path/to/FILE

Tenga en cuenta que se puede devolver algún tipo de punto de montaje aleatorio en caso de que haya varios montajes de enlace. Usar dftiene el mismo problema.

rudimeier
fuente
2
Funciona correctamente incluso con los archivos que están en subvolúmenes.
ceremcem
3

Como statdevuelve un campo "Dispositivo", tenía curiosidad por ver cómo la stat()llamada a la biblioteca subyacente podría usarse para obtener esta información mediante programación de una manera compatible con POSIX.

Este fragmento de código C:

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>

int main (int argc, const char *argv[]) {
    struct stat info;
    stat(argv[1], &info);
    printf("min: %d maj: %d\n",
        minor(info.st_dev),
        major(info.st_dev)
    );

    return 0;
}  

Le dará las ID de los dispositivos principales y secundarios para el dispositivo que contiene el archivo que figura en la línea de comando ( argv[1]). Desafortunadamente, major()y minor()no son POSIX, aunque la página del manual afirma que están "presentes en muchos otros sistemas" además de GNU / linux.

A continuación, puede obtener una correspondencia entre el número mayor / menor del dispositivo y el nodo del dispositivo, por ejemplo /proc/diskstats, y asignarlo para montar puntos desde /proc/mounts, también conocido como. /etc/mtab.

Entonces, una utilidad de línea de comandos para hacer esto sería bastante simple.

encerrada dorada
fuente
/proc/diskstatses solo para dispositivos de bloque, perderá el NFS, el proceso, el fusible ... Al menos en Linux, diferentes puntos de montaje pueden tener el mismo maj + min
Stéphane Chazelas
No sabía eso, gracias. También parece que st_devno puede proporcionar una manera de distinguir una partición NFS de otra. Quien realmente quiera escribir esto tendrá que tenerlo en cuenta;)
goldilocks
+1 por ser lo suficientemente geek como para considerar escribir código C "más simple o más directo" que lo que estaba haciendo el OP :).
terdon
0

Aquí hay más código de C ++ si desea hacer esto desde C ++ ...

  #include <boost/filesystem.hpp>
  #include <sys/stat.h>

  /// returns true if the path is a mount point
  bool Stat::IsMount(const std::string& path)
  {

      if (path == "") return false;
      if (path == "/") return true;

      boost::filesystem::path path2(path);
      auto parent = path2.parent_path();

      struct stat sb_path;
      if (lstat(path.c_str(), &sb_path) == -1) return false; // path does not exist
      if (!S_ISDIR(sb_path.st_mode)) return false; // path is not a directory

      struct stat sb_parent;
      if (lstat(parent.string().c_str(), &sb_parent) == -1 ) return false; // parent does not exist

      if (sb_path.st_dev == sb_parent.st_dev) return false; // parent and child have same device id

      return true;

  }

  /// returns the path to the mount point that contains the path
  std::string Stat::MountPoint(const std::string& path0)
  {
      // first find the first "real" part of the path, because this file may not exist yet
      boost::filesystem::path path(path0);
      while(!boost::filesystem::exists(path) )
      {
          path = path.parent_path();
      }

      // then look for the mount point
      path = boost::filesystem::canonical(path);
      while(! IsMount(path.string()) )
      {
          path = path.parent_path();
      }

      return path.string();
  }

Más enlaces para formas programáticas

Mark Lakata
fuente