2012-03-23 11 views
70

मुझे पता है कि यह ऐसा कुछ नहीं है जिसे कभी किया जाना चाहिए, लेकिन क्या स्लैश वर्ण का उपयोग करने का कोई तरीका है जो आमतौर पर लिनक्स में फ़ाइल नाम के भीतर निर्देशिका को अलग करता है?क्या फ़ाइल नाम में "/" उपयोग करना संभव है?

+2

क्या फाइल सिस्टम? – Nicolas

+1

मुझे लगता है कि आप अपने हार्डकिस्क विभाजन और पैच को सीधे '/' चरित्र में सीधे पहुंच का उपयोग करके फ़ाइल के नाम को संशोधित कर सकते हैं। क्या होता है एक दिलचस्प सवाल है ... शायद आप जो चाहते हैं उसे नहीं। – hochl

+1

लेकिन संक्षिप्त उत्तर होना चाहिए: नहीं, यह ऐसा कुछ नहीं है जो कभी किया जाना चाहिए :-) –

उत्तर

93

जवाब है कि आप तब तक नहीं कर सकते जब तक कि आपके फाइल सिस्टम में कोई बग न हो।

SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, 
       int, newdfd, const char __user *, newname) 

जब सिस्टम कॉल लागू हो जाता है, यह नाम पर एक पथ देखने (do_path_lookup) करता है:

अपनी फ़ाइल fs/namei.crenameat कहा जाता है में परिभाषित का नाम बदलने के लिए एक प्रणाली कॉल नहीं है: यहाँ क्यों है। इस अनुरेखण रखें, और हम link_path_walk जो इस है करने के लिए मिल:

