Я допустил опечатку:
$ history
169 9:34 la /usr/local/etc/
170 9:35 sudo mkdir ^C
171 9:36 sudo mkdir /usr/local/etc/dnsmasq.d
Теперь у меня есть файл с именем ^ C (ctrl + C) !!
Когда я использую ls
, я просто вижу вопросительный знак (вероятно, из-за языкового стандарта?)
% ls -al
total 60
drwxr-xr-x 2 root wheel 512 Jan 21 09:35 ? <- this one
drwxr-xr-x 5 admin wheel 512 Jan 21 16:24 .
drwxr-xr-x 3 root wheel 512 Jan 20 14:29 ..
-rw-r--r-- 1 admin nobody 1114 Jan 20 19:10 .cshrc
-rw------- 1 admin wheel 6002 Jan 21 15:27 .history
-rw-r--r-- 1 admin nobody 182 Jan 20 14:29 .login
-rw-r--r-- 1 admin nobody 91 Jan 20 14:29 .login_conf
-rw------- 1 admin nobody 301 Jan 20 14:29 .mail_aliases
-rw-r--r-- 1 admin nobody 271 Jan 20 19:04 .mailrc
-rw-r--r-- 1 admin nobody 726 Jan 20 19:05 .profile
-rw------- 1 admin nobody 212 Jan 20 14:29 .rhosts
-rw-r--r-- 1 admin nobody 911 Jan 20 19:06 .shrc
drwx------ 2 admin nobody 512 Jan 20 15:05 .ssh
drwxr-xr-x 2 admin wheel 512 Jan 20 19:08 bin
и
% ls -i
3611537 ? 3611534 bin
Я хочу удалить этот файл. Я пробую mv
, и при использовании табуляции он показывает мне:
% mv
^C/ bin/
Очевидно, я не могу ввести ^ C: - / Как удалить этот файл?
^V
(ctrl+v) работает как своего рода экранирующая последовательность для следующего нажатия клавиши, вставляя ассоциированное значение вместо того, чтобы совершать действия, которые обычно ассоциируются. Используя это, ^V^C
(ctrl+v, ctrl+c) должно работать для ввода вашего сложного имени файла в терминал.
Вы также можете удалить файл по inode:
$ ls -i1
290742 foo
293246 ^C
$ find . -inum 293246 -delete
Что бы вы ни делали, ради Бога, не ставьте -delete
до -inum
:
$ touch foo bar baz quux
$ find . -name '*u*' -delete
$ ls
bar baz foo
$ find . -delete -name 'b*'
find: `./baz': No such file or directory
find: `./bar': No such file or directory
$ ls
$
Поздравляю, вы только что стерли все свои файлы. С помощью find
, argument order matters!
Один из вариантов - искать имя файла с помощью чего-то кроме ls
. Если вы знаете, что оно было произведено дословно Ctrl+C, вы можете найти ASCII символ, произведенный с использованием таблицы управляющих символов, или с более дружественным интерфейсом, как тот, что предоставлен компанией Python:
>>> import os
>>> os.listdir('.')
['\x03', ...]
Другой вариант - это просмотреть шестнадцатеричный дамп вывода ls
, используя, например, hexdump
.
Тогда вы можете удалить файл с помощью (например) этой команды bash:
rmdir "$(printf '\x03')"
(Двойные кавычки нужны только в том случае, если символ, который вы пытаетесь напечатать, находится в переменной IFS
, такой как \x20
или \x0A
, но это хорошая привычка - заключать в кавычки замены команд, если вы не знаете, что хотите, чтобы оболочка выполняла разбиение полей и т.д.)
Часто в таких ситуациях легко придумать шаблон подстановки , который совпадает с соответствующим файлом.
В вашем случае это было бы просто ?
(совпадение всех имён файлов ровно с одним символом).
Просто убедитесь, что он действительно совпадает с тем, что вы хотите:
ls -ld ?
А затем удалите каталог:
rmdir ?
Вы также можете комбинировать это с заполнением вкладки . Вы можете набрать
rmdir ?
и нажать tab, и, например, в bash он будет заменён на
rmdir ^C/
и вы можете нажать enter и он сделает то, что вы хотите.
. Другой вариант - использовать rm -ri ./*
; rm
будет запрашивать вас перед удалением любого файла и каталога, поэтому вам нужно просто ответить y
на "плохой" файл, а n
- всем остальным.
На самом деле, в вашем случае вы даже можете сократить количество необходимых ответов, сделав rm -ri ./?/
, так как ваш "плохой" файл состоит всего из одного символа.
Вы можете использовать Midnight Commander (mc) для удаления файла - просто выберите с помощью кнопок вверх/вниз и нажмите F8.
Я делал это иногда, когда имена файлов имели странные символы из-за кодировки.
. Еще один способ: используйте stat
для получения экранированного представления имени каталога:
$ stat *|grep File:
File: ‘\003’
Теперь вы знаете представление имени файла, так что вы можете удалить файл по имени, используя printf
:
$ rmdir -v "$(printf '\003')"
rmdir: removing directory, ‘\003’
Или, если вы используете bash, вы можете избежать printf
:
$ rmdir -v $'\003'
rmdir: removing directory, ‘\003’
Если это единственная пустая директория (или вас не волнует удаление других пустых директорий), используйте rmdir */
. Вы получите сообщения об ошибке от rmdir
о невозможности удаления непустых каталогов, но это нормально. GNU rmdir
поддерживает --ignore-fail-on-non-empty
, или вы можете 2>/dev/null
.
Трейлинг /
делает глобус только совпадающими с именами каталогов.
Вы можете проверить заранее, какие пустые каталоги существуют под текущим, используя
find -maxdepth 1 -type d -empty -ls
. (И вы можете изменить -ls
на -delete
, если хотите).
Вы можете использовать более специфическое выражение глобуса типа rmdir [^A-Za-z0-9._]/
для сравнения каталогов, которые начинаются с неалфавитно-цифрового имени файла или имени файла подчеркивания. Я также включил .
, но глобусные выражения все равно не совпадают с .
обычно так или иначе.
Как отмечали другие, вы можете ограничиться односимвольными именами с глобусом ?
: rmdir ?/
rmdir
не имеет опции -i
, как это делает rm
, предположительно потому, что пустые каталоги обычно не ценны и могут быть просто воссозданы.
Решение, которое мне помогло:
rm ./[Tab][Tab][Tab]...
перебирать доступные файлы до тех пор, пока я не найду тот, который хочу удалить.
Но для этого вам нужно иметь в оболочке необходимые настройки .
.Прежде, чем делать что-либо рискованное, попробуйте сначала:
rmdir -- ^C
В общем -- это разделитель, говорящий команде no -o ptions, но он также позволит не интерпретировать странные символы как что-то другое.
Другим примером использования является whois -r -- "-r OBJECT-RIPE"
(-r - это ярлык для спелого, но в спелом whois тоже параметр)
Если он не работает при первой попытке, то может быть попробуйте rmdir -- "^C"
Но на моей оболочке csh мне ничего из этого не нужно, просто rmdir ^C
уже работает на меня.