Есть ли какие-либо недостатки использования $ комнаты (ls) для удаления файлов?

Я задавался вопросом при использовании rm $(ls) удалить файлы (или rm -r $(ls) удалить каталоги также), было безопасно? Поскольку во всех веб-сайтах, люди дают другие способы сделать это даже при том, что эта команда кажется намного легче, чем другие команды.

13
задан 2 September 2016 в 19:01

2 ответа

Что это предназначается, чтобы сделать?

  • ls файлы списков в текущем каталоге
  • $(ls) вывод замен ls места, что как аргумент в пользу rm
  • По существу rm $(ls) предназначается для удаления всех файлов в текущем каталоге

Что случилось с этим изображением?

ls не может правильно обработать специальные символы в имени файла. Пользователи UNIX, обычно рекомендуемые использовать разные подходы. Я имею, также показал это в связанном вопросе о подсчете имен файлов. Например:

$ touch file$'\n'name                                                                                                    
$ ls                                                                                                                     
file?name
$ rm $(ls)
rm: cannot remove 'file': No such file or directory
rm: cannot remove 'name': No such file or directory
$ 

Кроме того, как правильно упомянуто в ответе Denis, имени файла с продвижением тире, мог быть интерпретирован как аргумент rm после замены, которая побеждает цель удалить имя файла.

Какие работы

Вы хотите удалить файлы в текущем каталоге. Так используют шарик rm *:

$ ls                                                                                                                     
file?name
$ rm $(ls)
rm: cannot remove 'file': No such file or directory
rm: cannot remove 'name': No such file or directory
$ rm *
$ ls
$ 

Можно использовать find команда. Этот инструмент часто рекомендуется для больше, чем просто текущего каталога - он может рекурсивно пересечь все дерево каталогов и воздействовать на файлы через -exec . . .{} \;

$ touch "file name"                                
$ find . -maxdepth 1 -mindepth 1                                                                                         
./file name
$ find . -maxdepth 1 -mindepth 1 -exec rm {} \;                                                                          
$ ls
$ 

Python не имеет проблемы со специальными символами в именах файлов, таким образом, мы могли использовать это также (обратите внимание, что этот для файлов только, необходимо будет использовать os.rmdir() и os.path.isdir() если Вы хотите воздействовать на каталоги):

python -c 'import os; [ os.remove(i) for i in os.listdir(".") if os.path.isfile(i) ]'

На самом деле команда выше могла быть превращена в функцию или псевдоним в ~/.bashrc для краткости. Например,

rm_stuff()
{
    # Clears all files in the current working directory
    python -c 'import os; [ os.remove(i) for i in os.listdir(".") if os.path.isfile(i) ]'

}

Версия Perl этого была бы

perl -e 'use Cwd;my $d=cwd();opendir(DIR,$d); while ( my $f = readdir(DIR)){ unlink $f;}; closedir(DIR)'
7
ответ дан 23 November 2019 в 03:12

Нет, это не безопасно, и наиболее часто используемая альтернатива rm * не намного более безопасно.

Существует много проблем с rm $(ls). Поскольку другие уже покрыли в их ответах, выводе ls будет разделен в символах, существующих во внутреннем разделителе полей.

Лучший вариант развития событий, это просто не работает. Худший вариант развития событий, Вы намеревались удалить только файлы (но не каталоги) – или выборочно удалить некоторые файлы с -i – но существует файл с именем c -rf в текущем каталоге. Давайте посмотрим то, что происходит.

$ mkdir a
$ touch b
$ touch 'c -rf'
$ rm -i $(ls)
$ ls
c -rf

Команда rm -i $(ls) как предполагалось, удалил только файлы и спросил прежде, чем удалить каждого, но команда, которая в конечном счете выполнялась чтение

rm -i a b c -rf

таким образом, это сделало что-то еще полностью.

Отметьте это rm * только незначительно лучше. Со структурой каталогов как прежде, это будет вести себя, как предназначено здесь, но если Вам назвали файл -rf, Вам все еще не повезло.

$ mkdir a
$ touch b
$ touch ./-rf
$ rm -i *
$ ls
-rf

Существует несколько лучших альтернатив. Самые легкие включают только комнату и globbing.

  • Команда

    rm -- *
    

    будет работать точно, как предназначено, где -- сигналы, что все после того, как это не должно быть интерпретировано как опция.

    Это было частью инструкций по синтаксису утилиты POSIX больше двух десятилетий теперь. Это широко распространено, но Вы не должны ожидать, что это будет присутствовать везде.

  • Команда

    rm ./*
    

    заставляет шарик расшириться по-другому и таким образом не требует никакой поддержки со стороны названной утилиты.

    Для моего примера сверху, Вы видите команду, которая будет в конечном счете выполняться путем предварительного ожидания эха.

    $ echo rm ./*
    rm ./a ./b ./-rf
    

    Продвижение ./ предотвращает комнату от случайной обработки любых из имен файлов как опции.

26
ответ дан 23 November 2019 в 03:12

Другие вопросы по тегам:

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