วิธีรับจุดเมานต์ของระบบไฟล์ที่มีไฟล์ที่กำหนด


13

ฉันกำลังมองหาวิธีที่รวดเร็วในการค้นหาจุดเมานท์ของระบบไฟล์ที่มีไฟล์ที่กำหนด มีอะไรที่ง่ายกว่าหรือมากกว่าตรงกว่าโซลูชันของฉันด้านล่างหรือไม่

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

คำถามที่คล้ายกัน " มีคำสั่งให้ดูตำแหน่งที่ติดตั้งดิสก์หรือไม่ " ใช้โหนดอุปกรณ์ของดิสก์ปัจจุบันเป็นอินพุตและไม่ใช่ไฟล์โดยพลการจากดิสก์ ...


1
คุณสามารถทำได้ด้วยการtrโทรครั้งสุดท้ายโดยใช้awk -F'% '...
โจเซฟอาร์

คำตอบ:


6

คุณสามารถทำสิ่งที่ชอบ

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

หรือแม้กระทั่ง

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

ตั้งแต่awkแยกบนช่องว่าง (s) โดยค่าเริ่มต้นที่คุณไม่จำเป็นต้องระบุและคุณยังไม่จำเป็นต้องตัดช่องว่างด้วย-F trในที่สุดโดยการระบุจำนวนบรรทัดที่น่าสนใจ ( NR==2) tailคุณยังสามารถทำไปด้วย


คาถาที่ 2 ทำงานนอกกรอบได้ในขณะที่ฉันต้องเปลี่ยน 2 เป็น 3 ในครั้งแรก เรียบร้อย
Stu

@Gilles ขอบคุณสำหรับการแก้ไข คำถามหนึ่งข้อคำถามที่สองควรใช้งานได้โดยไม่ -Pถูกต้องใช่ไหม ในทุกกรณีฟิลด์สุดท้ายที่พิมพ์โดยawkควรเป็นดิสก์
terdon

@Stu นั่นอาจเป็นเพราะฉันไม่ได้ใช้-Pตัวเลือกที่ Gilles เพิ่งเพิ่มเข้าไป
terdon

1
@terdon -Pใช่แน่นอนสนามสุดท้ายของบรรทัดสุดท้ายจะเหมือนกันได้โดยไม่ต้อง อย่างไรก็ตามฉันขอแนะนำให้ใช้เสมอ-Pเมื่อคุณแยกวิเคราะห์ผลลัพธ์ของdfมันง่ายกว่าการตรวจสอบว่าการใช้งานนี้ปลอดภัย
Gilles 'หยุดความชั่วร้าย'

ดี ถ้าคุณต้องการตอนนี้รายการ / dev สำหรับ $ {FILE} (ด้วยเหตุผลบางอย่าง)mount | grep " on $(df -P ${FILE} | awk 'END{print $NF}') type" | awk '{print $1}'
ไนซ์

16

บน GNU / Linux ถ้าคุณมี GNU statจาก coreutils 8.6 หรือสูงกว่าคุณสามารถทำได้:

stat -c %m -- "$file"

มิฉะนั้น:

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

วิธีการของคุณถูกต้อง แต่ถือว่าจุดเชื่อมต่อไม่มีพื้นที่,%, บรรทัดใหม่หรืออักขระที่ไม่สามารถพิมพ์ได้อื่น ๆ คุณสามารถทำให้มันง่ายขึ้นเล็กน้อยด้วย GNU เวอร์ชั่นใหม่df(8.21 หรือสูงกว่า):

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

ฉันdfไม่รู้จัก--outputตัวเลือก
โจเซฟอาร์

@JosephR มันเป็นรุ่น 8.21 หรือสูงกว่า?
terdon

@terdon ไม่ใช่เวอร์ชั่น 8.13
Joseph R.

2
@JosephR Stephane อธิบายในคำตอบของเขาว่านี่เป็นคุณสมบัติของ GNU df> = 8.21
terdon

@terdon ขออภัยต้องพลาดในขณะที่อ่านผ่าน ๆ
โจเซฟอาร์

8

สำหรับลีนุกซ์เรามี findmnt จาก util-linux ที่สร้างขึ้นตรงนี้

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

โปรดทราบว่าจุดเมานท์สุ่มบางประเภทอาจถูกส่งคืนในกรณีที่มีการเชื่อมต่อหลายจุด การใช้dfมีปัญหาเดียวกัน


2
ทำงานอย่างถูกต้องแม้กับไฟล์ที่อยู่ในไดรฟ์ย่อย
ceremcem

3

เนื่องจากstatส่งคืนฟิลด์ "อุปกรณ์" ฉันอยากรู้ว่าstat()จะใช้การเรียกไลบรารี่พื้นฐานเพื่อรับข้อมูลนี้โดยทางโปรแกรมในลักษณะ POSIX ได้อย่างไร

ตัวอย่างรหัส 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;
}  

จะให้รหัสอุปกรณ์หลักและรองสำหรับอุปกรณ์ที่มีไฟล์อยู่ในบรรทัดคำสั่ง ( argv[1]) แต่น่าเสียดายmajor()และminor()ไม่ได้ POSIX แม้ว่าการเรียกร้องหน้าคนพวกเขาเป็น "ปัจจุบันในระบบอื่น ๆ อีกมากมาย" นอกจาก GNU / Linux

จากนั้นคุณสามารถได้รับการติดต่อระหว่างอุปกรณ์หลัก / รองหมายเลขและโหนดอุปกรณ์จากเช่น/proc/diskstatsและแมปที่จะเมานต์จุดจาก/proc/mountsaka /etc/mtab.

ดังนั้นอรรถประโยชน์บรรทัดคำสั่งในการทำเช่นนี้จึงค่อนข้างง่าย


/proc/diskstatsมีไว้สำหรับอุปกรณ์บล็อกเท่านั้นคุณจะพลาด NFS proc ฟิวส์ ... บน Linux อย่างน้อยจุดเมานท์ที่แตกต่างกันสามารถมี maj + min เหมือนกัน
Stéphane Chazelas

ไม่ทราบว่าขอบคุณ ดูเหมือนว่าst_devอาจไม่มีวิธีแยกพาร์ติชัน NFS หนึ่งจากอีกพาร์ติชันหนึ่ง ใครก็ตามที่ต้องการเขียนสิ่งนี้จะต้องคำนึงถึงเรื่องนั้นด้วย)
goldilocks

+1 สำหรับความพร้อมที่เกินบรรยายซึ่งคุณพิจารณาการเขียนรหัส C "ง่ายกว่าหรือตรงกว่า" กว่าสิ่งที่ OP กำลังทำอยู่ :)
terdon

0

นี่คือรหัส C ++ เพิ่มเติมหากคุณต้องการทำสิ่งนี้จาก 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();
  }

ลิงก์เพิ่มเติมสำหรับวิธีการเขียนโปรแกรม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.