ความแตกต่างระหว่าง 'rm' และ 'unlink' คืออะไร?


55

สมมติว่าคุณรู้ว่าเป้าหมายคือลิงก์สัญลักษณ์และไม่ใช่ไฟล์มีความแตกต่างระหว่างการใช้rmและunlinkการลบลิงก์หรือไม่


3
สิ่งนี้ได้รับการคุ้มครองอย่างดีใน ServerFault: serverfault.com/questions/38816/…
slm

@ slm ♦คำตอบตรงกับคำถามนั้น แต่คำถามนี้แตกต่างกันมันบอกว่า: "สมมติว่าคุณรู้ว่าเป้าหมายนั้นเป็นลิงก์สัญลักษณ์ไม่ใช่ไฟล์"
Stéphane Gourichon

ดูเหมือนว่าคุณไม่ได้รับคำตอบที่นี่ @IQAndreas โปรดทำเช่นนั้นหากพวกเขาช่วยคุณ
สีเทา

คำตอบ:


56

เมื่อใดก็ตามที่คุณมีคำถามประเภทนี้คุณควรทดสอบข้อสอบเล็กน้อยเพื่อดูว่าเกิดอะไรขึ้นจริง straceสำหรับนี้คุณสามารถใช้

ยกเลิกการเชื่อมโยง

$ touch file1
$ strace -s 2000 -o unlink.log unlink file1

RM

$ touch file1
$ strace -s 2000 -o rm.log rm file1

เมื่อคุณดูแฟ้มบันทึกผลลัพธ์ 2 รายการคุณสามารถ "เห็น" การโทรแต่ละครั้งทำอะไรได้จริง

ชำรุด

ด้วยunlinkการเรียกใช้การunlink()เรียกระบบ:

....
mmap(NULL, 106070960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6d025cc000
close(3)                                = 0
unlink("file1")                         = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
....

ด้วยrmเส้นทางที่แตกต่างกันเล็กน้อย:

....
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid()                               = 1000
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "file1", W_OK)      = 0
unlinkat(AT_FDCWD, "file1", 0)          = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
...

สายระบบunlink()และunlinkat()เป็นหลักเดียวกันยกเว้นสำหรับความแตกต่างที่อธิบายไว้ในหน้าคนนี้: http://linux.die.net/man/2/unlinkat

สิ่งที่สกัดมา

การเรียกใช้ระบบ unlinkat () ทำงานในลักษณะเดียวกับ unlink (2) หรือ rmdir (2) (ขึ้นอยู่กับว่าธงนั้นมีธง AT_REMOVEDIR หรือไม่) ยกเว้นความแตกต่างที่อธิบายไว้ในหน้าคู่มือนี้

หากชื่อพา ธ ที่กำหนดในชื่อพา ธ นั้นสัมพันธ์กันมันจะถูกแปลความสัมพันธ์กับไดเรกทอรีที่อ้างถึงโดยไฟล์ descriptor dirfd (แทนที่จะเป็นญาติกับไดเรกทอรีการทำงานปัจจุบันของกระบวนการเรียกเช่นเดียวกับ unlink (2) และ rmdir (2) ) สำหรับชื่อพา ธ สัมพัทธ์)

หากชื่อพา ธ ที่กำหนดในชื่อพา ธ นั้นสัมพันธ์กันและ dirfd เป็นค่าพิเศษ AT_FDCWD ดังนั้นชื่อพา ธ จะถูกแปลความสัมพันธ์กับไดเรกทอรีการทำงานปัจจุบันของกระบวนการเรียก (เช่น unlink (2) และ rmdir (2))

หากชื่อพา ธ ที่กำหนดในชื่อพา ธ เป็นสัมบูรณ์ดังนั้น dirfd จะถูกละเว้น


1
ตั้งแต่มันให้AT_FDCWDมีประสิทธิภาพแตกต่างระหว่างไม่มีและunlink unlinkat
Barmar

