ฉันจะบอกได้อย่างไรว่าสองไฟล์เชื่อมโยงกันอย่างหนักจากบรรทัดคำสั่ง? เช่นบางสิ่งบางอย่างเชื่อมโยงสิ่งนี้:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
ฉันจะบอกได้อย่างไรว่าสองไฟล์เชื่อมโยงกันอย่างหนักจากบรรทัดคำสั่ง? เช่นบางสิ่งบางอย่างเชื่อมโยงสิ่งนี้:
$ ls
fileA fileB fileC
$ is-hardlinked fileA fileB
yes
$ is-hardlinked fileA fileC
no
คำตอบ:
สำหรับระบบไฟล์ส่วนใหญ่ file ไฟล์จะถูกกำหนดโดยหมายเลขไอโหนดโดยเฉพาะดังนั้นสิ่งที่คุณต้องตรวจสอบคือไฟล์ทั้งสองมีหมายเลขไอโหนดเดียวกันและอยู่ในระบบไฟล์เดียวกันหรือไม่
แอช ksh, ทุบตีและ zsh มีโครงสร้างที่ไม่ตรวจสอบสำหรับคุณ: -efผู้ประกอบแฟ้มเท่าเทียมกัน
[ fileA -ef fileB ] && ! [ fileA -ef fileC ]
สำหรับกรณีขั้นสูงเพิ่มเติมให้ls -i /path/to/fileระบุหมายเลข inode ของไฟล์ df -P /path/to/fileแสดงให้เห็นว่าระบบไฟล์ใดที่ไฟล์นั้นเปิดอยู่ (หากไฟล์สองไฟล์อยู่ในไดเรกทอรีเดียวกันพวกเขาอยู่ในระบบไฟล์เดียวกัน) หากระบบของคุณมีstatคำสั่งมันอาจจะแสดงหมายเลขไอโหนดและระบบไฟล์ ( statแตกต่างจากระบบไปยังระบบตรวจสอบเอกสารของคุณ) หากคุณต้องการภาพรวมของการเชื่อมโยงฮาร์ดไดรฟ์ภายในไดเรกทอรีให้ลองls -i | sort(อาจส่งไปยัง awk )
ystem ระบบไฟล์ยูนิกซ์ดั้งเดิมทั้งหมดและอีกสองสามอย่างเช่น NTFS แต่อาจไม่ใช่กรณีที่แปลกใหม่อย่าง CramFS
fileA -ef fileBยังมีผลตอบแทน0(ความสำเร็จ) ถ้าfileAเป็น symlink ไปfileBหรือในทางกลับกันพวกเขาหรือการเชื่อมโยงทั้งไฟล์เดียวกัน
[ .bashrc -ef .bash/.bashrc ]ถูกต้อง แน่นอนถ้าไม่มีบริบทฉันก็ไม่รู้ว่าทำไม "ไม่ได้ผลจริง" - คุณสามารถเปรียบเทียบไฟล์ที่ไม่ถูกต้องคุณไม่สามารถตรวจสอบผลลัพธ์ได้อย่างถูกต้องคุณสามารถใช้เชลล์โดยไม่ต้อง-ef...
[ testแต่man [หรือman testจะทำให้คุณหน้าคนของคำสั่งภายนอกในขณะที่เพียงเกี่ยวกับทุกเปลือกออกมีมีในตัวคำสั่งกับตัวเลือกที่แตกต่างกันเล็กน้อยดังนั้นคุณต้องมองคนนี้ขึ้นมาในเปลือกของคุณการใช้งาน
function is-hardlinked() {
r=yes
[ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
echo $r
}
stat -c %d) และถ้าคุณอยู่บน Linux (ตามstatคำสั่งของคุณ) เชลล์ของคุณ[ fileA -ef fileB ]จะต้องทำสิ่งนี้ทั้งหมดโดยตรง นอกจากนี้คำสั่งของคุณจะไม่มีการแบ่งชื่อไฟล์ที่มีช่องว่างหรือ\[?*หรือเริ่มต้นด้วย-: ใส่เครื่องหมายอัญประกาศคู่ล้อมรอบคำสั่ง susbtitutions ( "$(stat -c %i -- "$1")") เสมอ
functionคำหลักที่ไม่สามารถเคลื่อนย้ายได้โดยใช้ชื่อฟังก์ชันที่ (เนื่องจากมีเครื่องหมายขีดกลาง) ละเมิดข้อตกลง POSIX ในชื่อที่อนุญาต
$1 $2คุณอาจต้องการใช้$()ไวยากรณ์แทน backticks เพราะวงเล็บทำให้ชัดเจนที่คำสั่งเริ่มต้นและที่มันสิ้นสุดและซ้อนได้ง่ายขึ้น
ในฐานะผู้โพสต์แรกแนะนำคุณสามารถเขียนสคริปต์ตามสิ่งนี้บน Linux:
stat -c '%i' fileA fileB fileC
stat -c %d) และถ้าคุณอยู่บน Linux (ตามstatคำสั่งของคุณ) เชลล์ของคุณ[ fileA -ef fileB ]จะต้องทำสิ่งนี้ทั้งหมดโดยตรง
ด้วย GNU find(1)เวอร์ชั่น 4.2.11 หรือใหม่กว่าคุณสามารถใช้สิ่งนี้:
if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
echo yes
else
echo no
fi
หากfileAเป็นไฟล์เดียวกับfileBแล้วfindจะพิมพ์ "ใช่" และอยู่ในสภาพที่จะกลายเป็นความจริง
ตรงกันข้ามกับการใช้ตัวดำเนินการความเท่าเทียมกันของไฟล์-efสิ่งนี้จะวางไข่กระบวนการใหม่