我對我的系統 Fedora 12 中的單一純文字文件的問題感到完全困惑。
Clon1918K_PCC1.gff
特別是,當我使用 ... 命令時,會列出我的文件,ls, ls -a, ls -li
但是當我嘗試透過cat, vim, cp, ls
etc 存取它時,它總是出現相同的錯誤Clon1918K_PCC1.gff: No such file or directory
。
但是,當我複製所有文件cp *.gff
或cp *
該文件時,它也會被複製。
我還嘗試用 nautilus 打開它,沒有出現問題,在兩種情況之一中,當我將內容複製到另一個同名檔案時,問題消失了。有趣的是,在這種情況下,奇怪的文件沒有被重寫,並且出現了 2 個具有完全相同名稱的文件,其中一個可訪問,另一個不可訪問。我尋找隱藏的角色,但一切似乎都很好。
有人對這個奇怪的案件有任何想法嗎?謝謝!
答案1
同一目錄中不能有兩個同名的檔案。根據定義,檔案名稱是唯一的鍵。
你所擁有的幾乎肯定是一個特殊的角色。我知道你檢查過它們,但具體是怎麼檢查的呢?你可以說類似ls *gff | hexdump -C
找特殊字元在哪裡。任何具有高位元設定的位元組(即80
和之間的十六進位值FF
)都將指示出現問題。以下任何內容20
(十進制 32)也是特殊字元。另一個提示是.
的右側文字列中存在點hexdump -C
。
有許多字元在 UTF-8 中看起來像 US ASCII 字元。即使在 US ASCII 中,1 和 l 通常看起來很相似。然後,你有西里爾字母的 C (U+0421)、希臘月牙西格瑪 (U+03F9,也完全像 C)、西里爾字母/希臘小寫“o”等。那裡可能有很多不可見的 Unicode 字元。
解釋:為什麼高位表示出了問題?檔案名稱「Clon1918K_PCC1.gff」似乎是 100% 7 位元 US ASCII。把它通過hexdump -C
會產生這樣的結果:
00000000 43 6c 6f 6e 31 39 31 38 4b 5f 50 43 43 31 2e 67 |Clon1918K_PCC1.g|
00000010 66 66 |ff|
所有這些位元組值都低於0x80
(第 8 位元清除),因為它們都是 7 位元 US ASCII 代碼點。 Unicode 代碼點 U+0000 到 U+007F 表示傳統的 7 位元 US ASCII 字元。代碼點 U+0080 及以上代表其他字符,並以 UTF-8 編碼為 2 到 6 個位元組(在 Linux 上,請嘗試man utf8
獲取有關如何完成此操作的大量資訊)。根據定義,UTF-8 將 US-ASCII 代碼點編碼為自身(即十六進位 ASCII 字符41
,Unicode U+0041,被編碼為單字節41
)。代碼點 ≥ 128 被編碼為 2 到 6 個位元組,每個都設定了第八位。透過此可以輕鬆檢測到非 ASCII 字元的存在無需解碼串流。例如,假設我將檔案名稱中的第三個字元“o”(ASCII 6f
、U+006F)替換為 Unicode 字元“U+03FB GREEK SMALL LETTER OMICRON”,如下所示:“ο”。hexdump -C
然後產生這個:
00000000 43 6c ce bf 6e 31 39 31 38 4b 5f 50 43 43 31 2e |Cl..n1918K_PCC1.|
00000010 67 66 66 |gff|
第三個字元現在被編碼為 UTF-8 序列ce bf
,每個位元組都有其第 8 位元設定。在這種情況下,這是你遇到麻煩的跡象。另外,請注意hexdump
僅解碼 7 位元 ASCII 的 ,無法解碼單一 UTF-8 字元並顯示兩個不可列印字元 ( ..
)。
答案2
嘗試使用 nautilus 重新命名該文件,但鍵入所需的名稱(不要複製貼上)。這肯定會刪除任何特殊字元。它甚至可能是檔案名稱前後的空格,您不可見,但作業系統和程式可見。我通常使用 mc 來處理真正奇怪的檔案名稱。
答案3
您是否考慮過 Rootkit 的存在?曾幾何時,我可以存取一台安裝了 rootkit 的 Solaris 電腦。名為「*01」的檔案在使用ls *01
或 時不可見ls -altr
,但在使用echo *01
. rootkit 的安裝ls
(以及許多其他可執行檔)已更改,因此某些檔案和進程在通常情況下不會出現。你的描述聽起來很像我遇到的rootkit。
答案4
萬一有人偶然發現這個並閱讀其他答案......你可以跳過很多圈子或像一些答案所說的那樣用通配符賭博,或者只是使用ls -b
- 我記得它是“二進制”。
shell 中的製表符補全應自動引用該字符,但您可以使用非 shell 的內容(例如 Nautilus),也可以使用 shell 轉義引用樣式為ls
其他命令產生方便的預引用字串。我在其他地方的另一個較長答案中使用了這個奇怪的文件示例,但它在這裡也相關:
sauer@lightning:/tmp/test> ls
a??file
sauer@lightning:/tmp/test> ls --quoting-style=shell-escape
'a'$'\t\033''file'
sauer@lightning:/tmp/test> mv -v 'a'$'\t\033''file' regular_filename
renamed 'a'$'\t\033''file' -> 'regular_filename'