क्या फ़ाइल नाम में "/" का उपयोग करना संभव है?


111

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


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

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

क्या एफएस गिनती में निर्देशिका प्रविष्टि में फ़ाइल नाम में एक स्लैश हैक करना है? यह अनुशंसित नहीं किया जाएगा; आप कभी भी फ़ाइल तक नहीं पहुँच पाएंगे।
जोनाथन लेफ़लर

35
यह मुझे उस समय की याद दिलाता है, जब मेरे दोस्त ने एक फाइल बनाई थी *और फिर पूछा, "मैं एक फाइल कैसे निकालूं?" मैंने जवाब दिया, rmउसके बाद फ़ाइल नाम दिया। खैर, आप बाकी जानते हैं।
डेविड हेफरनान

1
नए लिनक्स उपयोगकर्ताओं के लिए, जब आप एक अभिव्यक्ति या फ़ाइल नाम के बारे में आश्वस्त नहीं होते हैं, तो मुझे लगता है कि lsउन फ़ाइलों को सूचीबद्ध करने के लिए उपयोग करना अच्छा है , जिन्हें आप हटाना चाहते हैं और फिर बाद में lsकमांड को बदलना चाहते हैं rm
डेव एफ

जवाबों:


129

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

आपकी फ़ाइल में परिभाषित का नाम बदलने के लिए एक प्रणाली कॉल है fs/namei.cकहा जाता है renameat:

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

जब सिस्टम कॉल मंगाया जाता है, तो यह do_path_lookupनाम पर पथ लुकअप ( ) करता है। इसे ट्रेस करते रहें, और हमें यह मिल जाता 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 *' तकनीक का उपयोग करने से या तो काम नहीं होगा, क्योंकि बैश बस फ़ाइल नाम के लिए फैलता है। यहां तक rm -rfकि काम नहीं करेगा, क्योंकि एक साधारण स्ट्रेस से पता चलता है कि कैसे हुड के नीचे चीजें चलती हैं (छोटा):

$ 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विफल हो जाएँगी क्योंकि उन्हें फ़ाइलों को नाम से संदर्भित करना होगा।


8
इसके अलावा, ध्यान दें कि कम से कम e2fsckकिसी भी फ़ाइलनाम को एक अवैध फ़ाइल नाम के रूप में माना जाता है जिसे ठीक करना है- स्रोत देखें । इसलिए यदि आप किसी तरह से एक फ़ाइल नाम के साथ समाप्त हो जाते हैं, जिसमें स्लैश है, तो आप fsckसमस्या को ठीक करने के लिए उपयोग कर सकते हैं ।
एहबाक

4
@ehabkost कोई फ़ाइल नाम? एक बग की तरह लगता है e2fsck: पी
flarn2006

36

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


43
हां, ठीक है: केवल /, जो कि U + 002F है SOLIDUS, निषिद्ध है। अन्य उपयुक्त उम्मीदवारों के बहुत सारे हैं: suitable यू + 2044 है FRACTION SLASH; 22 यू + 2215 है DIVISION SLASH; 29 यू + 29 एफ 8 है BIG SOLIDUS; / U + FF0F है FULLWIDTH SOLIDUS, और + U + 2571 है BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT। सभी admirably काम करेगा!
tchrist

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

@ टीचर मैं यूनिकोड पर निर्भर नहीं रहना पसंद करता हूं। तो मैं शायद एक बहु चरित्र परिसीमा पसंद करेंगे ---। आपकी डेलीमीटर पसंद एक अलग चरित्र का उपयोग कर सकती है और पुनरावृत्ति की संख्या को भिन्न कर सकती है।
ट्रेवर बॉयड स्मिथ

कई वर्णों पर संभावित प्रतिस्थापनों की सूची के लिए, जिन्हें अलग-अलग फाइल सिस्टम के तहत निषिद्ध किया गया है, मेरे जवाब पर एक नज़र डालें: stackoverflow.com/a/61448658/4575793
Cadoiz

9

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


1
यह केवल फाइल सिस्टम पर निर्भर नहीं करता है, सभी * nix सिस्टम में सिस्टम कॉल निर्देशिका ट्री के घटक के रूप में / पार्स करेगा।
ब्लैकले मोरी

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

20
@ टिश्री एक्सक्यूज़ मी। "फ़ॉरवर्ड स्लैश" स्लैश कैरेक्टर को संदर्भित करने का एक पूरी तरह से स्वीकार्य तरीका है जो पूरी तरह से स्पष्ट करता है जो स्लैश को संदर्भित करता है। कभी-कभी लोग भ्रमित हो जाते हैं: P
रॉबर्ट मार्टिन

2
हाह, लेकिन @tchrist में भी एक बिंदु है, मुझे लगता है। फॉरवर्ड 'imply' / 'और' back 'imply' \ 'क्यों करता है? मेरे द्वारा अब तक की सबसे अच्छी व्याख्या यह है कि यदि किसी पंक्ति पर शुरू होने वाली कलम के साथ नीचे से ऊपर की ओर लिखा जाता है, तो पढ़ने / लिखने के दौरान '' आगे बढ़ता है 'या' आगे 'और' पीछे 'चलता है। बाएं से दाएं। मैं वास्तव में उस स्पष्टीकरण को पसंद नहीं करता, हालांकि, भाग में, क्योंकि मैं हमेशा नीचे से अपने पात्रों को नहीं लिखता और आगे बढ़ता हूं। मुझे लगता है कि ऊपर से शुरू करना और चरित्र लिखते समय आगे बढ़ना अक्सर बेहतर होता है।
जेसी डब्ल्यू कॉलिन्स

4
@jwso यह पूरी तरह से एक साइड पॉइंट है, लेकिन यह मानक, विहित भाषा है। स्लैश वह नहीं है जो यूनिकोड ऐसे प्रतीकों को बुलाता है जो इस तरह दिखता है, यह उन्हें सॉलिडस कहता है, लेकिन "\" एक रिवर्स सॉलिडस है, जो पीछे की तरफ का पर्याय है, इसलिए बैकस्लैश। लेकिन अगर किसी को एक औचित्य की आवश्यकता है, तो आगे और पीछे की दिशा है लाइन राइट या गिरना चाहिए, दिशा के आधार पर लेखन की दिशा (बाएं से दाएं)। यदि यह "\" जैसा दिखता है, तो यह नीचे झुकना चाहिए या <== या पीछे की तरफ गिरना चाहिए।
स्टुअर्ट आर। जेफरीज़

4

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


19
"जिसे हम किसी अन्य नाम से एक स्लैश कहते हैं वह दुर्गंध के रूप में सूंघेगा" - शेक्सपियर
रॉबर्ट मार्टिन

1

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

और, जैसा कि उल्लेख किया गया है, आप एक यूनिकोड वर्ण प्रदर्शित कर सकते हैं जो "एक स्लैश जैसा दिखता है", लेकिन यह उतना ही है जितना आपको मिलता है।


1

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

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.