คุณจะเห็นลิงค์ที่แท้จริงของ ls ได้อย่างไร?


97

ฉันวิ่ง

ln /a/A /b/B

ผมอยากจะเห็นในโฟลเดอร์ที่จุดไฟล์โดยals


1
ฮาร์ดลิงก์ไม่ได้เป็นตัวชี้ ชื่อนี้มีหลายชื่อสำหรับไฟล์เดียวกัน (inode) หลังจากการlink(2)เรียกใช้ระบบจะไม่มีความหมายในสิ่งที่เป็นต้นฉบับและอีกอันคือการเชื่อมโยง find / -samefile /a/Aนี่คือเหตุผลที่เป็นคำตอบชี้ให้เห็นวิธีเดียวที่จะพบการเชื่อมโยงทั้งหมด เนื่องจากรายการไดเรกทอรีหนึ่งสำหรับ inode ไม่ได้ "รู้เกี่ยวกับ" รายการไดเรกทอรีอื่น ๆ ของ inode เดียวกัน ทั้งหมดที่พวกเขาทำคือ refcount inode unlink(2)edเพื่อที่จะสามารถถูกลบเมื่อนามสกุลเพราะมันเป็น (นี่คือ "จำนวนลิงค์" ในlsผลลัพธ์)
Peter Cordes

@PeterCordes: จำนวน refcount จริงเก็บไว้ในรายการ hardlink หรือไม่ นั่นคือสิ่งที่ถ้อยคำของคุณบอกเป็นนัย ("สิ่งที่พวกเขาทำคือ refcount inode ... ") แต่นั่นคงไม่มีเหตุผลถ้าลิงก์ไม่รู้อะไรเลยเกี่ยวกับกันและกันตั้งแต่เมื่ออัปเดตหนึ่งแล้วสิ่งอื่น ๆ ทั้งหมดจะต้อง ได้รับการปรับปรุง หรือ refcount เก็บไว้ในไอโหนดเอง? (ยกโทษให้ฉันถ้ามันเป็นคำถามที่โง่ฉันคิดว่าตัวเองเป็นมือใหม่และฉันยังคงเรียนรู้)
loneboat

1
จำนวน refcount จะถูกเก็บไว้ใน inode ในที่สุดคุณจะต้องเป็นกรณีจากข้อเท็จจริงอื่น ๆ :) รายการไดเรกทอรีชื่อตัวชี้ไปยัง inodes เราเรียกมันว่า "ฮาร์ดลิงก์" เมื่อคุณมีหลายชื่อชี้ไปที่ไอโหนดเดียวกัน
Peter Cordes

คำตอบ:


171

คุณสามารถค้นหาหมายเลขไอโหนดสำหรับไฟล์ของคุณด้วย

ls -i

และ

ls -l

แสดงจำนวนการอ้างอิง (จำนวนของลิงก์ไปยัง inode เฉพาะ)

หลังจากคุณพบหมายเลขไอโหนดคุณสามารถค้นหาไฟล์ทั้งหมดด้วยไอโหนดเดียวกัน:

find . -inum NUM

จะแสดงชื่อไฟล์สำหรับ inode NUM ใน dir ปัจจุบัน (.)


46
คุณสามารถเรียกใช้ค้นหา -samefile ชื่อไฟล์
BeowulfNode42

1
@ BeowulfNode42 คำสั่งนี้ยอดเยี่ยม แต่มันต้องการโฟลเดอร์ root ที่แชร์ของไฟล์เดียวกันอย่างน้อย
Itachi

1
คำตอบนี้ให้ประโยชน์ในเชิงปฏิบัติ "ทำสิ่งนี้" แต่ฉันรู้สึกอย่างยิ่งว่า@LaurenceGonsalves ตอบคำถาม "อย่างไร" และ / หรือ "ทำไม"
เทรเวอร์บอยด์สมิ ธ

65

ไม่มีคำตอบที่ชัดเจนสำหรับคำถามของคุณ ซึ่งแตกต่างจาก symlinks, hardlinks แยกไม่ออกจาก "ไฟล์ต้นฉบับ"

