Я полностью озадачен проблемой с одним простым текстовым файлом в моей системе 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 -C
find, где находятся специальные символы. Любой байт с установленным старшим битом (то есть шестнадцатеричные значения между 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'