Назад | Перейти на главную страницу

FreeBSD: Каталог под названием ^ C (правда!) - как удалить?

Я сделал опечатку:

$ 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 у меня уже работает.