Làm thế nào để có được điểm gắn kết của hệ thống tập tin có chứa tệp đã cho


13

Tôi đang tìm kiếm một cách nhanh chóng để tìm điểm gắn kết của hệ thống tệp có chứa một TẬP TIN. Có điều gì đơn giản hơn hoặc trực tiếp hơn giải pháp của tôi dưới đây không?

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

Một câu hỏi tương tự " Có lệnh nào để xem đĩa được gắn ở đâu không? " Sử dụng nút thiết bị của đĩa hiện tại làm đầu vào và không phải là tệp tùy ý từ đĩa ...


1
Bạn có thể loại bỏ trcuộc gọi cuối cùng bằng cách sử dụngawk -F'% '...
Joseph R.

Câu trả lời:


6

Bạn có thể làm một cái gì đó như

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

hoặc thậm chí

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

Vì các awkphân chia trên (các) khoảng trắng theo mặc định, bạn không cần chỉ định -Fvà bạn cũng không cần phải cắt khoảng trắng với tr. Cuối cùng, bằng cách chỉ định số dòng quan tâm ( NR==2) bạn cũng có thể loại bỏ tail.


câu thần chú thứ 2 hoạt động vượt trội, trong khi tôi phải thay đổi 2 thành 3 trong lần đầu tiên. gọn gàng
Stu

@Gilles, cảm ơn đã chỉnh sửa. Một câu hỏi, thứ hai nên làm việc ngay cả khi không có -Pphải không? Trong mọi trường hợp, trường cuối cùng được in bằng awkphải là đĩa.
terdon

@Stu đó có lẽ là do tôi đã không sử dụng -Ptùy chọn mà Gilles vừa thêm.
terdon

1
@terdon Vâng, thực sự, trường cuối cùng của dòng cuối cùng là không có -P. Tuy nhiên, tôi khuyên bạn nên luôn luôn sử dụng -Pkhi bạn phân tích cú pháp đầu ra df, việc kiểm tra xem việc sử dụng cụ thể này có an toàn không.
Gilles 'SO- ngừng trở nên xấu xa'

đẹp. nếu bây giờ bạn cần nhập / dev cho $ {FILE} (vì một số lý do)mount | grep " on $(df -P ${FILE} | awk 'END{print $NF}') type" | awk '{print $1}'
không đồng bộ hóa vào

16

Trên GNU / Linux, nếu bạn có GNU stattừ coreutils 8.6 trở lên, bạn có thể làm:

stat -c %m -- "$file"

Nếu không thì:

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

Cách tiếp cận của bạn là hợp lệ nhưng giả sử điểm gắn kết không chứa khoảng trắng,%, dòng mới hoặc các ký tự không in được khác, bạn có thể đơn giản hóa nó một chút với các phiên bản GNU mới hơn df(8.21 trở lên):

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

Tôi dfkhông nhận ra --outputtùy chọn.
Joseph R.

@JosephR. phiên bản 8.21 trở lên?
terdon

@terdon Không có phiên bản 8.13.
Joseph R.

2
@JosephR. Stephane giải thích trong câu trả lời của mình rằng đây là một tính năng của GNU df> = 8.21.
terdon

@terdon Xin lỗi vì đã bỏ lỡ nó trong khi lướt qua.
Joseph R.

8

Đối với Linux, chúng tôi đã tìm thấy từ linux-linux được tạo chính xác cho việc này

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

Lưu ý rằng một số loại gắn kết ngẫu nhiên có thể được trả về trong trường hợp có một số gắn kết liên kết. Sử dụng dfcó cùng một vấn đề.


2
Hoạt động chính xác ngay cả với các tệp trong subvolume.
ceremcem

3

stattrả về trường "Thiết bị", tôi tò mò muốn xem cách stat()gọi thư viện cơ bản có thể được sử dụng để lấy thông tin này theo chương trình theo cách tuân thủ POSIX.

Đoạn mã C này:

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

Sẽ cung cấp ID thiết bị chính và phụ cho thiết bị chứa tệp được liệt kê trên dòng lệnh ( argv[1]). Thật không may, major()minor()không phải là POSIX, mặc dù trang man tuyên bố chúng "hiện diện trên nhiều hệ thống khác" bên cạnh GNU / linux.

Sau đó, bạn có thể nhận được sự tương ứng giữa số chính / số phụ của thiết bị và nút thiết bị từ, ví dụ /proc/diskstats, và ánh xạ để gắn điểm từ /proc/mounts, aka. /etc/mtab.

Vì vậy, một tiện ích dòng lệnh để làm điều này sẽ khá đơn giản.


/proc/diskstatschỉ dành cho các thiết bị khối, bạn sẽ bỏ lỡ NFS, Proc, fuse ... Trên Linux ít nhất, các điểm gắn kết khác nhau có thể có cùng một chủ đề + min
Stéphane Chazelas

Không biết điều đó, thx. Dường như st_devcó thể không cung cấp cách phân biệt một phân vùng NFS với phân vùng khác. Bất cứ ai thực sự muốn viết điều này sẽ phải tính đến điều đó;)
goldilocks

+1 vì đủ đam mê mà bạn cho là viết mã C "đơn giản hoặc trực tiếp hơn" so với những gì OP đang làm :).
terdon

0

Đây là nhiều mã C ++ hơn nếu bạn muốn làm điều này từ 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();
  }

Thêm liên kết cho các cách lập trình

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.