mv / null के लिए एक फ़ाइल mv / null तोड़ता है


25

अगर मैं करता हूं: touch file; mv file /dev/nullजड़ के रूप में, /dev/nullगायब हो जाता है। ls -lad /dev/nullऐसी किसी फ़ाइल या निर्देशिका के परिणाम नहीं। यह उन अनुप्रयोगों को तोड़ता है जो /dev/nullSSH की तरह निर्भर करते हैं और जिन्हें करके हल किया जा सकता है mknod /dev/null c 1 3; chmod 666 /dev/null। नियमित फ़ाइल को इस विशेष फ़ाइल में स्थानांतरित करने के परिणामस्वरूप गायब /dev/nullक्यों हो जाता है ?

स्पष्ट करने के लिए, यह परीक्षण उद्देश्यों के लिए था, और मैं समझता हूं कि mvकमांड कैसे काम करता है। मैं इस बारे में उत्सुक हूं कि ls -la /dev/nullनियमित फ़ाइल के साथ इसे बदलने से पहले अपेक्षित आउटपुट क्यों दिखाया जाता है, लेकिन बाद में यह पता चलता है कि /dev/nullमूल mvकमांड के माध्यम से एक फ़ाइल कथित रूप से बनाई गई थी, भले ही मौजूद नहीं है और फ़ाइल कमांड ASCII टेक्स्ट को दिखाता है। मुझे लगता है कि यह lsकमांड व्यवहार का संयोजन होना चाहिए devfsजब एक गैर विशेष फ़ाइल एक चरित्र / विशेष फ़ाइल की जगह लेती है। यह मैक ओएस एक्स पर है, अन्य ओएस पर व्यवहार भिन्न हो सकते हैं।


44
गड़बड़ मत करो /dev/null
देवनुल

7
इसलिए @devnull कहते हैं
Braiam

3
फ़ाइलों को हटाने का उचित तरीका rmकमांड है।
केसी

1
ऐसा लगता है कि आपकी समस्या का मूल है, OSX devfsसामान्य फ़ाइलों के बारे में मज़ेदार है। अजीब बात है कि आपको mvहालांकि कोई त्रुटि नहीं मिली । इस तरह से कैसे touch testfile; mv testfile /dev:?
ग्रीम

3
@ ग्रेग, 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 संस्करण से अपरिवर्तित है, लेकिन क्योंकि OSX के devfs नियमित फाइलों के साथ कि गैर POSIX व्यवहार है, एप्पल उनके ठीक करना चाहिए mv


1
मैं स्रोत कोड प्रदान करने और इसे बग के रूप में स्वीकार करने के लिए अभी सबसे अच्छा जवाब दे रहा हूं, जो कि मैं चला रहा था।
ग्रेग लेवेंथल

12

किसी फ़ाइल को पहले से मौजूद फ़ाइल के स्थान पर ले जाने से मौजूदा फ़ाइल बदल जाती है। इस स्थिति में /dev/nullडिवाइस फ़ाइल को बदल दिया जाता है, जैसे कि कोई सामान्य फ़ाइल होगी। इसके उपयोग से बचने के लिए -i(संवादात्मक, अधिलेखित होने से पहले चेतावनी) या -n(कोई क्लोब नहीं) विकल्प mv

/dev/nullकेवल अपने विशेष कार्य को एक बिट-बकेट के रूप में करता है तब डिवाइस को इस प्रकार खोला जाता है। उदाहरण के लिए, जब >शेल ऑपरेटर का उपयोग किया जाता है, तो फ़ाइल खोली जाती है, फिर छोटा किया जाता है (एक प्रतिस्थापित नहीं हटाया जाता है, जो आपसे अपेक्षित हो सकता है)। जैसा कि केसी ने उल्लेख किया है, फ़ाइल को हटाने का सही तरीका है rmया उसके साथ भी unlink


टेरडोन के लिए मेरी टिप्पणियाँ देखें।
ग्रीग लेवेंटल

समझ में आया, -d अनावश्यक था, यह सिर्फ एक बुरी आदत है, लेकिन फ़ाइल अभी भी ls आउटपुट में दिखाई देनी चाहिए, यह किसी भी रूप में नहीं दिखाना चाहिए।
ग्रीग लेवेंटल

@ ग्रेमी - 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
लेकिन मैं कह रहा हूं कि ls -lad / dev / null चलाते समय / dev / null गायब दिख रहा था। यह devfs के लिए कुछ विशिष्ट होना चाहिए, कि यह वही है जिसके बारे में मैं जानना चाहता था।
ग्रीग लेवेंटल

अगर मैं फ़ाइल / देव / अशक्त करता हूँ तो / देव / अशक्त होना चाहिए कि क्या फ़ाइल समाहित है लेकिन अभी भी मौजूद है। मैं जानना चाहता हूं कि इस कारण / dev / null को ls में नहीं मिला।
ग्रीग लेवेंटल

दी, मैं यह एक मैक पर कर रहा हूं, इसलिए यह थोड़ा अलग हो सकता है, लेकिन मुझे उम्मीद नहीं थी कि फाइल गुम होने के रूप में दिखाई देगी, मैंने केवल इसे स्रोत फ़ाइल में बदलने की अपेक्षा की थी।
ग्रीग लेवेंटल

@GreggLeventhal हाँ, यह एक OSX या BSD चीज़ होनी चाहिए (कृपया अपना Q संपादित करें और अपना OS निर्दिष्ट करें)। मेरे लिनक्स पर मैं अभी भी देख सकता हूं /dev/null, यह सिर्फ वह फाइल बन गई है जिसे मैंने स्थानांतरित किया था।
terdon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.