รายการไดเรกทอรีประกอบด้วยชื่อไฟล์และตัวชี้ไปยังไอโหนด inode ในทางกลับกันมีข้อมูลเมตาของไฟล์และ (ตัวชี้ไปที่) เนื้อหาของไฟล์จริง) การสร้างฮาร์ดลิงก์จะสร้างชื่อไฟล์อื่น + อ้างอิงถึงไอโหนดเดียวกัน การอ้างอิงเหล่านี้เป็นแบบทิศทางเดียว (ในระบบไฟล์ทั่วไปอย่างน้อย) - inode จะเก็บการอ้างอิงเท่านั้น ไม่มีวิธีที่แท้จริงในการค้นหาซึ่งเป็นชื่อไฟล์ "ดั้งเดิม"

โดยวิธีการนี้คือเหตุผลที่เรียกระบบที่จะ "ลบ" unlinkไฟล์ที่เรียกว่า มันเพิ่งลบฮาร์ดลิงก์ออก inode ข้อมูลที่แนบมาจะถูกลบเฉพาะเมื่อจำนวนการอ้างอิงของ inode ลดลงถึง 0

วิธีเดียวที่จะค้นหาการอ้างอิงอื่น ๆ ไปยัง inode ที่กำหนดคือการค้นหาอย่างละเอียดมากกว่าระบบไฟล์การตรวจสอบไฟล์ที่อ้างถึง inode ในคำถาม คุณสามารถใช้ 'ทดสอบ A -ef B' จากเปลือกเพื่อทำการตรวจสอบนี้


35
นั่นหมายความว่าไม่มีสิ่งใดเป็นฮาร์ดลิงก์ไปยังไฟล์อื่นเนื่องจากไฟล์ต้นฉบับนั้นเป็นฮาร์ดลิงก์ เชื่อมโยงอย่างหนักชี้ไปที่สถานที่ตั้งบนดิสก์
jtbandes

12
@jtbandes: ฮาร์ดลิงก์ชี้ไปที่ inode ซึ่งชี้ไปยังข้อมูลจริง
dash17291

33

UNIX มีฮาร์ดลิงก์และลิงก์สัญลักษณ์ (สร้างด้วย"ln"และ"ln -s"ตามลำดับ) ลิงก์สัญลักษณ์เป็นเพียงไฟล์ที่มีเส้นทางจริงไปยังไฟล์อื่นและสามารถข้ามระบบไฟล์ได้

ฮาร์ดลิงก์มีมาตั้งแต่ยุคแรกสุดของ UNIX (ที่ฉันจำได้อยู่แล้วและมันกลับมาอีกซักพัก) พวกเขาเป็นสองรายการไดเรกทอรีที่อ้างอิงข้อมูลพื้นฐานเดียวกันแน่นอน inodeข้อมูลในแฟ้มที่ระบุไว้โดยตัวของมัน แต่ละไฟล์บนระบบไฟล์ชี้ไปที่ไอโหนด แต่ไม่จำเป็นว่าไฟล์แต่ละไฟล์จะชี้ไปที่ไอโหนดที่ไม่ซ้ำกันนั่นคือที่มาของฮาร์ดลิงก์

เนื่องจาก inodes มีความเฉพาะตัวสำหรับระบบไฟล์ที่กำหนดจึงมีข้อ จำกัด ว่าฮาร์ดลิงก์ต้องอยู่ในระบบไฟล์เดียวกัน (ซึ่งแตกต่างจากลิงก์สัญลักษณ์) โปรดทราบว่าซึ่งแตกต่างจากลิงก์สัญลักษณ์ไม่มีไฟล์ที่มีสิทธิพิเศษ - ไฟล์เหล่านั้นเท่าเทียมกัน พื้นที่ข้อมูลที่จะถูกปล่อยออกมาเมื่อทุกไฟล์โดยใช้ไอโหนดที่ถูกลบ (และกระบวนการทั้งหมดที่ปิดเช่นกัน แต่ที่เป็นปัญหาที่แตกต่างกัน)

คุณสามารถใช้"ls -i"คำสั่งเพื่อรับ inode ของไฟล์เฉพาะ จากนั้นคุณสามารถใช้"find <filesystemroot> -inum <inode>"คำสั่งเพื่อค้นหาไฟล์ทั้งหมดบนระบบไฟล์ด้วย inode ที่กำหนด

นี่คือสคริปต์ที่ทำอย่างนั้น คุณเรียกใช้ด้วย:

findhardlinks ~/jquery.js

และจะค้นหาไฟล์ทั้งหมดในระบบไฟล์นั้นซึ่งเป็นลิงค์ยากสำหรับไฟล์นั้น:

