Я сделал опечатку:
$ 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) работает как своего рода escape-последовательность для следующего нажатия клавиши, вставляя связанное значение вместо того, чтобы выполнять какие-либо действия, которые обычно были бы связаны.
Воспользовавшись этим, ^V^C
(ctrl+v, ctrl+c) должен работать для ввода вашего сложного имени файла в терминал.
Вы также можете удалить файл по иноду:
$ 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
, порядок аргументов имеет значение!
Другой вариант - использовать rm -ri ./*
; rm
спросит вас перед удалением любого файла и каталога, поэтому вам просто нужно ответить y
в "плохой" файл и n
всем остальным.
На самом деле, в вашем случае вы даже можете сократить количество необходимых ответов, выполнив rm -ri ./?
, так как ваш "плохой" файл состоит всего из одного символа.
Один из вариантов - найти имя файла не по ls
. Если вы знаете, что это было составлено дословно Ctrl+C, вы можете найти символ ASCII, созданный с помощью таблица управляющих символовили с более дружелюбным интерфейсом, например, с Python:
>>> import os
>>> os.listdir('.')
['\x03', ...]
Другой вариант - посмотреть шестнадцатеричный дамп вывода ls
, используя, например, hexdump
.
Затем вы можете удалить файл с помощью (например) этой команды bash:
rmdir "$(printf '\x03')"
(Двойные кавычки нужны только в том случае, если символ, который вы пытаетесь напечатать, находится в вашем IFS
переменная, например \x20
или \x0A
, но хорошая привычка заключать подстановки команд в кавычки, если вы не знаете, что хотите, чтобы оболочка выполняла разделение полей и т. д.)
Часто в таких ситуациях легко придумать шаблон подстановки который соответствует соответствующему файлу.
В вашем случае это было бы просто ?
(соответствие всех имен файлов ровно одним символом).
Просто убедитесь, что он действительно соответствует тому, что вы хотите:
ls -ld ?
А затем удалите каталог:
rmdir ?
Вы также можете комбинировать это с завершение табуляции. Вы можете ввести
rmdir ?
и нажмите вкладку, например в bash он будет заменен на
rmdir ^C/
Затем вы можете нажать Enter, и он сделает то, что вы хотите.
Вы можете использовать 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’
Решение, которое сработало для меня:
rm ./[Tab][Tab][Tab]...
чтобы просмотреть доступные файлы, пока не найду тот, который хочу удалить.
Но вам нужно иметь необходимые настройки в вашей оболочке, чтобы это работало.
Самый простой способ - переместить все во временный каталог, а затем rm -r DIRNAME
.
Если это единственный пустой каталог (или вам не нужно удалять другие пустые каталоги), использовать 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._]/
для сопоставления каталогов, которые начинаются с не буквенно-цифрового имени или символа подчеркивания. Я также включил .
, но выражения glob не совпадают .
в любом случае нормально.
Как указывали другие, вы можете ограничить его односимвольными именами с помощью шара ?
: rmdir ?/
rmdir
не имеет -i
вариант путь rm
делает, предположительно потому, что пустые каталоги обычно не представляют ценности и могут быть просто воссозданы.
Прежде чем делать что-либо рискованное, сначала попробуйте следующее:
rmdir -- ^C
В общем, это разделитель, указывающий, что за командой не последуют никакие -o ptions, но он также позволяет не интерпретировать странные символы как что-то еще.
Другой пример использования: whois -r -- "-r OBJECT-RIPE"
(-r - это сокращение для спелых, но в спелых who также является параметром)
Если с первого раза не сработает, то может попробовать rmdir -- "^C"
Но в моей оболочке csh мне это не нужно, просто rmdir ^C
у меня уже работает.