Как я могу удалить файл, какое имя файла имеет непечатаемые символы

Как насчет/etc/rc.local?

Это будет выполняться в последний раз в последовательности запуска.

48
03.10.2018, 05:09
15 ответов

Файл имеет имя, но это сделано из непечатаемых символов. При использовании ksh93, удара, zsh, mksh или FreeBSD sh, можно попытаться удалить его путем определения его непечатаемого имени. Сначала удостоверьтесь, что имя является правильным с: ls -ld $'\177' Если это показывает правильный файл, то используйте комнату: rm $'\177'

Другой (немного более опасный) подход должен использовать rm -i -- * . С-i опцией комната требует подтверждения прежде, чем удалить файл, таким образом, можно пропустить все файлы, Вы хотите сохранить только тот.

Удачи!

47
27.01.2020, 19:34
  • 1
    я подозреваю это rm -i * не работал бы в этом случае; из-за новых строк расширилась бы оболочка * к чему-то это rm не распознал бы как имя файла. –  Keith Thompson 13.01.2012, 07:32
  • 2
    @KeithThompson: расширение Шарика в оболочке не подвергается дальнейшей интерпретации. Не было бы новой строки на расширенное имя, если это не содержало тот. –  Christoffer Hammarström 13.01.2012, 13:25
  • 3
    @ChristofferHammarström: Хм. Я сделаю некоторые эксперименты и прокомментирую далее. –  Keith Thompson 13.01.2012, 21:05
  • 4
    @ChristofferHammarström: существует новая строка на расширенное имя, потому что имя файла содержит символы новой строки. Но кажется, что я недооценил bash и GNU rm. В моей системе, rm *, rm -i *, и rm Ctrl-V DEL TAB ENTER вся работа правильно, даже если имя файла содержит символ новой строки (я использовал "\177foo\nbar\n"). Некоторые команды не обрабатывают такие имена файлов хорошо, но инструменты GNU кажутся устойчивыми; версии не-GNU тех же инструментов не могли бы вести себя также. В любом случае различные приемы в этих ответах полезны для знания. –  Keith Thompson 13.01.2012, 22:29
  • 5
    @KeithThompson, любая оболочка обработает файл globbing правильно, не только Bash, и rm никогда не делает формы разделения слова, является ли это GNU rm или нет. Оболочка разворачивает шарики и, когда она выполняет требовавшуюся команду, она передает в получающихся именах файлов, поскольку пустой указатель разделил аргументы (в коде C). То, что опасно, должно передать список по каналу файлов к чему-то, что использует новые строки в качестве разделителей; посмотрите, Почему является цикличное выполнение по выводу находки плохой практикой? –  Wildcard 15.11.2016, 08:19

Для тех, кто использует vim выполните его в текущем рабочем каталоге:

$ vim ./ 

и перейдите в файл с клавишами со стрелками или j/k. Затем хит Shift+D и подтвердите удаление с y.

24
27.01.2020, 19:34

Существует, вероятно, способ передать имя файла rm, но если Вы волнуетесь по поводу питания чего-нибудь, что можно использовать файловый менеджер GUI. Emacs идет с режимом редактирования каталога, который можно использовать, если Вам установили его:

  1. Откройте папку в emacs. Можно работать emacs /path/to/folder, или откройте emacs, поразите Esc+x и работайте dired, который запросит путь

    http://so.mrozekma.com/unix-dired-delete1.png

  2. Переместитесь в строку с файлом, Вы хотите удалить и нажать d. Необходимо видеть a D в левом поле рядом с файлом:

    http://so.mrozekma.com/unix-dired-delete2.png

  3. Нажмите x для сохранения изменений. Это запросит, чтобы удостовериться, что Вы хотите удалить файл; нажмите y:

    http://so.mrozekma.com/unix-dired-delete3.png

9
27.01.2020, 19:34
  • 1
    Похож на прекрасную идею, но я, может казаться, не нахожу emacs на этой машине. Рискуя тем, чтобы запустить священную войну... это может быть сделано в энергии? –  Mr Moose 13.01.2012, 03:57
  • 2
    Для тех, кто использует vim выполните его в текущем рабочем каталоге: vim ./ и перейдите в файл с клавишами со стрелками. Затем хит Shift+D и подтвердите удаление с y. –   13.01.2012, 04:01
  • 3
    @hesse, Ничего себе. Не что-то я ожидал бы vim поддерживать –  Michael Mrozek♦ 13.01.2012, 04:02
  • 4
    @MichaelMrozek согласился, он имеет все эти функции, которые я occationally склонен обнаруживать. –   13.01.2012, 04:11
  • 5