static int link_path_walk(const char *name, struct nameidata *nd) 
{ 
     struct path next; 
     int err; 
     unsigned int lookup_flags = nd->flags; 

     while (*name=='/') 
       name++; 
     if (!*name) 
       return 0; 
... 

इस कोड को किसी भी फाइल सिस्टम के लिए लागू होता है। इसका मतलब क्या है? इसका अर्थ यह है कि यदि आप परंपरागत माध्यमों का उपयोग कर फ़ाइल के नाम के रूप में वास्तविक '/' वर्ण के साथ पैरामीटर पास करने का प्रयास करते हैं, तो यह वही नहीं करेगा जो आप चाहते हैं। चरित्र से बचने का कोई रास्ता नहीं है।

  • यूनिकोड वर्ण या कुछ है कि एक स्लेश तरह दिखता है, लेकिन नहीं है का उपयोग करें: एक फाइल सिस्टम इस "का समर्थन करता है" तो यह इसलिए क्योंकि वे या तो है।
  • उनके पास एक बग है।

इसके अलावा, अगर आप में जाने के लिए और एक फ़ाइल नाम में एक स्लेश चरित्र जोड़ने के लिए बाइट्स संपादित किया था, बुरी चीजें क्या होगा। इसका कारण यह है कि आप कभी भी इस फ़ाइल को नाम से नहीं देख सकते :(जब भी आपने किया था, लिनक्स मान लेगा कि आप एक गैर-निर्देशिका निर्देशिका का जिक्र कर रहे थे। 'आरएम *' तकनीक का उपयोग करना या तो काम नहीं करेगा, क्योंकि बैश बस फाइलनाम में फैलता है।यहां तक ​​कि rm -rf काम नहीं होता है, के बाद से एक सरल strace कैसे चीजें हुड के नीचे पर जाने का पता चलता है (छोटा):

$ ls testdir 
myfile2 out 
$ strace -vf rm -rf testdir 
... 
unlinkat(3, "myfile2", 0)    = 0 
unlinkat(3, "out", 0)     = 0 
fcntl(3, F_GETFD)      = 0x1 (flags FD_CLOEXEC) 
close(3)        = 0 
unlinkat(AT_FDCWD, "testdir", AT_REMOVEDIR) = 0 
... 

सूचना है कि unlinkat को इन कॉल विफल हो जाएगा क्योंकि वे नाम से फाइलों का उल्लेख करने की जरूरत है।

+4

इसके अलावा, ध्यान दें कि कम से कम 'e2fsck' किसी भी फ़ाइल नाम को एक अवैध फ़ाइल नाम के रूप में मानता है जिसे ['स्रोत देखें] (http://git.kernel.org/?p=fs/ ext2/e2fsprogs.git, एक = ब्लॉब; च = e2fsck/pass2.C# L455)। इसलिए यदि आप किसी फ़ाइल नाम के साथ समाप्त हो जाते हैं जो उसमें स्लेश हो गया है, तो आप समस्या को ठीक करने के लिए 'fsck' का उपयोग कर सकते हैं। – ehabkost

26

आप एक यूनिकोड वर्ण का उपयोग कर सकते हैं जो "/" (उदाहरण के लिए this seemingly redundant glyph) के रूप में प्रदर्शित करता है) मानते हैं कि आपका फाइल सिस्टम इसका समर्थन करता है।

+25

हां, ठीक है: केवल /, जो यू + 002 एफ 'सॉलिडस' है, प्रतिबंधित है। अन्य उपयुक्त उम्मीदवार हैं:/यू +2044 'फ्रक्शन स्लैश' है;/यू +2215 'डिवीजन स्लैश' है; ⧸ यू + 2 9 एफ 8 'बिग सोलिडस' है;/यू + एफएफ 0 एफ 'फुलविड्थ सोलिडस' है, और ╱ यू +2571 है 'बॉक्स ड्रॉइंग लाइट डायगोनल अप्पर राइट लेफ्ट बाएं'। सभी सराहनीय काम करेंगे! – tchrist

+0

लेकिन फिर यदि उपयोगकर्ता उन वास्तविक पात्रों को उनकी फ़ाइल/डीआईआर नामों में उपयोग करता है तो क्या होगा? हमें एक सामान्य बचने के समाधान की आवश्यकता है। बहुत खराब लिनक्स का सामान्य कोड किसी का समर्थन नहीं करता है, क्योंकि यह सचमुच ASCII 0x2F पर मेल खाता है। ASCII कम से कम 20 वर्षों से एक बड़ा नो-नो है। (यूनिकोड 1.0 1 99 1 से है!) – Evi1M4chine

0

संक्षिप्त उत्तर है: नहीं, आप नहीं कर सकते। निर्देशिका संरचना को परिभाषित करने के कारण यह एक आवश्यक निषेध है।

और जैसा कि बताया गया है, आप एक यूनिकोड चरित्र प्रदर्शित कर सकते हैं जो "स्लैश जैसा दिखता है", लेकिन जहां तक ​​आप प्राप्त करते हैं।

4

केवल एक सहमत-पर एन्कोडिंग के साथ। उदाहरण के लिए, आप सहमत हो सकते हैं कि % को %% के रूप में एन्कोड किया जाएगा और %2F का अर्थ / होगा। इस फ़ाइल तक पहुंचने वाले सभी सॉफ़्टवेयर को एन्कोडिंग को समझना होगा।

+13

"जिसे हम किसी भी अन्य नाम से स्लैश कहते हैं, वह गंध के रूप में गंध करेगा" - शेक्सपियर –

3

यह इस बात पर निर्भर करता है कि आप किस फाइल सिस्टम का उपयोग कर रहे हैं।

  • ext3: No
  • ext4: No
  • JFS: Yes
  • ReiserFS: No
  • XFS: अधिक लोकप्रिय वालों में से कुछ की No
+1

यह केवल फाइल सिस्टम पर निर्भर नहीं है, सभी * निक्स सिस्टम में सिस्टम कॉल पार्स करेगा/निर्देशिका पेड़ के एक घटक के रूप में। –

+0

फॉरवर्ड स्लैश कैरेक्टर कर्नेल में हार्ड-कोड किया गया है, फाइल सिस्टम से स्वतंत्र है (अपने कर्नेल स्रोत में 'grep -r' '/' "* * * करने का प्रयास करें) –

+0

@RobertMartin" फॉरवर्ड "स्लैश ??? – tchrist

1

सामान्य रूप से फ़ाइल नाम में "खराब" वर्णों का उपयोग करने का प्रयास करना एक बुरा विचार है; भले ही आप इसे किसी भी तरह प्रबंधित करते हैं, फिर भी यह फ़ाइल को बाद में उपयोग करना मुश्किल बनाता है। फाइल सिस्टम विभाजक फ्लैट-आउट बिल्कुल काम नहीं करेगा, इसलिए आपको वैकल्पिक विधि चुनने की आवश्यकता होगी।

क्या आपने यूआरएल-एन्कोडिंग यूआरएल को तब फ़ाइल नाम के रूप में उपयोग करने पर विचार किया है? परिणाम फ़ाइल नाम के रूप में ठीक होना चाहिए, और एन्कोडेड संस्करण से नाम को पुनर्निर्माण करना आसान है।

एक और विकल्प इंडेक्स बनाना है - आप जिस भी विधि को पसंद करते हैं, आउटपुट फ़ाइल नाम बनाएं - अनुक्रमिक रूप से क्रमांकित नाम, SHA1 हैश, जो कुछ भी - जेनरेट की गई फ़ाइल नाम/यूआरएल जोड़ी के साथ एक फाइल लिखें। आप इसे हैश में सहेज सकते हैं और इसे यूआरएल-टू-फाइलनाम लुकअप करने के लिए या हैश के उलट संस्करण के साथ इसके विपरीत उपयोग कर सकते हैं, और यदि आप आवश्यक हो तो इसे लिख सकते हैं और बाद में इसे फिर से लोड कर सकते हैं।

संबंधित मुद्दे

 संबंधित मुद्दे