2012-03-23 41 views
70

我知道這不是應該做的事,但是有沒有辦法使用通常在Linux中分隔文件名內的目錄的斜線字符?是否可以在文件名中使用「/」?

+2

什麼文件系統? – Nicolas 2012-03-23 22:29:28

+1

我想你可以修改一個文件的名字,直接訪問你的硬盤分區並在某個地方用'/'字符修補。會發生什麼是一個有趣的問題......很可能不是你想要的。 – hochl 2012-03-23 22:32:33

+1

但簡短的回答應該是:不,這不應該做的事情:-) – 2012-03-23 22:32:38

回答

93

答案你不能,除非你的文件系統有bug。這裏的原因:

有一個系統調用在重命名叫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; 
... 

本準則適用於任何文件系統。這是什麼意思?這意味着如果您嘗試使用傳統方式將具有實際'/'字符的參數作爲文件的名稱傳遞,它將不會執行您想要的操作。沒有辦法逃避角色。如果一個文件系統「支持」這一點,是因爲他們要麼:

  • 使用Unicode字符或東西看起來像斜線,但並非如此。
  • 他們有一個錯誤。

此外,如果你沒有去和編輯添加的斜槓字符到文件名中的字節,不好的事情會發生。這是因爲你永遠不能用名字來引用這個文件:(因爲任何時候你都會這樣做,Linux會認爲你指的是一個不存在的目錄。使用'rm *'技術也無法工作,因爲bash只是把它擴展到文件名。即使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; A =斑點; F =的e2fsck/pass2.c#l455)。所以如果你以某種方式結束了一個文件名,那麼你可以使用'fsck'來解決這個問題。 – ehabkost 2012-09-04 14:58:54

26

假設您的文件系統支持它,您可以使用顯示爲「/」的Unicode字符(例如this seemingly redundant glyph)。

+25

是的,確切地說:只有/,這是U + 002F'SOLIDUS',被禁止。有很多其他合適的候選人:/是U + 2044'FRACTION SLASH'; /是U + 2215'DIVISION SLASH'; ⧸是U + 29F8'BIG SOLIDUS'; /是U + FF0F'FULLWIDTH SOLIDUS',而╱是U + 2571是'BOX LIGHT DIAGONAL UPPER RIGHT LOWER LEFT'。所有這些都會令人讚歎! – tchrist 2012-03-23 22:38:39

+0

但是,如果用戶在他的文件/目錄名稱中使用這些實際字符會怎麼樣? 我們需要一個通用的轉義解決方案。太糟糕的Linux的正常代碼不支持任何,因爲它在ASCII 0x2F字面上匹配。 自從至少20年以來,ASCII是一個不容忽視的問題。 (Unicode 1.0是從1991年開始!) – Evi1M4chine 2016-06-05 09:30:45

0

簡短的回答是:不,你不能。由於如何定義目錄結構,這是一個必要的禁止。

而且,如前所述,您可以顯示一個「看起來像」斜線的unicode字符,但這就是您所能得到的。

4

只限於商定的編碼。例如,您可能會同意將%編碼爲%%,而%2F將表示/。所有訪問此文件的軟件都必須瞭解編碼。

+13

「我們稱之爲任何其他名稱的斜線會聞到臭味」 - 莎士比亞 – 2012-03-23 23:14:30

3

這取決於您正在使用的文件系統。

  • EXT3:No
  • EXT4:No
  • JFS:Yes
  • 的reiserfs:No
  • XFS:一些較受歡迎的No
+1

它不僅僅取決於文件系統,所有* nix系統的系統調用都會解析/作爲目錄樹的一個組件。 – 2012-03-23 22:35:37

+0

正斜槓字符被硬編碼到內核中,與文件系統無關(嘗試在內核源代碼中執行'grep -r「'/'」*') – 2012-03-23 23:17:35

+0

@RobertMartin「Forward」斜槓? – tchrist 2012-03-24 02:07:16

1

通常,嘗試在文件名中使用「壞」字符是一個壞主意;即使你以某種方式管理它,它往往會使以後很難使用該文件。文件系統分隔符完全不起作用,因此您需要選擇另一種方法。

你有沒有考慮URL編碼的URL,然後用它作爲文件名?結果應該是文件名,並且很容易從編碼版本重建名稱。

另一個選擇是創建一個索引 - 使用任何你喜歡的方法創建輸出文件名 - 順序編號的名稱,SHA1哈希,不管 - 然後用生成的文件名/ URL編寫一個文件。你可以將它保存到一個散列中,並用它來做一個URL到文件名的查找,反之亦然,反之亦然,如果需要的話,你可以寫出來並重新加載它。

相關問題