Вы уже продемонстрировали с file * то, что шарик оболочки (*) может взять этот файл, поэтому теперь просто сделайте rm на том шарике.

  • Изменитесь на каталог, в котором находится файл.
  • Выполненный rm -i *
  • Войти n для всех файлов за исключением того с на вид невидимым именем файла
8
27.01.2020, 19:34

Файл на самом деле имеет имя, но это сделано из непечатаемых символов.

Легкий метод должен полагаться на завершение оболочки: нажимайте Tab неоднократно, пока “странное” имя файла не будет вставлено. Необходимо было настроить оболочку для циклического повторения между возможными завершениями:

  • В ударе необходимо вызвать menu-complete, который не связывается по умолчанию, а не complete, который связывается с Вкладкой по умолчанию. С другой стороны, используйте Esc * для вставки завершений для всех файлов, и удалить тех Вы не хотите удалять из командной строки.
  • В zsh настройки по умолчанию прекрасны; Вы должны иметь setopt auto_menu или setopt menu_complete набор.

Если завершение не полезно в Вашей оболочке, можно звонить rm -i -- * и ответьте "нет" за исключением этого конкретного файла. Если имя файла не начинается с печатаемого символа, можно ограничить соответствия файлами, первый символ которых не находится в ряде печатаемых символов:

rm -i [!!-~]*
rm -i [![:print:]]*
rm -i -- [!a-z]

(Остерегайтесь, если Ваш шаблон может соответствовать названному файлу -f, который rm рассматривал бы как опция.)

Другой метод должен звонить ls -i найти inode файла (inode однозначно определяет файл в данной файловой системе), затем find -inum воздействовать на тот конкретный файл. Этот метод главным образом полезен, когда каталог содержит много файлов.

ls -i
# note the inode number 12345
find . -xdev -inum 12345 -delete

Если Ваш find не имеет a -delete опция, звонить rm:

find . -xdev -inum 12345 -exec rm -- {} \;

(Да, я знаю, что большая часть из этого была уже отправлена. Но ответы с релевантной информацией делают это более сложным, чем это должно быть.)

8
27.01.2020, 19:34

Попытайтесь использовать echo -e получить символ \177, затем xargs передать его rm. echo не берет десятичные Escape, поэтому преобразовывает в шестнадцатеричное число: Складывается 177 является восьмеричным; echo требует a \0 (литерал, не пустой байт) прежде:

echo -ne '\0177\0' | xargs -0 rm
4
27.01.2020, 19:34
  • 1
    Вы говорите, что \xb1\0 является шестнадцатеричным представлением \177? –  Mr Moose 13.01.2012, 03:57
  • 2
    @MrMoose \xb1 является десятичным 177, \0 пустой указатель - завершает его, и -0 говорит xargs взять завершенное пустым указателем имя вместо завершенного новой строкой. –  Kevin 13.01.2012, 04:02
  • 3
    я использую удар на SunOS и когда я попробовал Вашу команду, я получил xargs: недопустимая опция - 0. Я посмотрел на страницу справочника и не мог видеть опцию для пустого завершения. Мне удалось получить фиксацию для проблемы теперь все же. Посмотрите ответ, отмеченный как ответ. –  Mr Moose 13.01.2012, 05:18
  • 4
    Ваш echo, как есть, отправляет 2 имен файлов в xargs, и затем в на rm... второе имя файла \n.. Это приводит или к ошибке или к удалению файла того имени ('\n') –  Peter.O 13.01.2012, 05:29
  • 5
    @perer Да, я просто заметил это. Я добавил -n избавиться от новой строки. –  Kevin 13.01.2012, 05:34

Я могу примерно гарантировать Вам, что файл действительно имеет имя. Это просто, оказывается, имя, которое содержит непечатаемые символы.

Если rm не работал, затем с помощью вывода find с -inum опция как аргумент rm вероятно, не поможет; это просто собирается передать тот же аргумент rm, с той же проблемой.

