Вопрос: 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/

Очевидно, я не могу набрать a ^ C: - / Как удалить этот файл?


127
2018-01-21 15:55


Источник


Слишком плохо, что слово состояния устройства не попал в POSIX. - Mark Plotnick
@MarkPlotnick: слишком плохо оригинал  dsw не попал в POSIX. - Matteo Italia
Я не думаю, что вы назвали его ctrl + C, вы назвали его после символа ascii, который сопоставляется с этим ярлыком на клавиатуре, то есть ETX (ascii 3). У вашего шрифта консоли нет глифа для этого символа, поэтому он использует общий подстановочный глиф «?». - jiggunjer
emacs -nw -f dired дает навигатор каталогов. <kbd> D </ kbd> удаляет файл под курсором после подтверждения. - Thorbjørn Ravn Andersen
@MatteoItalia Слишком плохое управление персонажами в именах файлов и других идиотский  идеи превратили его в POSIX ... - pipe


Ответы:


^V (Ctrl+v) работает как своего рода escape-последовательность для следующего нажатия клавиши, вставляя связанное значение вместо того, чтобы выполнять любые действия, которые обычно связываются.

Используя это, ^V^C (Ctrl+v, Ctrl+с) должны работать для ввода вашего сложного имени файла в терминале.


188
2018-01-21 16:23



Вероятно, это было именно то, как OP сделала свою опечатку в первую очередь. V и C находятся рядом друг с другом на клавиатуре. - Stig Hemmer
Или они пытались использовать буфер обмена Windows на терминале bsd. - Joel Coel
@JoelCoel привычки никогда не умирают! - Mafii
Интересно, ^V^C делает не работа в редакторе Zsh; кавычко вставка виджета (найдите страницу для ^V) явно не вставляет символы прерывания. Ответ Якоба (с использованием printf) может быть более переносимым способом подачи управляющего символа в аргумент оболочки. - Miles
@StigHemmer: Что может случиться, вы нажимаете Ctrl-C в середине команды, затем забудьте об этом и скопируйте-вставьте команду позже. - Mehrdad


Вы также можете удалить файл с помощью 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, аргумент!


89
2018-01-22 03:42



Почему бы не поставить -delete до -inum? Это просто предосторожность в случае, если вы нажимаете кнопку ввода преждевременно или порядок аргументов влияет на результат? - detuur
@detuur: порядок влияет на результат. См. Править. - bishop
Не клади -delete в команду, период, пока вы не запустите команду без -delete чтобы проверить, что он находит то, что вы хотите. - Kaz
@Kaz не поможет с добавлением -delete в центр команды - RiaD
Использование @Kaz -print вместо -delete делает очень хороший тест. - Mark Ransom