pax@daemonspawn:~# ./findhardlinks /home/pax/jquery.js
Processing '/home/pax/jquery.js'
   '/home/pax/jquery.js' has inode 5211995 on mount point '/'
       /home/common/jquery-1.2.6.min.js
       /home/pax/jquery.js

นี่คือสคริปต์

#!/bin/bash
if [[ $# -lt 1 ]] ; then
    echo "Usage: findhardlinks <fileOrDirToFindFor> ..."
    exit 1
fi

while [[ $# -ge 1 ]] ; do
    echo "Processing '$1'"
    if [[ ! -r "$1" ]] ; then
        echo "   '$1' is not accessible"
    else
        numlinks=$(ls -ld "$1" | awk '{print $2}')
        inode=$(ls -id "$1" | awk '{print $1}' | head -1l)
        device=$(df "$1" | tail -1l | awk '{print $6}')
        echo "   '$1' has inode ${inode} on mount point '${device}'"
        find ${device} -inum ${inode} 2>/dev/null | sed 's/^/        /'
    fi
    shift
done

@pax: ดูเหมือนว่าจะมีข้อผิดพลาดในสคริปต์ ฉันเริ่มโดย. ./findhardlinks.bashขณะที่อยู่ใน Zsh ของ OS X หน้าต่างปัจจุบันของฉันในหน้าจอปิด

4
@Masi ปัญหาคือสิ่งแรกของคุณ (เหมือนกับคำสั่ง source) ที่ทำให้คำสั่ง exit 1 ออกจากเชลล์ของคุณ ใช้ chmod a + x findhardlinks.bash จากนั้นเรียกใช้งานด้วย. /findhardlinks.bash หรือใช้ bash findhardlinks.bash
njsf

โปรดดูคำตอบของฉันสำหรับคำตอบของคุณที่superuser.com/questions/12972/to-see-hardlinks-by-ls/ …
LéoLéopold Hertz 준영

3
หากต้องการทำสิ่งนี้โดยทางโปรแกรมอาจมีความยืดหยุ่นมากกว่าถ้าคุณใช้สิ่งนี้แทน: INUM=$(stat -c %i $1). NUM_LINKS=$(stat -c %h $1)ด้วย ดูman statตัวแปรรูปแบบเพิ่มเติมที่คุณสามารถใช้ได้
Joe

คำตอบที่ดีที่สุด ความรุ่งโรจน์
MariusMatutiae

24
ls -l

คอลัมน์แรกจะแสดงสิทธิ์ คอลัมน์ที่สองจะเป็นจำนวนรายการย่อย (สำหรับไดเรกทอรี) หรือจำนวนเส้นทางไปยังข้อมูลเดียวกัน (ฮาร์ดลิงก์รวมถึงไฟล์ต้นฉบับ) ไปยังไฟล์ เช่น:

-rw-r--r--@    2    [username]    [group]    [timestamp]     HardLink
-rw-r--r--@    2    [username]    [group]    [timestamp]     Original
               ^ Number of hard links to the data

2
มีประโยชน์ในการพิจารณาว่าไฟล์ที่ระบุมีลิงก์อื่น ๆ หรือไม่ แต่ไม่ใช่ที่ที่พวกเขาอยู่
mklement0

นอกจากนี้ยังไม่มีความแตกต่างทางเทคนิคระหว่างฮาร์ดลิงก์และไฟล์ต้นฉบับ พวกเขาทั้งคู่เหมือนกันในสิ่งที่พวกเขาเพียงแค่ชี้ไปinodeที่จุดหันไปที่เนื้อหาดิสก์
guyarad

13

วิธีการที่ง่ายกว่านี้ต่อไปนี้? (หลังอาจแทนที่สคริปต์ยาวด้านบน!)

หากคุณมีไฟล์เฉพาะ<THEFILENAME>และต้องการทราบว่าฮาร์ดลิงก์ทั้งหมดกระจายอยู่ในไดเรกทอรี<TARGETDIR>(ซึ่งอาจเป็นระบบไฟล์ทั้งหมดที่แสดงโดย/)

find <TARGETDIR> -type f -samefile  <THEFILENAME>

ขยายตรรกะถ้าคุณต้องการทราบไฟล์ทั้งหมดในการ<SOURCEDIR>มีฮาร์ดลิงก์หลายตัวกระจายอยู่<TARGETDIR>:

find <SOURCEDIR> -type f -links +1   \
  -printf "\n\n %n HardLinks of file : %H/%f  \n"   \
  -exec find <TARGETDIR> -type f -samefile {} \; 

นี่คือคำตอบที่ดีที่สุดสำหรับฉัน! แต่ฉันจะไม่ใช้-type fเพราะไฟล์สามารถเป็นไดเรกทอรีด้วย
silvio

3
@silvio: คุณสามารถสร้างฮาร์ดลิงก์ไปยังไฟล์เท่านั้นไม่ใช่ไดเรกทอรี
mklement0

@ mklement0: ถูกต้อง!
silvio

.และ..รายการในไดเรกทอรี hardlinks คุณสามารถบอกได้ว่าหลาย subdirs .อยู่ในไดเรกทอรีจากการนับการเชื่อมโยงของ นี่คือ moot อย่างไรก็ตามเนื่องจากfind -samefile .ยังไม่พิมพ์subdir/..ผลลัพธ์ ใด ๆ find(อย่างน้อยรุ่น GNU) ดูเหมือนว่าจะ hardcoded จะไม่สนใจแม้จะมี.. -noleaf
Peter Cordes

นอกจากนี้แนวคิดการค้นหาลิงก์ทั้งหมดคือO(n^2)และเรียกใช้findครั้งเดียวสำหรับสมาชิกแต่ละคนของชุดไฟล์ฮาร์ด ลิงก์ find ... -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separateจะทำงาน (16 ไม่กว้างพอสำหรับการแสดงทศนิยม 2 ^ 63-1 ดังนั้นเมื่อ XFS ระบบแฟ้มของคุณมีขนาดใหญ่พอที่จะมีหมายเลขไอโหนดที่สูงระวัง)
ปีเตอร์ Cordes

5

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

ด้วยการส่งผ่านระบบไฟล์เพียงครั้งเดียวเพื่อค้นหาและจัดกลุ่มไฟล์ฮาร์ดลิงก์ทั้งหมด

find dirs   -xdev \! -type d -links +1 -printf '%20D %20i %p\n' |
    sort -n | uniq -w 42 --all-repeated=separate

นี่เร็วกว่าคำตอบอื่น ๆในการค้นหาไฟล์ฮาร์ดลิงก์หลายชุด
find /foo -samefile /barดีมากสำหรับไฟล์เดียว

  • -xdev: จำกัด ระบบไฟล์เดียว ไม่จำเป็นอย่างเคร่งครัดเนื่องจากเราพิมพ์ FS-id เป็น uniq ด้วย
  • ! -type dปฏิเสธไดเรกทอรี: .และ..รายการหมายถึงพวกเขาเชื่อมโยงอยู่เสมอ
  • -links +1 : นับลิงค์อย่างเคร่งครัด > 1
  • -printf ...พิมพ์ FS-id, หมายเลขไอโหนดและพา ธ (ด้วยการขยายไปยังความกว้างคอลัมน์คงที่ที่เราสามารถบอกuniqได้)
  • sort -n | uniq ... การเรียงลำดับตัวเลขและไม่ซ้ำกันใน 42 คอลัมน์แรกโดยแยกกลุ่มด้วยบรรทัดว่าง

การใช้! -type d -links +1หมายความว่าอินพุตเรียงลำดับมีขนาดใหญ่เท่ากับเอาต์พุตสุดท้ายของ uniq เท่านั้นดังนั้นเราจึงไม่ได้ทำการเรียงลำดับสตริงจำนวนมาก นอกจากว่าคุณจะรันในไดเรกทอรีย่อยที่มีเพียงหนึ่งในชุดของลิงก์ อย่างไรก็ตามจะใช้เวลา CPU น้อยลงในการข้ามระบบไฟล์มากกว่าโซลูชันที่โพสต์อื่น ๆ

ตัวอย่างผลลัพธ์:

...
            2429             76732484 /home/peter/weird-filenames/test/.hiddendir/foo bar
            2429             76732484 /home/peter/weird-filenames/test.orig/.hiddendir/foo bar

            2430             17961006 /usr/bin/pkg-config.real
            2430             17961006 /usr/bin/x86_64-pc-linux-gnu-pkg-config

            2430             36646920 /usr/lib/i386-linux-gnu/dri/i915_dri.so
            2430             36646920 /usr/lib/i386-linux-gnu/dri/i965_dri.so
            2430             36646920 /usr/lib/i386-linux-gnu/dri/nouveau_vieux_dri.so
            2430             36646920 /usr/lib/i386-linux-gnu/dri/r200_dri.so
            2430             36646920 /usr/lib/i386-linux-gnu/dri/radeon_dri.so
...

สิ่งที่ต้องทำ ?: ยกเลิกแผ่นส่งออกที่มีหรือ awk มีการสนับสนุนการเลือกข้อมูลที่ จำกัด อย่างมากดังนั้นฉันจึงเลือกเอาท์พุท find และใช้ความกว้างคงที่ 20chars กว้างพอสำหรับ inode สูงสุดหรือหมายเลขอุปกรณ์ (2 ^ 64-1 = 18446744073709551615) XFS เลือกหมายเลขไอโหนดตามตำแหน่งที่ดิสก์ถูกจัดสรรไม่ใช่ต่อเนื่องกันตั้งแต่ 0 ดังนั้นระบบไฟล์ XFS ขนาดใหญ่จึงสามารถมีหมายเลข inode> 32 บิตได้แม้ว่าจะไม่มีไฟล์หลายพันล้านไฟล์ก็ตาม ระบบไฟล์อื่นอาจมีหมายเลขไอโหนด 20 หลักแม้ว่าจะไม่ใหญ่โตก็ตามcutuniq

สิ่งที่ต้องทำ: เรียงลำดับกลุ่มของรายการที่ซ้ำกันตามเส้นทาง ให้เรียงลำดับตามจุดเชื่อมต่อจากนั้นหมายเลขไอโหนดจะรวมสิ่งต่าง ๆ เข้าด้วยกันหากคุณมีหลายส่วนย่อยที่มีฮาร์ดลิงก์จำนวนมาก (เช่นกลุ่มของกลุ่มสองกลุ่มทำงานร่วมกัน แต่เอาท์พุทผสมกัน)

สุดท้ายsort -k 3จะเรียงลำดับบรรทัดแยกกันไม่ใช่กลุ่มของบรรทัดเป็นระเบียนเดียว sort --zero-terminated -k 3การประมวลผลล่วงหน้าด้วยบางสิ่งบางอย่างเพื่อแปลงคู่บรรทัดใหม่เป็นไบต์ NUL และการใช้ GNU อาจทำเคล็ดลับได้ trใช้งานได้กับอักขระเดี่ยวเท่านั้นไม่ใช่ 2-> 1 หรือ 1-> 2 รูปแบบ perlจะทำมัน (หรือเพียงแค่แยกและจัดเรียงภายใน Perl หรือ awk) sedอาจใช้งานได้


1
%Dเป็นตัวระบุระบบไฟล์ (เป็นค่าเฉพาะสำหรับการบู๊ตปัจจุบันในขณะที่ไม่มีระบบไฟล์umounted) ดังนั้นการติดตามต่อไปนี้จะเป็นเรื่องทั่วไปมากกว่า: find directories.. -xdev ! -type d -links +1 -printf '%20i %20D %p\n' | sort -n | uniq -w 42 --all-repeated=separate. ใช้งานได้นานหากไม่มีไดเรกทอรีที่ระบุมีไดเรกทอรีอื่นในระดับระบบแฟ้มรวมถึงดูทุกสิ่งที่สามารถเชื่อมโยงได้ (เช่นอุปกรณ์หรือซอฟต์ลิงค์ - ใช่ซอฟต์ลิงค์สามารถนับลิงค์ได้มากกว่า 1) โปรดทราบว่าdev_tและino_tวันนี้มีความยาว 64 บิต สิ่งนี้น่าจะมีอยู่ตราบใดที่เรามีระบบ 64 บิต
Tino

@Tino: จุดดีเกี่ยวกับการใช้ใช้แทน! -type d -type fฉันยังมี symlink ที่ฮาร์ดลิงก์บางตัวในระบบไฟล์ของฉันจากการจัดระเบียบกลุ่มของไฟล์ Updated ตอบของฉันกับรุ่นปรับปรุงของคุณ ( แต่ผมใส่ FS-ID แรกดังนั้นการเรียงลำดับในกลุ่มน้อยโดยระบบแฟ้ม.)
ปีเตอร์ Cordes

3

นี่เป็นข้อคิดเห็นบางอย่างสำหรับคำตอบและสคริปต์ของ Torocoro-Macho แต่เห็นได้ชัดว่ามันไม่เหมาะสมในช่องแสดงความคิดเห็น


เขียนสคริปต์ของคุณใหม่ด้วยวิธีการที่ตรงไปตรงมามากขึ้นในการค้นหาข้อมูลและทำให้การเรียกใช้กระบวนการน้อยลง

#!/bin/sh
xPATH=$(readlink -f -- "${1}")
for xFILE in "${xPATH}"/*; do
    [ -d "${xFILE}" ] && continue
    [ ! -r "${xFILE}" ] && printf '"%s" is not readable.\n' "${xFILE}" 1>&2 && continue
    nLINKS=$(stat -c%h "${xFILE}")
    if [ ${nLINKS} -gt 1 ]; then
        iNODE=$(stat -c%i "${xFILE}")
        xDEVICE=$(stat -c%m "${xFILE}")
        printf '\nItem: %s[%d] = %s\n' "${xDEVICE}" "${iNODE}" "${xFILE}";
        find "${xDEVICE}" -inum ${iNODE} -not -path "${xFILE}" -printf '     -> %p\n' 2>/dev/null
    fi
done

ฉันพยายามทำให้มันคล้ายกับของคุณมากที่สุดเพื่อการเปรียบเทียบที่ง่าย

ความคิดเห็นเกี่ยวกับสคริปต์นี้และของคุณ

  • เราควรหลีกเลี่ยง$IFSเวทย์มนตร์เสมอหากมี glob พอเพราะมันซับซ้อนโดยไม่จำเป็นและชื่อไฟล์จริงสามารถมีการขึ้นบรรทัดใหม่ (แต่ในทางปฏิบัติส่วนใหญ่เหตุผลแรก)

  • คุณควรหลีกเลี่ยงการวิเคราะห์คำด้วยตนเองlsและออกมากที่สุดเท่าที่จะเป็นไปได้เพราะมันจะกัดคุณไม่ช้าก็เร็ว ตัวอย่างเช่น: ในawkบรรทัดแรกของคุณคุณล้มเหลวในทุกชื่อไฟล์ที่มีช่องว่าง

  • printfมักจะบันทึกปัญหาในที่สุดเนื่องจากมีความแข็งแกร่งกับ%sไวยากรณ์ นอกจากนี้ยังให้คุณควบคุมการแสดงผลได้อย่างเต็มที่และสอดคล้องกับทุกระบบไม่เหมือนechoกัน

  • stat สามารถช่วยคุณประหยัดได้มากในกรณีนี้

  • GNU find มีพลัง

  • คุณheadและtailการร้องขอสามารถจัดการได้โดยตรงawkกับเช่นexitคำสั่งและ / หรือการเลือกNRตัวแปร สิ่งนี้จะบันทึกขั้นตอนการร้องขอซึ่งนักพนันส่วนใหญ่มักทำงานหนักในสคริปต์ที่ทำงานหนัก

  • คุณegreps grepสามารถก็เช่นกันจะเป็นเพียงแค่


xDEVICE = $ (stat -c% m "$ {xFILE}") ใช้ไม่ได้กับทุกระบบ (เช่น: stat (GNU coreutils) 6.12) หากสคริปต์แสดงผล "รายการ:?" ที่ด้านหน้าของแต่ละบรรทัดจากนั้นแทนที่บรรทัดที่ละเมิดนี้ด้วยบรรทัดเหมือนสคริปต์ต้นฉบับ แต่ด้วย xITEM เปลี่ยนชื่อเป็น xFILE: xDEVICE = $ (df "$ {xFILE}" | tail -1l | awk '{print $ 6} ')
kbulgrien

ถ้าคุณเพียงต้องการกลุ่ม hardlinks มากกว่าซ้ำกับสมาชิกแต่ละคนเป็น "ต้นแบบ" find ... -xdev -type f -links +1 -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separateการใช้งาน นี่คือเร็วกว่ามากเนื่องจากมันเคลื่อนที่ผ่าน fs เพียงครั้งเดียว สำหรับหลาย FS พร้อมกันคุณจะต้องใส่หมายเลข inode ด้วยรหัส FS อาจจะด้วยfind -exec stat... -printf ...
Peter Cordes

เปลี่ยนความคิดนั้นให้เป็นคำตอบ
Peter Cordes

2

ตามfindhardlinksสคริปต์ (เปลี่ยนชื่อเป็นhard-links) นี่คือสิ่งที่ฉันได้รับการปรับโครงสร้างใหม่และทำให้ใช้งานได้

เอาท์พุท:

# ./hard-links /root

Item: /[10145] = /root/.profile
    -> /proc/907/sched
    -> /<some-where>/.profile

Item: /[10144] = /root/.tested
    -> /proc/907/limits
    -> /<some-where else>/.bashrc
    -> /root/.testlnk

Item: /[10144] = /root/.testlnk
    -> /proc/907/limits
    -> /<another-place else>/.bashrc
    -> /root/.tested

 

# cat ./hard-links
#!/bin/bash
oIFS="${IFS}"; IFS=$'\n';
xPATH="${1}";
xFILES="`ls -al ${xPATH}|egrep "^-"|awk '{print $9}'`";
for xFILE in ${xFILES[@]}; do
  xITEM="${xPATH}/${xFILE}";
  if [[ ! -r "${xITEM}" ]] ; then
    echo "Path: '${xITEM}' is not accessible! ";
  else
    nLINKS=$(ls -ld "${xITEM}" | awk '{print $2}')
    if [ ${nLINKS} -gt 1 ]; then
      iNODE=$(ls -id "${xITEM}" | awk '{print $1}' | head -1l)
      xDEVICE=$(df "${xITEM}" | tail -1l | awk '{print $6}')
      echo -e "\nItem: ${xDEVICE}[$iNODE] = ${xITEM}";
      find ${xDEVICE} -inum ${iNODE} 2>/dev/null|egrep -v "${xITEM}"|sed 's/^/   -> /';
    fi
  fi
done
IFS="${oIFS}"; echo "";

ฉันโพสต์ความคิดเห็นเกี่ยวกับสคริปต์นี้เป็นคำตอบแยกต่างหาก
Daniel Andersson

1

โซลูชัน GUI ใกล้กับคำถามของคุณจริง ๆ :

คุณไม่สามารถแสดงรายการไฟล์ฮาร์ดลิงก์ที่เกิดขึ้นจริงจาก "ls" เพราะเนื่องจากผู้วิจารณ์ก่อนหน้าได้ชี้ให้เห็นว่าไฟล์ "ชื่อ" เป็นเพียงนามแฝงกับข้อมูลเดียวกัน อย่างไรก็ตามมีเครื่องมือ GUI ที่ใกล้เคียงกับสิ่งที่คุณต้องการจริงๆคือการแสดงรายการพา ธ ของชื่อไฟล์ที่ชี้ไปที่ข้อมูลเดียวกัน (เป็นฮาร์ดลิงก์) ภายใต้ลินุกซ์เรียกว่า FSLint ตัวเลือกที่คุณต้องการอยู่ภายใต้ "ชื่อ clashes" -> ยกเลิกการเลือก "$ PATH" ในการค้นหา (XX) -> และเลือก "นามแฝง" จากช่องแบบเลื่อนลงหลังจาก "for ... " ไปยังกึ่งกลางด้านบน

FSLint มีเอกสารไม่ดีมาก แต่ฉันพบว่าทำให้แน่ใจว่าไดเรกทอรีต้นไม้ที่ จำกัด ภายใต้ "เส้นทางการค้นหา" ด้วยช่องทำเครื่องหมายที่เลือกสำหรับ "เรียกคืนหรือไม่" และตัวเลือกข้างต้นการแสดงรายการของข้อมูลฮาร์ดลิงก์ที่มีพา ธ และชื่อที่ "ชี้" ไปยังข้อมูลเดียวกันจะถูกสร้างขึ้นหลังจากโปรแกรมค้นหา


FSlint สามารถพบได้ที่pixelbeat.org/fslint
mklement0

1

คุณสามารถกำหนดค่าlsเพื่อเน้นการเชื่อมโยงโดยใช้ 'นามแฝง' แต่ตามที่ระบุไว้ก่อนหน้านี้ไม่มีวิธีแสดง 'แหล่งที่มา' ของการเชื่อมโยงซึ่งเป็นสาเหตุที่ฉันผนวก.hardlinkเพื่อช่วย

ไฮไลต์การเชื่อมโยง

เพิ่มสิ่งต่อไปนี้ในของคุณ .bashrc

alias ll='LC_COLLATE=C LS_COLORS="$LS_COLORS:mh=1;37" ls -lA --si --group-directories-first'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.