sed
สร้างไฟล์ชั่วคราวเขียนเอาต์พุตลงในไฟล์นั้นจากนั้นเปลี่ยนชื่อไฟล์ชั่วคราวที่ด้านบนของต้นฉบับ
คุณสามารถดูสิ่งที่เกิดขึ้นโดยใช้strace
:
$ strace -e trace=file sed -i -e '' a
execve("/usr/bin/sed", ["sed", "-i", "-e", "", "a"], [/* 34 vars */]) = 0
<...trimmed...>
open("a", O_RDONLY) = 3
open("./sedxvhRY8", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
rename("./sedxvhRY8", "a") = 0
+++ exited with 0 +++
บันทึกทั้งหมดนี้การดำเนินงานไฟล์sed
ทำให้มันสร้างไฟล์ใหม่ (อย่างปลอดภัยด้วยO_CREAT|O_EXCL
) a
เขียนข้อมูลลงไปและจากนั้นย้ายกลับไปด้านบนของไฟล์ต้นฉบับของฉัน
sed -i
ยอมรับคำต่อท้ายที่จะใช้สำหรับการสำรองข้อมูลและในกรณีนั้นมันจะย้ายต้นฉบับออกไปก่อน (แทนที่จะเปลี่ยนชื่อเป็นด้านบน) ข้อโต้แย้งที่มีผลบังคับใช้ในส่วน BSD sed
s ในกรณีนี้มีช่วงเวลาสั้น ๆ เมื่อไม่มีไฟล์ชื่อที่ถูกต้องในไดเรกทอรีเลย
perl
ในเวอร์ชันล่าสุดเปิดไฟล์อินพุตจากนั้นลบมันและสร้างไฟล์ใหม่ด้วยชื่อเดียวกัน:
open("a", O_RDONLY) = 3
unlink("a") = 0
open("a", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4
เมื่อคุณลบ ( unlink
) ไฟล์ที่คุณเปิดไว้แล้วคุณจะยังคงเข้าถึงมันได้ตราบใดที่คุณยังคงใช้งานได้ดังนั้นมันสามารถอ่านข้อมูลออกจากไฟล์ที่ถูกลบได้ ด้วยวิธีนี้perl
เขียนลงในไฟล์เอาต์พุตโดยตรงแทนที่จะเป็นไฟล์ชั่วคราว: ไม่มีการสร้างไฟล์เพิ่มเติม แต่ถ้าคุณอ่านไฟล์ในระหว่างกระบวนการคุณจะได้รับเนื้อหาบางส่วนซึ่งแตกต่างจากsed
วิธีการของ นอกจากนี้ยังมีช่วงเวลาสั้น ๆ เมื่อไม่มีไฟล์ที่มีชื่อที่ถูกต้องซึ่งเป็นจุดเริ่มต้นของกระบวนการแทนการสิ้นสุด (เหมือนในsed -i .bak
)
ทั้งsed
และperl
จะ:
- แทนที่ลิงก์สัญลักษณ์ด้วยไฟล์ธรรมดา
- ทำลายการเชื่อมโยงอย่างหนัก
- รักษาความเป็นเจ้าของกลุ่มถ้าเป็นไปได้
- สร้างไฟล์ที่มีกลุ่มเริ่มต้นของคุณ (หรือกลุ่มของไดเรกทอรีหลักหากไดเรกทอรีนั้นมี
setgid
บิต) หากเป็นกลุ่มที่คุณไม่ได้เป็นเจ้าของและคุณไม่ได้รูท
- รักษาความเป็นเจ้าของไฟล์หากคุณรูท
- รักษาสิทธิ์พื้นฐาน
- รักษา
setuid
และsetgrp
บิตถ้ากลุ่มผลลัพธ์เหมือนกันกับกลุ่มที่เริ่ม
- รักษาความเหนียว
- ไม่รักษา xattrs
sed
จะ:
- รักษา ACLs (บนลินุกซ์; ผมไม่ทราบว่าเกี่ยวกับคนอื่น)
perl
จะ:
ดังกล่าวข้างต้นเป็นความจริงบน Linux กับ GNU sed
และ Mac OS X ด้วย (FreeBSD sed
มา)