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

Что-то я чувствую, что должен знать наверняка: если я ls <something>, будет rm <something> удалите точно те же файлы это ls отображенный? Есть ли любые обстоятельства где rm мог удалить файлы это ls не показал? (Это находится в этих 18,04 ударах),

Править: спасибо всем, кто ответил. Я думаю, что полный ответ является комбинацией всех ответов, таким образом, я принял наиболее проголосовавший ответ как "ответ".

Неожиданные вещи я учился по пути:

  • ls не так просто, как Вы могли бы думать в его обработке его аргументов
  • В простой un-fiddled-with установке Ubuntu, .bashrc псевдонимы ls
  • Не называйте свои файлы, начинающиеся с тире, поскольку они могут быть похожими на аргументы команды, и именование одного-r просит его!
33
задан 7 September 2018 в 22:25

10 ответов

Ну, оба ls и rm воздействуйте на аргументы, которые передаются им.

Этими аргументами может быть простой файл, таким образом, ls file.ext и rm file.ext воздействуйте на тот же файл, и результат ясен (перечислите файл / удаляют файл).

Если вместо этого аргументом является каталог, ls directory перечисляет содержание каталога в то время как rm directory не будет работать, как (т.е. rm без флагов не может удалить каталоги, в то время как, если Вы делаете rm -r directory, это рекурсивно удаляет все файлы под directory и сам каталог).

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

Как экстремальный пример думают ls $(rand).txt и rm $(rand).txt, аргументами является "то же", но результаты очень отличаются!

40
ответ дан 23 November 2019 в 00:30

Как насчет:

$ mkdir what
$ cd what
$ mkdir -p huh/uhm ./-r
$ ls *
uhm
$ rm *
$ ls
-r
$ ls -R
.:
-r

./-r:

В основном подстановочные знаки, расширяющиеся до элементов, начинающихся с - (или вводимых вручную элементов, начинающихся с -, но это выглядит как обман), могут интерпретироваться по-разному [ 113] и rm.

4
ответ дан 23 November 2019 в 00:30

Если вы сделаете только ls вместо ls -a, да rm может удалить скрытые файлы, которые вы не видели с ls без -a.

Пример:

Согласно:

dir_test
├── .test
└── test2

ls dir_test: будет отображаться только test2

ls -A dir_test: будет отображаться test2 + .test

rm -r dir_test: удалит все (.test + test2)

Я надеюсь, что это поможет вам.

4
ответ дан 23 November 2019 в 00:30

Если Вы думаете о чем-то как ls foo*.txt по сравнению с. rm foo*.txt, затем да, они покажут и удалят те же файлы. Оболочка разворачивает шарик и передает его рассматриваемой команде, и работа команд над перечисленными файлами. Один список их, одно удаление их.

Заметное отличие - это, если какой-либо из тех файлов, оказалось, был каталогом, то ls перечислил бы его содержание, но rm не удался бы удалить его. Это - обычно не проблема с тех пор rm удалил бы меньше, чем, чем показали ls.

Большая проблема здесь прибывает из выполнения ls * или rm * в каталоге, содержащем имена файлов, запускающиеся с тире. Они расширились бы до командных строк двух программ, как будто Вы записали им сами, и ls взял бы -r означать "обратный порядок сортировки", в то время как rm взял бы -r означать рекурсивное удаление. Различие имеет значение, есть ли у Вас подкаталоги по крайней мере два уровня глубоко. (ls * покажет содержание первых каталогов уровня, но rm -r * будет все мимо первого подуровня, также.)

