Cara mendapatkan mount point dari sistem file yang berisi file yang diberikan


13

Saya mencari cara cepat untuk menemukan titik pemasangan sistem file yang berisi FILE yang diberikan. Apakah ada yang lebih sederhana atau lebih langsung daripada solusi saya di bawah ini?

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

Pertanyaan serupa " Apakah ada perintah untuk melihat di mana disk dipasang? " Menggunakan simpul perangkat disk saat ini sebagai input, dan bukan file sembarang dari disk ...


1
Anda dapat trmembatalkan panggilan terakhir dengan menggunakanawk -F'% '...
Joseph R.

Jawaban:


6

Anda bisa melakukan sesuatu seperti

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

atau bahkan

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

Karena awkpemisahan pada spasi putih secara default, Anda tidak perlu menentukan -Fdan Anda juga tidak perlu memotong spasi dengan tr. Terakhir, dengan menentukan jumlah baris yang diminati ( NR==2), Anda juga dapat menghapusnya tail.


mantra ke-2 berhasil di luar kotak, sementara saya harus mengubah 2 menjadi 3 di yang pertama. rapi
Stu

@Gilles, terima kasih atas hasil editnya. Satu pertanyaan, yang kedua harus bekerja bahkan tanpa -Pbenar? Dalam semua kasus, bidang terakhir yang dicetak awkadalah disk.
terdon

@ Sit itu mungkin karena saya belum menggunakan -Popsi yang baru saja ditambahkan Gilles.
terdon

1
@terdon Ya, memang, bidang terakhir dari baris terakhir adalah sama tanpa -P. Meskipun demikian saya sarankan selalu menggunakan -Pketika Anda parsing output df, lebih mudah daripada memeriksa bahwa penggunaan khusus ini aman.
Gilles 'SO- stop being evil'

bagus. jika Anda perlu sekarang entri / dev untuk $ {FILE} (untuk beberapa alasan)mount | grep " on $(df -P ${FILE} | awk 'END{print $NF}') type" | awk '{print $1}'
tidak disinkronkan pada

16

Di GNU / Linux, jika Anda memiliki GNU statdari coreutils 8.6 atau lebih tinggi, Anda bisa melakukan:

stat -c %m -- "$file"

Jika tidak:

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

Pendekatan Anda valid tetapi mengasumsikan titik mount tidak mengandung spasi,%, baris baru atau karakter yang tidak dapat dicetak lainnya, Anda dapat menyederhanakannya sedikit dengan versi GNU yang lebih baru df(8.21 atau lebih tinggi):

df --output=target FILE | tail -n +2

Saya dftidak mengenali --outputopsi.
Joseph R.

@ JosephRR. apakah itu versi 8.21 atau lebih tinggi?
terdon

@terdon Tidak, itu versi 8.13.
Joseph R.

2
@ JosephRR. Stephane menjelaskan dalam jawabannya bahwa ini adalah fitur GNU df> = 8.21.
terdon

@terdon Maaf pasti melewatkannya saat membaca sekilas.
Joseph R.

8

Untuk Linux kami memiliki findmnt dari util-linux yang dibuat khusus untuk ini

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

Perhatikan bahwa beberapa jenis mountpoint acak dapat dikembalikan jika ada beberapa bind mounts. Menggunakan dfmemiliki masalah yang sama.


2
Bekerja dengan benar bahkan dengan file yang ada dalam subvolume.
ceremcem

3

Sejak statmengembalikan bidang "Perangkat", saya ingin tahu bagaimana stat()panggilan pustaka yang mendasarinya dapat digunakan untuk mendapatkan informasi ini secara terprogram dengan cara yang sesuai dengan POSIX.

Potongan kode C ini:

#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;
}  

Akan memberikan ID perangkat utama dan kecil untuk perangkat yang berisi file yang tercantum pada baris perintah ( argv[1]). Sayangnya, major()dan minor()bukan POSIX, meskipun halaman manual mengklaim mereka "ada di banyak sistem lain" selain GNU / linux.

Anda kemudian bisa mendapatkan korespondensi antara nomor utama / kecil perangkat dan simpul perangkat dari, mis. /proc/diskstats, Dan memetakan tempat untuk me-mount poin /proc/mounts, alias. /etc/mtab.

Jadi utilitas baris perintah untuk melakukan ini akan sangat sederhana.


/proc/diskstatshanya untuk perangkat blok, Anda akan melewatkan NFS, proc, fuse ... Di Linux setidaknya, mountpoints yang berbeda dapat memiliki maj + min yang sama
Stéphane Chazelas

Tidak tahu itu, terima kasih. Tampaknya juga st_devmungkin tidak menyediakan cara untuk membedakan satu partisi NFS dari yang lain. Siapa pun yang benar-benar ingin menulis ini harus memperhitungkannya;)
goldilocks

Memberi +1 untuk menjadi cukup geek yang Anda anggap menulis kode C "lebih sederhana atau lebih langsung" daripada apa yang dilakukan OP :).
terdon

0

Berikut ini lebih banyak kode C ++ jika Anda ingin melakukan ini dari 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();
  }

Lebih banyak tautan untuk cara-cara terprogram

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.