जवाब है कि आप नहीं कर सकते, जब तक कि आपके फाइल सिस्टम में बग न हो। यहाँ पर क्यों:
आपकी फ़ाइल में परिभाषित का नाम बदलने के लिए एक प्रणाली कॉल है 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
विफल हो जाएँगी क्योंकि उन्हें फ़ाइलों को नाम से संदर्भित करना होगा।