Другим вариантом является использование rm -ri ./*; rm попросит вас перед удалением любого файла и каталога, так что вам просто нужно ответить y к «плохим» файлам и n всем остальным.

Фактически, в вашем случае вы можете даже сократить количество ответов, необходимых для выполнения rm -ri ./?, так как ваш «плохой» файл имеет длину всего один символ.


31
2018-01-21 20:13



select f in ?; do rm -i "$f"; break; done имеет все преимущества -i, без агонии, чтобы ответить no к нежелательным или ошибочно отвечая «да» тому, который вы хотите сохранить. - bishop
В случае OP это каталог, а не файл. rmdir ?/ удалит все пустые односимвольные каталоги и пожалуется, что остальные непустые. - Peter Cordes
@bishop: whoa, я даже не знал, что select существует, довольно аккуратно! - Matteo Italia
@PeterCordes: wops, я не заметил, что мы говорили о каталогах; я добавил -r (а также ./ - это всегда легко забыть) к моим примерам, поскольку, к сожалению, rmdir не поддерживает -i флаг. Тем не менее, я полагаю, что в этом случае лучшим способом было бы сочетание епископа и вашего комментария. - Matteo Italia
@MatteoItalia select существует только в некоторых оболочках, поэтому, вероятно, вы не столкнулись с этим - скрипты и решения, предназначенные для переноски, избегают этого, поэтому мы с меньшей вероятностью увидим это «в дикой природе». - mtraceur


Один из вариантов - найти имя файла с чем-то другим, кроме ls, Если вы знаете, что он был составлен дословно Ctrl+С, вы можете найти символ ASCII, созданный с помощью таблица управляющих символов, или с более дружественным интерфейсом, подобным тому, который предоставляется Python:

>>> import os
>>> os.listdir('.')
['\x03', ...]

Другой вариант - посмотреть на шестнадцатеричный дамп вывода ls, используя, например, hexdump,

Затем вы можете удалить файл с помощью (например) этой команды bash:

rmdir "$(printf '\x03')"

(Двойные кавычки нужны только в том случае, если символ, который вы пытаетесь распечатать, находится в вашем IFS переменная, такая как \x20 или \x0A, но это хорошая привычка указывать замены команд, если вы не знаете, что вы хотите, чтобы оболочка выполняла разделение поля и т. д.),


23
2018-01-21 18:51



Также cat -v (плюс man ascii) может помочь для первой части. - Matteo Italia
... или вы используете os.rmdir('\x03') непосредственно из оболочки Python. - moooeeeep


Часто в таких ситуациях легко придумать шаблон подстановки который соответствует соответствующему файлу.

В вашем случае это будет просто ? (сопоставление всех имен файлов с одним символом).

Просто убедитесь, что он действительно соответствует тому, что вы хотите:

ls -ld ?

Затем удалите каталог:

rmdir ?

Вы также можете комбинировать это с завершение вкладки, Вы можете ввести

rmdir ?

и нажмите вкладку, и, например, в bash он будет заменен на

rmdir ^C/

и вы можете нажать кнопку ввода, и он делает то, что вы хотите.


15
2018-01-21 21:02





Вы можете использовать Midnight Commander (mc) для удаления файла - просто выберите с помощью кнопок вверх / вниз и нажмите F8.

Иногда я делал это, когда имена файлов имели странные символы из-за кодирования.


11
2018-01-21 20:29



Или просто о любом другом файловом менеджере. - Stig Hemmer
@StigHemmer, конечно, некоторые делают лучше, чем другие, для отображения определенных имен файлов. Вероятно, ответ мог бы объяснить, почему MC является оптимальным выбором по сравнению с несколькими другими. Я бы не знал, поскольку я никогда не использовал его. - can-ned_food


Еще один способ: использовать stat для получения экранированного представления имени каталога:

$ stat *|grep File:
  File: ‘\003’

Теперь вы знаете представление имени файла, поэтому вы можете удалить файл по имени, используя printf:

$ rmdir -v "$(printf '\003')"
rmdir: removing directory, ‘\003’

Или, если вы используете bash, вы можете избежать printf:

$ rmdir -v $'\003'
rmdir: removing directory, ‘\003’

7
2018-01-22 10:25



BTW, если оболочка bash, $'\x03' проще, чем вызов printf. То же самое для FreeBSD sh, которое распространяется поверх оболочки POSIX с некоторыми вкусными функциями. - Netch
@Netch хорошая точка зрения о bash's $'...', но я бы избежал бесполезного преобразования от восьмеричного к шестнадцатеричному в целом. Например. что, если файл был назван '\111' (в stat вывод)? Вы все равно удалите его, используя $'\x49'? Лучше использовать ту же последовательность, что и stat дал вам: в случае OP, rmdir $'\003', - Ruslan


Решение, которое сработало для меня, это:

rm ./[Tab][Tab][Tab]...

чтобы просмотреть доступные файлы, пока не найду тот, который я хочу удалить.

Но вам нужно иметь необходимые настройки в вашей оболочке для этого.


6
2018-01-22 08:31



^ C действительно рано в последовательности табуляции, так что +1 для вас. - joshudson