6
มันทำให้ฉันมีความสุขที่จะอ่านคำตอบนี้เพราะผมเพียงแค่ "เรียนรู้ที่จะตกปลา" ในการที่มีประสิทธิภาพวิธีการที่ยืดหยุ่นเมื่อฉันมักจะได้รับปลาหรือบางครั้งฉัน "เรียนรู้ที่จะปลา" ในทางพื้นฐานในดังนั้น :-)
ปัญญาชน

20

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

rmเป็นคำสั่ง Unix แบบดั้งเดิมซึ่งมีฟังก์ชั่นอื่น ๆ อยู่บ้างและไม่ได้เป็นชุดของunlink(ดูด้านล่าง)

ประการแรกrmทำการตรวจสอบความปลอดภัย หากคุณลองrmวัตถุที่คุณไม่มีสิทธิ์เขียน (ซึ่งไม่เกี่ยวข้องกับความสามารถของคุณในการลบออก: สิทธิ์โดยตรงคือ!) rmอย่างไรก็ตามจะปฏิเสธเว้นแต่-fจะระบุไว้ rmโดยปกติจะบ่นว่าไฟล์ไม่มีอยู่จริงเช่นเดียวกับunlink; แต่ด้วย-f, rmไม่บ่น วิธีนี้มักใช้ใน Makefiles ( clean: @rm -f $(OBJS) ...) ดังนั้นจึงmake cleanไม่ล้มเหลวเมื่อไม่มีสิ่งใดที่จะลบ

ประการที่สองrmมี-iตัวเลือกสำหรับยืนยันการลบแบบโต้ตอบ

ประการที่สามrmมี-rการลบไดเรกทอรีซ้ำซึ่งเป็นสิ่งที่unlinkไม่จำเป็นต้องทำเนื่องจากฟังก์ชั่นห้องสมุด C ไม่ได้ทำเช่นนั้น

ยูทิลิตี้ไม่ว่าปล้นลงunlink rmจะดำเนินการส่วนหนึ่งของสิ่งที่rmไม่ แต่มันมีความหมายซึ่งเป็นชุดของrm มี -fและ RM โดยไม่ต้อง -f

สมมติว่าคุณต้องการเพียงแค่ลบไฟล์ปกติโดยไม่คำนึงถึงสิทธิ์ของตนเอง นอกจากนี้สมมติว่าคุณต้องการให้คำสั่งล้มเหลวหากไฟล์ไม่มีอยู่หรือด้วยเหตุผลอื่น ทั้งrm fileมิได้rm -f fileเป็นไปตามข้อกำหนด rm fileจะปฏิเสธหากไฟล์ไม่สามารถเขียนได้ แต่rm -f fileจะไม่สนใจบ่นหากไฟล์หายไป unlink fileทำงาน

unlinkอาจถูกนำมาใช้เพราะrmเป็นคนฉลาดเกินไป: บางครั้งคุณก็ต้องการให้บริสุทธิ์ Unix unlinkความหมาย: "โปรดให้รายการไดเรกทอรีนี้หายไปถ้าไดเรกทอรีสิทธิ์อนุญาตให้"


2
นี่คือคำตอบที่ชัดเจนที่สุดที่นี่ จริง ๆ แล้วมันให้กรณีใช้สำหรับunlinkแทนที่จะอธิบายความแตกต่าง
Wildcard

19

ด้วยไฟล์เดียวrmและunlinkทำภารกิจเดียวกันลบไฟล์ ตามที่กำหนดไว้ใน POSIX rmและunlinkทั้งการเรียกเพื่อยกเลิกการเชื่อมโยง () การโทรของระบบ

ใน GNU rmจะเรียกใช้เพื่อยกเลิกการเชื่อมโยงการเรียกระบบซึ่งเทียบเท่ากับฟังก์ชั่นunlink()หรือrmdir ()ยกเว้นในกรณีที่เส้นทางระบุเส้นทางที่สัมพันธ์กัน

บันทึก

ในบางระบบunlinkสามารถลบไดเรกทอรีได้ อย่างน้อยที่สุดในระบบ GNU unlinkไม่สามารถลบชื่อไดเรกทอรีได้

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