Чтобы избежать что, запишите разрешающие шарики с продвижением ./ указать на текущий каталог и/или поместить a -- сигнализировать о конце опции, обрабатывающей перед шариком (т.е. rm ./* или rm -- *).

С шариком как *.txt, это - на самом деле не проблема, так как точка является недопустимым символом опции и вызовет ошибку (пока кто-то не разворачивает утилиты для изобретения значения для нее), но еще более безопасно поместить ./ там так или иначе.


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

20
ответ дан 23 November 2019 в 00:30

Если Вы вводите ls * и затем rm *, возможно, что Вы удалите больше файлов, чем ls показал - они, возможно, были созданы в крошечном временном интервале между концом ls и запустите rm.

15
ответ дан 23 November 2019 в 00:30

При не принятии во внимание поведения оболочки давайте сфокусируемся на только что rm и ls может иметь дело с собой. По крайней мере один случай, где ls покажет что rm не может удалить включает полномочия каталога и другой - специальные каталоги . и ...

Полномочия папки

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

Таким образом, Вы, возможно, прочитали и выполняете полномочия на каталоге, который позволит Вам, пересекают каталог и просматривают содержание в очень хорошо, например ls /bin/echo, но Вы не можете rm /bin/echo если Вы не владелец /bin или поднимите свои полномочия с sudo.

И Вы будете видеть случаи как это везде. Вот один такой случай: https://superuser.com/a/331124/418028


Специальные каталоги '.' и '..'

Другой особый случай . и .. каталоги. Если Вы делаете ls . или ls .. , это счастливо покажет Вам содержание, но rm'луг их не позволяется:

$ rm -rf .
rm: refusing to remove '.' or '..' directory: skipping '.'
17
ответ дан 23 November 2019 в 00:30

ls * и rm * не ответственны за расширение шарика - это сделано оболочкой прежде, чем передать его команде.

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

Так лучший способ сделать это (или по крайней мере, иначе) должно пропустить посредника.

echo * покажет Вам точно, что было бы передано Вашему rm команда.

9
ответ дан 23 November 2019 в 00:30

Существуют пограничные случаи где что ls шоу не что rm удаляет. Скорее экстремальное значение, но к счастью мягкое - то, если аргументом, который Вы передаете, является символьная ссылка на каталог: ls покажет Вам все файлы в symlinked каталоге, в то время как rm удалит символьную ссылку, оставляя исходный каталог и его содержание нетронутыми:

% ln -s $HOME some_link
% ls some_link    # Will display directory contents  
bin    lib    Desktop ...
% rm some_link
% ls $HOME
bin    lib    Desktop ...
4
ответ дан 23 November 2019 в 00:30

Уже существует много хороших ответов, но я хочу добавить некоторое более глубокое понимание.

Задайте себе вопрос: Скольким передаются параметры ls, если Вы пишете

ls *

...? Обратите внимание что ls команда не добирается * как параметр, если существуют какие-либо файлы это * может быть расширен до. Вместо этого оболочка сначала выполняет globbing прежде, чем вызвать команду, таким образом, ls команда на самом деле получает столько же параметров, сколько существуют файлы, подобранные globbing. Для подавления globbing заключите параметр в кавычки.

Это верно для любой команды: echo * по сравнению с echo '*'.

Существует сценарий, назовите его countparams.sh протестировать эффект. Это говорит Вам, сколько параметров это было передано и перечисляет их.

#!/bin/bash
echo "This script was given $# parameters."
arr=( "$@" )
for ((i=0;i<$#;i++)); do
        echo "Parameter $((i+1)): ${arr[$i]}"
done

Сделайте это исполняемым файлом и работайте ./countparams.sh *. Извлеките уроки из его вывода!

3
ответ дан 23 November 2019 в 00:30

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


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

Это, как гарантируют, будет безопасно против условий состязания:
        ls *.txt / новый файл создается / rm *.txt
потому что Вам предлагает каждый файл та же программа, это делает удаление.


Это является слишком громоздким для нормальной эксплуатации, и если Вы искажаете rm кому: rm -i, Вы будете использовать \rm или rm -f справедливо часто. Но стоит, по крайней мере, упомянуть, что существует решение состояния состязания. (Это даже портативно к системам не-GNU: POSIX rm(1) указывает -i опция.)

Другая опция была бы массивом удара: to_remove=(*.txt), затем попросите, чтобы пользователь подтвердил (возможно, после выполнения ls -ld -- "${to_remove[@]}"), затем rm -- "${to_remove[@]}". Таким образом, расширение шарика только сделано однажды, и список передается дословно rm.

Другой практически применимой опцией является GNU rm -I (страница справочника), которая запрашивает при удалении больше чем 4 объектов. (Но не показывает Вам список, просто общее количество.) Я использую alias rm='rm -I' на моем рабочем столе.

Это - хорошая гарантия против перебирающего жир возврата с полувведенным шаблоном, который соответствует слишком много. Но использование ls сначала обычно хорошо в каталоге, которым Вы владеете, или в однопользовательской системе, и когда нет фоновых процессов, которые могли асинхронно создать новые файлы там. Для принятия мер против перебирающего жир не вводить rm -rf /foo/bar/baz слева направо. rm -rf / является специальным в корпусе, но rm -rf /usr не!   Не учитывают -rf часть, или запускаются с ls, и только добавьте rm -rf часть после ввода пути.

1
ответ дан 23 November 2019 в 00:30

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

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