[*nix] как принято удалять всё из папки?

Dasar

как под *nix-ами принято удалять(копировать и т.д.) всё из папки?
Сейчас использую

rm -rf * .*

но это царапает мою тягу к прекрасному

vall

find -delete

bestpilot8

Копировать можно, вбивая название каталога.
cp -R sourcefolder destinationfolder
cp -R sourcefolder/ destinationfolder

bash в макоси по первой команде копирует каталог с содержимым, а по второй — именно содержимое.

Dasar

спасибо
другие операции (копирование, изменение прав и т.д.) с использованием квантора "все" (скопировать всё, поменять права у всех и т.д.) тоже делается через комбинацию с find?

tokuchu

rm -rf * .*
А это ".." не зацепляет?

Dasar

> bash в макоси по первой команде копирует каталог с содержимым, а по второй — именно содержимое.
полезный нюанс, спасибо
ps
я такое поведение у rsync-а заметил, а у cp пропустил.

vall

можно с find, но другие рекурсивные операции можно применять на .
а если хочется потрогать только файлы или только директории то без find не обойтись: find -type d -exec chmod 755 '{}' ';'

Dasar

А это ".." не зацепляет?
оно цепляет и .., и . , но rm ругается, что их удалить не может. В итоге, делает то, что хочется, но сильно коряво конечно.

Dasar

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

margadon

А это ".." не зацепляет?
склероз мне подсказывает, что вот ровно так я однажды сколько-то лет назад снёс довольно полезную папочку с незакоммиченным кодом
хотя может то что другое было опасное - уже не помню

apl13

склероз мне подсказывает, что вот ровно так я однажды сколько-то лет назад снёс довольно полезную папочку с незакоммиченным кодом
Склероз подсказывает, что в эпоху мифов и первобытнообщинного строя так и / рекурсивно сносили. Пока в командных процессорах не стали защиту от дурака делать.

Serab

оно цепляет и .., и . , но rm ругается, что их удалить не может. В итоге, делает то, что хочется, но сильно коряво конечно.
это он просто добрый, команда не обязана не работать с "." и "..", потому что, в конце концов, это легальные относительные пути. Это просто rm таким чувствительным стал, потому что случайно можно много чего запороть. В скриптах на это полагаться нежелательно, да и нелогично, почему rm надо пользовать так, а другую команду — по-другому :confused:

tokuchu

но другие рекурсивные операции можно применять на .
минус: относительные пути получаются с точкой, что не всегда удобно
Чего?
А вообще зачем ты хочешь удалить всё из каталога, но каталог не трогать? Может тогда проще и каталог удалить и создать заново?

tokuchu

bash в макоси по первой команде копирует каталог с содержимым, а по второй — именно содержимое.
Прекрасные грабли! :grin:

Dasar

А вообще зачем ты хочешь удалить всё из каталога, но каталог не трогать? Может тогда проще и каталог удалить и создать заново?
если удалять каталог, то отваливаются открытые handle-ы, которые на этот каталог ссылались. Это проявляется, например, в use case-е когда скрипт запускается из диры, которую надо почистить.

Phoenix

Хотел написать, что не зацепляет, потом понял, что у меня шел другой. (zsh)
зависит от шела. sh зацепит