Файл является единственным в том каталоге, правильно?

Первая вещь, которую я попробовал бы, к cd в каталог затем введите rm ./, затем поразите клавишу Tab. Это должно развернуть аргумент подлинному имени файла и предыдущее ./ должен предотвратить rm от интерпретации аргумента как что-то другое, чем имя файла.

Другое решение к cd к родительскому каталогу затем используйте rm -r (или, при необходимости, rm -rf) на каталоге. Это должно удалить каталог и все его содержание, независимо от имени. Можно затем использовать mkdir воссоздать каталог (и возможно chmod восстановить его полномочия).

РЕДАКТИРОВАНИЕ:

Взгляд на Ваш ls -lb вывод снова, я думаю, что имя файла запускается с ASCII DEL символ (который плох не не фатальный) и содержит один или несколько символов новой строки (который действительно плох). Насколько я могу сказать, rm команда не может интерпретировать новую строку как часть имени файла.

Но unlink() системный вызов может. Вот сценарий Perl, который я бросил вместе, который выполнит итерации через файлы в текущем каталоге и попросит у Вас каждого, хотите ли Вы удалить его. Это не использует внешнюю команду как rm удалить файлы, таким образом, это должно смочь обработать любые забавные символы что поддержка файловой системы (что-либо кроме ASCII NUL и /).

Выполнение rm -r или rm -rf на содержании каталога должен все еще работать, но если Вы просто хотите удалить единственный файл, можно попробовать это.

#!/usr/bin/perl

use strict;
use warnings;

opendir my $DIR, '.' or die ".: $!\n";
my @files = sort grep { -f } readdir $DIR;
closedir $DIR;

foreach my $file (@files) {
    my $pfile = printable($file);
    print "Remove $pfile? ";
    my $answer = scalar <STDIN>;
    if ($answer =~ /^[Yy]/) {
        print "Removing $pfile\n";
        unlink $file or warn "Unable to remove $pfile: $!\n";
    }
}

sub printable {
    my($s) = @_;
    $s =~ s/[^ -~]/?/g;
    return $s;
}

(Другое решение, если существуют другие файлы в каталоге, который Вы хотите сохранить, состоит в том, чтобы переместить все другие файлы во временный каталог, затем уничтожить и воссоздать каталог и положить обратно другие файлы.)

(О, и независимо от того, что Вы сделали для создания того файла, попытайтесь не сделать это снова!)

3
27.01.2020, 19:34

Если можно найти точно то использование файла find команда, затем можно использовать -delete предикат. Просто будьте осторожны, и сделайте -delete последний параметр команды находки или это причинит боль много...

1
27.01.2020, 19:34

Другие ответы являются большими и будут работать почти во всех средах.

Но, если Вы, оказывается, имеете выполнение gui, просто открываете каталог в наутилусе, дельфине, завоевателе или Вашем любимом файловом менеджере, и необходимо смочь легко видеть и удалить любой файл, который имеет несовместное имя несколькими щелчками мышью.

Если Вы не регулярный emacs или пользователь энергии (как показано в нескольких других ответах), это могло бы быть самым легким способом пойти.

0
27.01.2020, 19:34

имел аналогичную проблему с файлом, названным «\ 033» (фактический «побег» символ).

for x in $( ls | awk '!/^[A-Z]/ && !/^[a-z]/ && !/^[0-9]/');do rm -i -- $x ; done

Вышеуказанное пригласило вас удалить файлы в текущем каталоге, который не начинается с буквы или номера.

0
27.01.2020, 19:34

Вместо этого можно переименовать текущий каталог в DirX_OLD, создать новый каталог с именем DirX и переместить все необходимые файлы из DirX_OLD в DirX. После копирования файлов можно удалить DirX_OLD

0
27.01.2020, 19:34

Вы близки. Пошагово, вот как удалить файл по номеру кода.

Сначала найдите номер нужного вам файла, используя ls -li. Номер входа будет находиться в первой колонке вывода.

Например:

$ls -li
311010 -rw-rw-r-- 1 me me 3995 Apr  6 16:27 -???\# ;-)

В этом случае, номер входа 311010

Используйте find для поиска файла по номеру входа.

find . -inum 311010 

Убедитесь, что find возвращает только имя файла, который вы хотите удалить. Например:

$find . -inum 311010
./-???\# ;-)

Убедившись, что find найдет нужный файл, передайте параметр -delete на find. Файл будет удален за Вас.

find . -inum 311010 -delete
1
27.01.2020, 19:34

Вы видите границы, которые составляли предыдущие PV. Выполните команду pvs --segments , чтобы lvm соответствовали system-config-lvm . Для получения дополнительной информации см. http://www.redhat.com/magazine/009jul05/features/lvm2/ .

-121--133150-

Я уверен, что это должно быть возможно. Я могу предложить только взлом, где Вы используете дополнительные ssh-соединения для каждого переноса другой пары файловых дескрипторов. Например, следующий сценарий подтверждения концепции выполняет первый ssh для выполнения фиктивной команды (sleep) для подключения до локальных fds 5 и 6 до удаленных stdin и stdout, предполагая, что эти fds те, которые вы хотите добавить к обычным 0,1,2.

Затем выполняется реальный ssh, и на удаленном сервере он подключается к удаленным fds 5 и 6 к stdin и stdout другого ssh.

В качестве примера этот сценарий передает страницу gzipped man через на пульт, который распускает и прогоняет его через человека. Stdin и stdout реального ssh все еще доступны для другие вещи.

#!/bin/bash
exec 5</usr/share/man/man1/ssh.1.gz 6>/tmp/out6 # pretend need 5 and 6

ssh remote 'echo $$ >/tmp/pid; exec sleep 99999' <&5 >&6 &
sleep 1 # hack. need /tmp/pid to be set

ssh remote '
  pid=$(</tmp/pid) 
  exec 5</proc/$pid/fd/0 6>/proc/$pid/fd/1
  echo start
  gzip -d <&5 | man /dev/stdin >&6
  echo stop
  kill -hup $pid
'
wait
less /tmp/out6
-121--35715-
rm -dfvr /"(null)" 

работал на меня.

-4
27.01.2020, 19:34

У каждого файла есть имя, вам просто нужно найти, какое именно.

Я буду использовать эти файлы в качестве примера:

$ touch $'\177' $'\001\002' $'\033\027' a b abc $'a\177b'

Эти файлы будут отображаться как ?в обычном режиме ls:

.
$ ls
??  ?  ?002  a  abc  b

Но если ваш lsразрешает опцию -Q, должно быть ясно, какое настоящее имя файла:

$ ls -1iQ *
26739122 "\001\002"
26739117 "\033\027"
26739115 "\177"
26739118 "a"
26739121 "a\177b"
26739120 "abc"
26739119 "b"

это номера инодов и имена в кавычках в столбце 1файлов в pwd.

Это использование возможностей оболочки (POSIX )для использования расширений (подстановок):

Иметь имена с любым непечатаемым символом -:

$ ls -1iQ *[![:print:]]*
26739122 "\001\002"
26739117 "\033\027"
26739115 "\177"
26739121 "a\177b"

И список файлов, которые могут иметь только непечатаемые -символы:

$ ls -1iQ [![:print:]]*
26739122 "\001\002"
26739117 "\033\027"
26739115 "\177"

Затем, чтобы выборочно (удалить-i(интерактивную )опцию )их, используйте:

$ rm -i [![:print:]]*
rm: remove regular file ''$'\001\002'? n
rm: remove regular file ''$'\033\027'? n
rm: remove regular file ''$'\177'? n

Вам просто нужно выбрать, какие из них стереть, ответив yна вопрос выше.

0
27.01.2020, 19:34

Если у вас есть bash с автодополнением, это может вам помочь. Я набрал символ, который был показан в списке каталогов. Затем я активировал автозаполнение и переименовал это во что-то, что можно распечатать.

Вот что у меня сработало:

$ ll
-rw-r--r--.  1 xxxxxxxx  xxxxx 25608 Oct 11 11:11 ?
$ mv ?  
(hit the [tab] and it gets extended to...)
$ mv ^[
(now complete the command and rename to something printable)
$ mv ^[ weirdchar
$ ll
-rw-r--r--.  1 xxxxxxxx  xxxxx 25608 Oct 11 11:11 weirdchar
(now delete)
$ rm weirdchar
0
27.01.2020, 19:34

Теги

Похожие вопросы