ทำไมคุณถึง cat / dev / null ไปยังอะไร?
คุณจะทำเช่นนั้นเพื่อตัดทอนเนื้อหาไฟล์ในขณะที่ยังคง inode เหมือนเดิม โปรแกรมทั้งหมดที่เปิดไฟล์นั้นไว้สำหรับการอ่านหรือเขียนจะไม่ได้รับผลกระทบจากความจริงที่ว่าขนาดไฟล์จะถูกรีเซ็ตเป็นศูนย์
ทางเลือกที่พบบ่อยปลอมเป็นการลบไฟล์จากนั้นสร้างใหม่อีกครั้ง:
rm file
touch file
หรือคล้ายกัน:
mv file file.old
gzip file.old
touch file
ปัญหาคือวิธีการเหล่านี้ไม่ได้ป้องกันไม่ให้ไฟล์เก่าถูกเขียนโดยกระบวนการใดก็ตามที่มีไฟล์ที่ถูกลบเปิดในเวลาที่ลบ เหตุผลที่อยู่ภายใต้ระบบไฟล์ Unix เมื่อคุณลบไฟล์คุณจะยกเลิกการเชื่อมโยงชื่อ (พา ธ ) จากเนื้อหา (inode) เท่านั้น ไอโหนดจะยังคงมีชีวิตอยู่ตราบใดที่มีกระบวนการที่เปิดให้อ่านหรือเขียน
สิ่งนี้นำไปสู่ผลกระทบด้านลบหลายประการ: บันทึกที่เขียนหลังจากการลบไฟล์จะหายไปเนื่องจากไม่มีวิธีที่ง่าย / สะดวกในการเปิดไฟล์ที่ถูกลบ ตราบเท่าที่กระบวนการกำลังเขียนไปยังไฟล์ที่ถูกลบเนื้อหาของมันยังคงใช้พื้นที่บนระบบไฟล์ นั่นหมายความว่าถ้าคุณลบ / สร้างไฟล์เพราะมันเต็มดิสก์ของคุณดิสก์จะยังคงเต็มอยู่ วิธีหนึ่งในการแก้ไขปัญหาหลังนี้คือการรีสตาร์ทกระบวนการตัวบันทึก แต่คุณอาจไม่ต้องการทำเช่นนั้นสำหรับบริการที่สำคัญและบันทึกตัวกลางจะหายไปอย่างแน่นอน นอกจากนี้ยังมีผลข้างเคียงจากความจริงที่ว่าไฟล์ที่คุณสร้างอาจไม่มีสิทธิ์เจ้าของและกลุ่มเท่ากันกับต้นฉบับ ตัวอย่างนี้สามารถป้องกันตัววิเคราะห์บันทึกการอ่านไฟล์ที่สร้างขึ้นใหม่หรือแย่กว่านั้นป้องกันกระบวนการบันทึกการเขียนบันทึกของตัวเอง
วิธีแรกcat /dev/null > file
ให้บรรลุเป้าหมายอย่างถูกต้องอย่างไรก็ตามแม้จะมีตำนานเมืองที่หวงแหน แต่cat /dev/null
ส่วนหนึ่งก็ไม่มีประโยชน์อะไรเลย มันเปิดไฟล์หลอกซึ่งว่างเปล่าโดยการออกแบบมันล้มเหลวในการอ่านอะไรจากมันและในที่สุดก็ออกจาก การใช้คำสั่งนี้จะเป็นการสูญเสียการกดแป้นพิมพ์, ไบต์, การเรียกของระบบและรอบการทำงานของ CPU และสามารถถูกแทนที่โดยไม่มีการเปลี่ยนแปลงการทำงานใด ๆ โดยคำสั่ง no-op ที่เร็วขึ้นอย่างไม่ต้องสงสัย:
หรือแม้กระทั่ง
ให้ฉันลองอุปมาอุปมัยเพื่ออธิบายว่าไร้ประโยชน์cat /dev/null
อย่างไร สมมติว่าเป้าหมายของคุณคือการล้างแก้ว
คุณลบของเหลวใด ๆ ออกจากมันก่อน นั่นเพียงพอแล้วและเป็นอย่างแม่นยำสิ่งที่ ( > file
) ได้รับจากการเปลี่ยนเส้นทางข้อเท็จจริงจะถูกประมวลผลก่อนเสมอ
จากนั้นคุณเลือกขวดเปล่า ( /dev/null
) แล้วเทลงในแก้วเปล่า ( cat
) นี่คือขั้นตอนที่ไม่มีจุดหมาย ...
หากคุณอ่านเอกสารที่เชื่อมโยงถึงจุดสิ้นสุดคุณอาจสังเกตเห็นความคิดเห็นในบรรทัดนี้จากสคริปต์ที่ปรับปรุงแล้ว:
cat / dev / null> wtmp # ':> wtmp' และ '> wtmp' มีผลเหมือนกัน
พวกเขามีแน่นอน; แย่มากcat /dev/null
ถูกเก็บไว้ในรหัส
นั่นหมายความว่ารหัสต่อไปนี้จะทำงานกับเชลล์ทั่วไปทั้งหมด (ทั้งcsh
และsh
ตระกูล):
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
และสิ่งนี้จะทำงานร่วมกับเปลือกหอยทั้งหมดโดยใช้ไวยากรณ์บอร์นเช่นash
, bash
, ksh
, zsh
และชอบ:
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
อย่างไรก็ตามโปรดทราบว่าด้วยเชลล์ Bourne ก่อนหน้า POSIX คำสั่งใด ๆ เหล่านี้รวมถึงcat /dev/null
จะไม่ตัดไฟล์ถ้ามันถูกเขียนหลังจากนั้นโดยสคริปต์เชลล์ที่กำลังรันอยู่ต่อท้าย แทนที่จะเป็นไฟล์ศูนย์ไบต์นั่นจะเป็นไฟล์กระจัดกระจายที่มีขนาดไม่เปลี่ยนแปลง เช่นเดียวกันจะเกิดขึ้นหากไฟล์ถูกเขียนโดยกระบวนการที่กำลังค้นหาตำแหน่งที่คิดว่าเป็นไฟล์ปัจจุบันก่อนที่จะเขียน
ระวังด้วยว่าโซลูชันทางเลือกบางตัวมักแนะนำให้ตัดทอนไฟล์ที่มีข้อบกพร่อง
ทั้งสองอย่างต่อไปนี้ไม่ทำงาน ไฟล์ผลลัพธ์ไม่ว่างเปล่า แต่มีบรรทัดว่าง นี้จะทำลายไฟล์บันทึกเช่นwtmp
เก็บบันทึกความกว้างคงที่
echo > file
echo "" > file
ตัวถัดไปที่ใช้sh
ตัวเลือกBSD ไม่ใช่แบบพกพา POSIX ไม่ได้ระบุตัวเลือกที่อนุญาตสำหรับเสียงก้องดังนั้นคุณอาจท้ายไฟล์ที่มีบรรทัดที่มี " -n
":
echo -n > file
นั่นไม่ใช่แบบพกพาอย่างใดอย่างหนึ่งโดยใช้sh
ลำดับSystem V escape เชลล์บางตัวจะสร้างไฟล์ที่มีบรรทัดที่มี " \c
":
echo "\c" > file
ใช้คำสั่งที่ออกแบบมาเพื่อทำงาน ปัญหาที่ใช้truncate
ไม่สามารถเคลื่อนย้ายได้เนื่องจากคำสั่งนี้ไม่ได้ถูกระบุโดย POSIX อาจหายไปจากระบบ Unix / Linux
truncate -s 0
ในที่สุดนี่คือทางเลือกสองทางที่พกพาได้และจะทำงานได้อย่างถูกต้อง: