Странный случай: Текстовый файл, который существует и не существует

Странный случай: Текстовый файл, который существует и не существует

Я полностью озадачен проблемой с одним простым текстовым файлом в моей системе Fedora 12. Я использовал известное программное обеспечение в биоинформатике, Maker, для создания множества простых текстовых файлов, и один из них, похоже, «недоступен».

В частности, мой файл с именем Clon1918K_PCC1.gffотображается в списке, когда я использую ls, ls -a, ls -liкоманды ..., но когда я пытаюсь получить к нему доступ с помощью cat, vim, cp, lsи т. д., всегда появляется одна и та же ошибка Clon1918K_PCC1.gff: No such file or directory.

Однако когда я копирую все файлы вместе с cp *.gffэтим cp *файлом, он также копируется.

Также я пытался открыть его с помощью nautilus без проблем, и в одном из двух случаев, когда я копировал содержимое в другой файл с тем же именем, проблема исчезала. Интересно, что в этом случае странный файл не перезаписывается, а появляются 2 файла с точно таким же именем, один из них доступен, а другой нет. Я искал скрытые символы, но все, кажется, в порядке.

У кого-нибудь есть идеи по этому странному делу?? Спасибо!

решение1

Не может быть двух файлов с одинаковым именем в одном каталоге. Имена файлов по определению являются уникальными ключами.

То, что у вас есть, почти наверняка является специальным символом. Я знаю, что вы проверяли их, но как именно? Вы могли бы сказать что-то вроде ls *gff | hexdump -Cfind, где находятся специальные символы. Любой байт с установленным старшим битом (то есть шестнадцатеричные значения между 80и FF) будет признаком того, что что-то пошло не так. Все, что ниже 20(десятичное 32), также является специальным символом. Еще одна подсказка — наличие точек .в правом текстовом столбце hexdump -C.

Существует множество символов, которые выглядят как символы US ASCII в UTF-8. Даже в 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 (в Linux попробуйте man utf8найти много информации о том, как это делается). По определению, UTF-8 кодирует кодовые точки US-ASCII как они сами (т. е. шестнадцатеричный символ ASCII 41, Unicode U+0041, кодируется как один байт 41). Кодовые точки ≥ 128 кодируются как два-шесть байтов,каждый из которых имеет установленный восьмой бит. Наличие не-ASCII символа можно легко обнаружить с помощью этогобез необходимости декодировать поток. Например, предположим, что я заменяю третий символ в имени файла, «o» (ASCII 6f, U+006F), на символ Unicode «U+03FB ГРЕЧЕСКАЯ СТРОЧНАЯ БУКВА ОМИКРОН», который выглядит так: «ο». 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

Вы рассматривали наличие руткита? Когда-то давно у меня был доступ к машине Solaris, на которой был установлен руткит. Файлы с именем '*01' не были видны с ls *01или ls -altr, но отображались с echo *01. Установка руткита изменилась ls(и ряд других исполняемых файлов), так что некоторые файлы и процессы не появлялись при обычных обстоятельствах. Ваше описание очень похоже на руткит, с которым я столкнулся.

решение4

На случай, если кто-то наткнется на это и прочтет другие ответы... Вымогпрыгать через множество обручей или играть с подстановочными знаками, как говорится в некоторых ответах, или просто использовать ls -b— я помню это как «двоичный».

Автодополнение Tab в оболочке должно автоматически заключать символ в кавычки, но вы можете использовать что-то, что не является оболочкой (например, Nautilus), или использовать стиль кавычек shell-escape с 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'

Связанный контент