Автозаполнение Bash дает другое имя файла, чем ls

Невероятно странная вещь только что произошла. Через серьезную опечатку я вошел

cp filename.xsl .^?~ 

Да, это верно, точка-вопросительный вопрос-тильда! Истина чуждо, чем вымысел.

Это становится более странным. Когда я печатаю

 cat . 

а затем нажмите TAB , я получаю

 ./ ../ .^?~ 

но когда я делаю ls -a , я получаю

 . .. .?~ 

Наконец, когда я

 rm .?~ 

команда remove вызывает меня так:

 rm: remove write-protected regular file `.\177~'? 

прежде чем успешно удалить его. Почему неважно существование каретки?

  • Без учета . и .. из результатов поиска и ls
  • Попросите команду ls вести себя по-разному в зависимости от количества записей
  • Сохранение цветопередачи с разрезом
  • Результат ls *, ls ** и ls ***
  • = sign в конце .sock-файлов в выводе ls
  • 'ls' показывает два идентичных файла в каталоге
  • Есть ли какие-то подводные камни для переопределения ls?
  • Что означает `l` в листинге` ls`?
  • 3 Solutions collect form web for “Автозаполнение Bash дает другое имя файла, чем ls”

    Это связано с тем, что каретка часто используется для обозначения нажатия клавиши ctrl или что в противном случае это управляющий символ.

    Ключевая последовательность, которую вы написали, такова:

    cp filename.xsl . ctrl + V backspace ~ Введите

    Вероятно, вы пытались скопировать файл в свой домашний каталог ( ~ ). Вы можете повторить это, набрав ctrl + V backspace . Вы увидите ^? напечатан на экране.

    Вы можете просматривать файлы с непечатаемыми символами, преобразованными в escapes в стиле C, как это (это флаг -b который важен, но так как ваш файл начинается с точки, в которой вы нуждаетесь -a а также:

     $ ls -ab . .. .\177~ 

    Без -b вы видите только это как .?~ Не потому, что он просто опускает ^ , а потому, что любой непривлекательный символ отображается как ? , Попробуйте touch ctrl + V Введите foo Enter и затем ls . Файл, который вы увидите, будет ?foo . Тогда ls -b покажет \rfoo .

    Итак, когда вы rm .?~ Это соответствует, потому что в этом случае ? вы набрали, интерпретируется оболочкой как подстановочный шаблон, подходящий для любого отдельного символа, а не только фактический вопросительный знак. У вас есть rm aliased to rm -i поэтому он подтверждает ваше действие, и когда он показывает это, появляется код escape-кода в стиле C.

    Странный символ, который у вас есть в этом имени файла (как указано rm ), является символом 0177 ( 0x7F h / 127 d ). Это характер Del .

    Кажется, что автозаполнение Bash не справляется с этим последовательно. ls печатает ? для непечатаемых символов (по умолчанию). Пытаться:

     $ echo a > .$'\x7f'~ $ ls -b .?? .\177~ 

    rm полезен и печатает его восьмеричную ценность.

    Когда вы нажимаете TAB, и оболочка делает какое-то имя файла, угадывая, оно печатает два символа: «^» и «?». для байта, оцененного восьмеричным 177. Вы можете получить имя файла с байтом этого значения, нажав ctrl-V, а затем shift-ctrl-? (три ключа одновременно) для тестирования.

    Имя файла не было dot-caret-questionmark-тильдой, а точками-восьмеричными 177-тильдами. Различные программы выбрали представление восьмидесятизначных байтов различными способами.

    Linux и Unix - лучшая ОС в мире.