$2:45 garry ~(0/1)$ mkdir wow
$2:45 garry ~(0/1)$ cd wow
$2:45 garry ~/wow(0/1)$ ls -la
total 8K
drwxr-xr-x 2 igor 4096 Dec 29 02:45 .
drwxr-xr-x 87 igor 4096 Dec 29 02:45 ..
$2:45 garry ~/wow(0/1)$ touch aaa
$2:45 garry ~/wow(0/1)$ touch .aaa
$2:45 garry ~/wow(0/1)$ ls -la
total 8K
drwxr-xr-x 2 igor 4096 Dec 29 02:45 .
drwxr-xr-x 87 igor 4096 Dec 29 02:45 ..
-rw-r--r-- 1 igor 0 Dec 29 02:45 .aaa
-rw-r--r-- 1 igor 0 Dec 29 02:45 aaa
$2:45 garry ~/wow(0/1)$ echo *
aaa
$2:45 garry ~/wow(0/1)$ echo .*
.aaa
$2:45 garry ~/wow(0/1)$ rm .
rm: cannot remove `.': Is a directory
$2:46 garry ~/wow(0/1)$ rm -Rf .
rm: cannot remove directory: `.'
$2:46 garry ~/wow(0/1)$ sh
%{%}%(!.#.$)%E%{%}%T%{%} %(!.%{%}.%{%})%U%%m%u%{%} %{%}%3(.!...!)%2.(%j/%L)%{%}%(!.#.$) echo *
aaa
%{%}%(!.#.$)%E%{%}%T%{%} %(!.%{%}.%{%})%U%%m%u%{%} %{%}%3(.!...!)%2.(%j/%L)%{%}%(!.#.$) echo .*
. .. .aaa
%{%}%(!.#.$)%E%{%}%T%{%} %(!.%{%}.%{%})%U%%m%u%{%} %{%}%3(.!...!)%2.(%j/%L)%{%}%(!.#.$) bash
garry ~/wow $ echo .
.
garry ~/wow $ echo *
aaa
garry ~/wow $ echo .*
. .. .aaa
garry ~/wow $


вообще, ад, если раньше ".." можно было удалить.

tokuchu

Ну тут лучше на конкретный шелл завязываться, наверное. В man bash есть раздел "Pathname Expansion", там в принципе можно понять что нужно сделать, чтобы "*" превращалась во все файлы кроме "." и "..".

Dasar

>> минус: относительные пути получаются с точкой, что не всегда удобно
>Чего?
например:
если делать так tar *, то путь файлов в архиве будет foo
если же делать так tar ., то путь файлов в архиве будет ./foo
и во втором случае, чтобы из tar-а получить только файл foo, необходимо явно указывать ./foo (просто foo не сработает)

tokuchu

Вроде как этого достаточно:
shopt -s dotglob

tokuchu

>> минус: относительные пути получаются с точкой, что не всегда удобно
>Чего?
например:
если делать так tar *, то путь файлов в архиве будет foo
если же делать так tar ., то путь файлов в архиве будет ./foo
и во втором случае, чтобы из tar-а получить только файл foo, необходимо явно указывать ./foo (просто foo не сработает)
А мне кстати 2-й вариант больше нравится делать в таких случаях. Тогда при указании паттернов включения-исключения, если надо к корню архива привязаться, то можно "./" указать.

tokuchu

вообще, ад, если раньше ".." можно было удалить.
Ну если ты просил об этом. :)

Dasar

shopt -s dotglob
легко запутаться. Для всей системы ставить неправильно, а то, что это надо прописать в каждый скрипт легко забыть.

tokuchu

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

Dasar

Ну если ты заранее знаешь, что * не раскрывается в файлы, начинающиеся с точки.
Мне хочется получить железное правило (оно же привычка) описывающая требования к оформлению строки кода, которая по смыслу должна обработать все файлы.
Правило, что где-то ранее должна быть переопределена глобальная настройка с помощью shopt -s dotglob под это плохо подходит. Потому что легко пропустить, что какой-то другой участок кода меняет эту глобальную настройку под какие-то свои задачи, и в этом случае всё сломается

Dasar

получаются вот такие два заклинания
относительные пути с точкой

find -maepth 1 -not -name .

относительные пути без точки

find * .* -maepth 0 -not -name . -not -name ..

Alena_08_11

Я все врем удаляю через rm -rf ./* и не парился особо. а щас оказывается, что если бы я начал пользоваться никсами ранее, то мог бы такой командой рекурсивно снести всё? дела ...

Serab

нет, этой командой ты бы ничего лишнего не снес, но она не сносит файлы, начинающиеся на точку, об этом, собственно, и тред :)

Serab

Прекрасные грабли!
есть же что-то такое в связи со ссылками на каталоги, типа rm cat/ не хочет удалять ссылку cat, а rm cat работает. Не помню уже что там к чему.

AlexV769

если cat - это симлинк на какой-то каталог, то cat/ - это собственно тот каталог и есть, а вовсе не симлинк.

Serab

Ну да, так. Тоже чем-то напоминает грабли :)

nas1234

можно вопрос?
а почему в данной теме даже не поднималась тема гуя?

bestpilot8

Но зачем?

vall

Да, но нагуя?

IvladV71

> как под *nix-ами принято удалять(копировать и т.д.) всё из папки?
откуда?

nas1234

командная строка это же неудобно!

Dasar

а почему в данной теме даже не поднималась тема гуя?
потому что если можно использовать gui, то всё тоже самое делается более очевидным образом

hoha32

всё тоже самое делается более очевидным образом
это при условии что все скрытые и системные файлы заранее были сделаны видимыми

tokuchu

Ну да, так. Тоже чем-то напоминает грабли :)
Ну тут по крайней мере у тебя комманда не выполнится. А там можно облажаться с тем что ты хотел сделать, при комплишене может / подставиться.

tokuchu

получаются вот такие два заклинания
Ну в том же bash может быть такое заклинание тогда, если не нужно глобально объявлять:
shopt -s dotglob
... * ...
shopt -u dotglob
В принципе иногда такое может быть и лучше написать.
С find могут быть проблемы, если ты хочешь скормить его вывод кому-то через пайп. Это лучше делать через -print0, но тогда другая комманда должна уметь это прочитать.
Вот ещё есть обсуждения в инете:
http://stackoverflow.com/questions/1586477/bash-globbing-aut...
http://unix.stackexchange.com/questions/6393/how-do-you-move...

Phoenix

Ну если ты просил об этом.

тогда непонятно, почему
rm -Rf dir
не сносило корень, в dir ведь есть ..

tokuchu

тогда непонятно, почему
rm -Rf dir
не сносило корень, в dir ведь есть ..
Ну ты ещё скажи, что оно не зацикливалось, ведь в dir есть "."
Потому что оно рекурсивно по "." и ".." не ходит.

Dasar

shopt -s dotglob
... * ...
shopt -u dotglob
этот код некорректен, восстанавливать необходимо то состояние настроек которое было, а не то, которые думается, что было.
> С find могут быть проблемы, если ты хочешь скормить его вывод кому-то через пайп.
проблемы какого рода?
так-то его удобнее через вложенный вызов использовать, типа: rm -rf `find ...`
ps
что есть еще проблема с -, я помню

tokuchu

этот код некорректен, восстанавливать необходимо то состояние настроек которое было, а не то, которые думается, что было.
Ну это смотря где использовать. В своём скрипте вполне корректно. Да и в командной строке тоже, сессия обычно ограничена, а не от кого-то по наследству передаётся.
> С find могут быть проблемы, если ты хочешь скормить его вывод кому-то через пайп.
проблемы какого рода?
Всякие разные символы могут быть в именах фалов — от пробелов и до переводов строки.
так-то его удобнее через вложенный вызов использовать, типа: rm -rf `find ...`
Это вот как раз самое плохое использование. Даже пробелы в файлах уже вызовут проблему.
ps
что есть еще проблема с -, я помню
Это лечится легче, чем пробелы и переводы строки.

Dasar

Всякие разные символы могут быть в именах фалов — от пробелов и до переводов строки.
согласен, про такую гадость я совсем забыл

Serab

про это никогда нельзя забывать, это главный бич этого вашего unix-way

Dasar

главный бич этого вашего unix-way
скорее это бич malformed unstructured текста

Serab

Можно, конечно, заставить всех на xml общаться. Единственная проблема в том, что человека сложно, а у всех этих тулзов обычно такой вывод, что и для глаз удобно, это будто бы by design.

Serab

тогда непонятно, почему
rm -Rf dir
не сносило корень, в dir ведь есть ..
подожди, не пугайся ты так :grin: ты понимаешь, как работает globbing? Это bash когда видит "*" подставляет вместо нее все файлы, что видит, т.е. если в каталоге есть файлы foo, bar, то

rm *

превращается в

rm foo bar
и только после этого выполняется.
Т.е. проблема только в том, что bash, когда видит ".*" подставляет . и .., т.е. rm видит на входе

rm . .. .foo .bar

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

Dasar

Можно, конечно, заставить всех на xml общаться.
терминал может без проблем автоматически переводить "сильно"-форматированный текст в "слабо"-форматированный при показе пользователю
ps
"сильно"-форматированный текст - любой строковый литерал обязан быть заквоченным
"слабо"-форматированный текст - может опускаться квотинг простых строковых литералов

Serab

Ты переусложняешь. Так-то достаточно запретить перевод строки в именах файлов :)

Dasar

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

vall

квотинг никогда не работает. мой личный опыт хождения по граблям показывает что на него надеяться нельзя — всё ломается от первого чиха. только строки разделённые \n или \0. если что-то не получается передать как аргумент без квотинга значит нужно передавать как текст через пайп.

Serab

зато так будет надежно работать. А если сделать аккуратно, то и прозрачно для пользователя
Не понятно, как "так". Ты предлагаешь ввести на уровне ОС понятие "формат текстового файла"? (более продвинутый, что уже есть). Там и так уже есть некоторое понятие "набора строк", можно добавить эскейпинг перевода строки и будет тебе полноценный массив строк без необходимости изголяться с нулевым символом. Но внедрить это повсюду не представляется возможным.

tokuchu

Перестаньте его кормить, он сейчас про павер шел рассказывать начнёт. :grin:

Dasar

Перестаньте его кормить, он сейчас про павер шел рассказывать начнёт.
в powershell-е есть интересные мысли, но сделан он топорно. Формат обмена там тоже никак не зафиксирован.

Dasar

Ты предлагаешь ввести на уровне ОС понятие "формат текстового файла"?
я предлагаю ввести жесткий формат обмена данными между программами: xml, json, s-expression, что-то еще. Стандартизовать форматы common-структур: число, набор чего-либо, ссылки и т.д.
> Но внедрить это повсюду не представляется возможным.
Почему нет? Достаточно обеспечить гладкую совместимость с существующими программами. И предоставить бенефиты от поддержки нового формата.
> Там и так уже есть некоторое понятие "набора строк", можно добавить эскейпинг перевода строки и будет тебе полноценный массив строк без необходимости изголяться с нулевым символом.
одного эскейпинга перевода строк недостаточно, еще как минимум требуется признак, что строка поддерживает escaping

tokuchu

я предлагаю ввести жесткий формат обмена данными между программами: xml, json, s-expression, что-то еще. Стандартизовать форматы common-структур: число, набор чего-либо, ссылки и т.д.
Мне кажется его могут заинтересовать твои идеи:

Dasar

у Lennart-а тоже есть своё понимание unix-way?

Dasar

квотинг никогда не работает.
но интернет же как-то работает, что при работе через голый html, что при работе через ajax

nas1234

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

tokuchu

перевод строки в названии файла? но зачем?
Может быть. Этого достаточно.

tokuchu

у Lennart-а тоже есть своё понимание unix-way?
Ага. Погугли systemd, journald.

nas1234

Может быть
я собственно и спрашиваю, зачем это разрешено файловой системой, а не зачем это использовать.

tokuchu

я собственно и спрашиваю, зачем это разрешено файловой системой, а не зачем это использовать.
Скорее не запрещено. На сколько я помню, нельзя только / и \0.

serega1604

затем, что никаких оснований запрещать их нет. насколько я понимаю в ntfs они тоже не запрещены (в отличие от Windows™)

evgen5555

cd ..
rm -fr folder
mkdir folder

Dasar

cd ..
rm -fr folder
mkdir folder

evgen5555

в никсах всегда надо следить за тем, что запущено - это ж не винда

Dasar

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

find -mindepth 1 -maepth 1 -print0 | xargs -0 rm -rf --

ps
есть, кстати, стандартная команда, которая набор строк разделенных символом-0 переводит в правильно заэкспейченный набор значений разделенных пробелом?

spitfire

-print0 | xargs
Если print0 — то xargs -0 (тоже ноль, не "о").

Dasar

Если print0 — то xargs -0 (тоже ноль, не "о").
согласен, опечатался.

tokuchu

есть, кстати, стандартная команда, которая набор строк разделенных символом-0 переводит в правильно заэкспейченный набор значений разделенных пробелом?
Команда вроде не эскейпит. Это же в шеле происходит.
Если она вернёт на stdout "a\ b", То если ты её вызовешь в ``, то получишь 2 аргумента — "a\\" и "b".
Может быть можно поиграться со всякими IFS или как-то так. Надо в мане читать, не помню уже. Может быть можно разделитель поменять в bash.
Оставить комментарий
Имя или ник:
Комментарий: