mv ไฟล์ไปยัง / dev / null แบ่ง dev / null


25

ถ้าฉันทำ: touch file; mv file /dev/nullเป็นราก/dev/nullหายไป ls -lad /dev/nullส่งผลให้ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว แบ่งการใช้งานนี้ซึ่งขึ้นอยู่กับ/dev/nullเช่น SSH mknod /dev/null c 1 3; chmod 666 /dev/nullและสามารถแก้ไขได้โดยการทำ ทำไมการย้ายไฟล์ปกติไปยังไฟล์พิเศษนี้ส่งผลให้หายไป/dev/null?

เพื่อชี้แจงนี่คือเพื่อวัตถุประสงค์ในการทดสอบและฉันเข้าใจว่าmvคำสั่งทำงานอย่างไร สิ่งที่ฉันอยากรู้คือทำไมls -la /dev/nullก่อนที่จะแทนที่ด้วยไฟล์ปกติจะแสดงผลลัพธ์ที่คาดหวัง แต่หลังจากนั้นมันก็แสดงว่า/dev/nullไม่มีอยู่แม้ว่าไฟล์นั้นจะถูกสร้างขึ้นผ่านmvคำสั่งดั้งเดิมและคำสั่ง file แสดงข้อความ ASCII ฉันคิดว่านี่ต้องเป็นการรวมกันของlsพฤติกรรมคำสั่งร่วมกับdevfsเมื่อไฟล์ที่ไม่ใช่พิเศษมาแทนที่อักขระ / ไฟล์พิเศษ นี่คือบน Mac OS X พฤติกรรมอาจแตกต่างกันไปตามระบบปฏิบัติการอื่น


44
/dev/nullจะไม่ยุ่งกับ
devnull

7
ดังนั้น @devnull พูด
Braiam

3
วิธีที่เหมาะสมในการลบไฟล์คือrmคำสั่ง
casey

1
ดูเหมือนว่าเป็นต้นเหตุของปัญหาของคุณ OSX devfsเป็นเรื่องตลกเกี่ยวกับไฟล์ปกติ แปลกที่คุณไม่ได้รับข้อผิดพลาดจากmvแม้ว่า วิธีการเกี่ยวกับวิธีนี้touch testfile; mv testfile /dev?
แกรม

3
@Gregg mvสามารถปรมาณูได้ในระบบไฟล์เดียวกันเท่านั้น
แกรม

คำตอบ:


16

ดูที่ซอร์สโค้ดสำหรับ mv http://www.opensource.apple.com/source/file_cmds/file_cmds-220.7/mv/mv.c :

/*
 * If rename fails because we're trying to cross devices, and
 * it's a regular file, do the copy internally; otherwise, use
 * cp and rm.
 */
if (lstat(from, &sb)) {
    warn("%s", from);
    return (1);
}
return (S_ISREG(sb.st_mode) ?
    fastcopy(from, to, &sb) : copy(from, to));

...

int
fastcopy(char *from, char *to, struct stat *sbp)
{
...
while ((to_fd =
    open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)) < 0) {
        if (errno == EEXIST && unlink(to) == 0)
            continue;
        warn("%s", to);
        (void)close(from_fd);
        return (1);
}

ในครั้งแรกที่ผ่านไปในขณะที่วงopen(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)จะล้มเหลวด้วย EEXIST จากนั้น/dev/nullจะถูกยกเลิกการเชื่อมโยงและวนซ้ำ แต่ในขณะที่คุณชี้ให้เห็นในความคิดเห็นของคุณไฟล์ปกติไม่สามารถสร้างขึ้นได้/devดังนั้นในรอบต่อไปที่ผ่านลูปopen(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)จะยังคงล้มเหลว

ฉันต้องการรายงานข้อผิดพลาดกับ Apple mvรหัสที่มาเป็นส่วนใหญ่ไม่เปลี่ยนแปลงจาก FreeBSD รุ่น แต่เนื่องจาก devfs OSX มีพฤติกรรมที่ไม่ใช่ POSIX mvกับไฟล์ปกติแอปเปิ้ลของพวกเขาควรจะแก้ไข


1
ฉันกำลังให้คำตอบที่ดีที่สุดในขณะนี้สำหรับการให้ซอร์สโค้ดและยอมรับว่านี่เป็นข้อผิดพลาดซึ่งเป็นสิ่งที่ฉันกำลังขับรถ
Gregg Leventhal

12

การย้ายไฟล์ไปยังตำแหน่งของไฟล์ที่มีอยู่แล้วจะแทนที่ไฟล์ที่มีอยู่ ในกรณีนี้/dev/nullไฟล์อุปกรณ์จะถูกแทนที่เช่นเดียวกับไฟล์ปกติใด ๆ หลีกเลี่ยงการใช้นี้-i(interactive เตือนก่อนที่จะเขียนทับ) หรือ-n(ไม่ clober) mvทางเลือกสำหรับ

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


ดูความคิดเห็นของฉันที่จะ terdon
Gregg Leventhal

เข้าใจดีว่า -d นั้นไม่จำเป็นซึ่งเป็นนิสัยที่ไม่ดีอย่างไรก็ตามไฟล์ควรยังคงปรากฏในเอาต์พุต ls ไม่ควรแสดงว่าไม่มีอยู่
Gregg Leventhal

@ Graeme - ยินดีต้อนรับสู่ 3K เป็นงานที่ดี!
slm

10

อืมเพราะคุณเขียนทับไฟล์พิเศษด้วยไฟล์ธรรมดา? คุณคาดหวังว่าจะเกิดอะไรขึ้น dev/nullไม่ใช่ไดเรกทอรี แต่เป็นไฟล์ที่ชี้ไปยังnullอุปกรณ์ เมื่อคุณทำmvบางสิ่งกับมันคุณจะลบต้นฉบับและแทนที่ด้วยสิ่งที่คุณย้าย:

$ file /dev/null 
/dev/null: character special 
$ sudo mv file /dev/null 
$ file /dev/null 
/dev/null: ASCII text

2
แต่ฉันกำลังบอกว่า / dev / null แสดงว่าหายไปเมื่อใช้ ls -lad / dev / null นี่เป็นสิ่งที่เฉพาะเจาะจงสำหรับผู้ที่ชื่นชอบมันเป็นสิ่งที่ฉันอยากรู้
Gregg Leventhal

หากฉัน mv ไฟล์ / dev / null ดังนั้น / dev / null ควรมีไฟล์ที่มีอยู่ แต่ยังคงมีอยู่ ฉันต้องการทราบว่าทำไมสิ่งนี้ทำให้ / dev / null ไม่พบใน ls
Gregg Leventhal

ได้รับฉันกำลังทำสิ่งนี้บน Mac ดังนั้นมันอาจแตกต่างกันเล็กน้อย แต่ฉันไม่ได้คาดหวังว่าไฟล์จะแสดงว่าหายไปฉันแค่คาดหวังว่ามันจะแสดงเมื่อเปลี่ยนเป็นไฟล์ต้นฉบับ
Gregg Leventhal

@GreggLeventhal ใช่มันจะต้องเป็น OSX หรือ BSD (โปรดแก้ไข Q ของคุณและระบุ OS ของคุณ) บน Linux ของฉันฉันยังคงเห็น/dev/nullว่ามันเป็นเพียงไฟล์ที่ฉันย้าย
terdon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.