[*nix] как принято удалять всё из папки?
find -delete
cp -R sourcefolder destinationfolder
cp -R sourcefolder/ destinationfolder
bash в макоси по первой команде копирует каталог с содержимым, а по второй — именно содержимое.
другие операции (копирование, изменение прав и т.д.) с использованием квантора "все" (скопировать всё, поменять права у всех и т.д.) тоже делается через комбинацию с find?
rm -rf * .*А это ".." не зацепляет?
полезный нюанс, спасибо
ps
я такое поведение у rsync-а заметил, а у cp пропустил.
а если хочется потрогать только файлы или только директории то без find не обойтись: find -type d -exec chmod 755 '{}' ';'
А это ".." не зацепляет?оно цепляет и .., и . , но rm ругается, что их удалить не может. В итоге, делает то, что хочется, но сильно коряво конечно.
но другие рекурсивные операции можно применять на .минус: относительные пути получаются с точкой, что не всегда удобно
А это ".." не зацепляет?склероз мне подсказывает, что вот ровно так я однажды сколько-то лет назад снёс довольно полезную папочку с незакоммиченным кодом
хотя может то что другое было опасное - уже не помню
склероз мне подсказывает, что вот ровно так я однажды сколько-то лет назад снёс довольно полезную папочку с незакоммиченным кодомСклероз подсказывает, что в эпоху мифов и первобытнообщинного строя так и / рекурсивно сносили. Пока в командных процессорах не стали защиту от дурака делать.
оно цепляет и .., и . , но rm ругается, что их удалить не может. В итоге, делает то, что хочется, но сильно коряво конечно.это он просто добрый, команда не обязана не работать с "." и "..", потому что, в конце концов, это легальные относительные пути. Это просто rm таким чувствительным стал, потому что случайно можно много чего запороть. В скриптах на это полагаться нежелательно, да и нелогично, почему rm надо пользовать так, а другую команду — по-другому
Чего?но другие рекурсивные операции можно применять на .минус: относительные пути получаются с точкой, что не всегда удобно
А вообще зачем ты хочешь удалить всё из каталога, но каталог не трогать? Может тогда проще и каталог удалить и создать заново?
bash в макоси по первой команде копирует каталог с содержимым, а по второй — именно содержимое.Прекрасные грабли!
А вообще зачем ты хочешь удалить всё из каталога, но каталог не трогать? Может тогда проще и каталог удалить и создать заново?если удалять каталог, то отваливаются открытые handle-ы, которые на этот каталог ссылались. Это проявляется, например, в use case-е когда скрипт запускается из диры, которую надо почистить.
зависит от шела. 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 $
вообще, ад, если раньше ".." можно было удалить.
Ну тут лучше на конкретный шелл завязываться, наверное. В man bash есть раздел "Pathname Expansion", там в принципе можно понять что нужно сделать, чтобы "*" превращалась во все файлы кроме "." и "..".
>Чего?
например:
если делать так tar *, то путь файлов в архиве будет foo
если же делать так tar ., то путь файлов в архиве будет ./foo
и во втором случае, чтобы из tar-а получить только файл foo, необходимо явно указывать ./foo (просто foo не сработает)
shopt -s dotglob
>> минус: относительные пути получаются с точкой, что не всегда удобноА мне кстати 2-й вариант больше нравится делать в таких случаях. Тогда при указании паттернов включения-исключения, если надо к корню архива привязаться, то можно "./" указать.
>Чего?
например:
если делать так tar *, то путь файлов в архиве будет foo
если же делать так tar ., то путь файлов в архиве будет ./foo
и во втором случае, чтобы из tar-а получить только файл foo, необходимо явно указывать ./foo (просто foo не сработает)
вообще, ад, если раньше ".." можно было удалить.Ну если ты просил об этом.
shopt -s dotglobлегко запутаться. Для всей системы ставить неправильно, а то, что это надо прописать в каждый скрипт легко забыть.
легко запутаться. Для всей системы ставить неправильно, а то, что это надо прописать в каждый скрипт легко забыть.Ну если ты заранее знаешь, что * не раскрывается в файлы, начинающиеся с точки. И хочешь это изменить в конктретном месте, то это несложно. Не знаю что тебя запутывает.
Ну если ты заранее знаешь, что * не раскрывается в файлы, начинающиеся с точки.Мне хочется получить железное правило (оно же привычка) описывающая требования к оформлению строки кода, которая по смыслу должна обработать все файлы.
Правило, что где-то ранее должна быть переопределена глобальная настройка с помощью shopt -s dotglob под это плохо подходит. Потому что легко пропустить, что какой-то другой участок кода меняет эту глобальную настройку под какие-то свои задачи, и в этом случае всё сломается
относительные пути с точкой
find -maepth 1 -not -name .
относительные пути без точки
find * .* -maepth 0 -not -name . -not -name ..
Я все врем удаляю через rm -rf ./* и не парился особо. а щас оказывается, что если бы я начал пользоваться никсами ранее, то мог бы такой командой рекурсивно снести всё? дела ...
нет, этой командой ты бы ничего лишнего не снес, но она не сносит файлы, начинающиеся на точку, об этом, собственно, и тред
Прекрасные грабли!есть же что-то такое в связи со ссылками на каталоги, типа rm cat/ не хочет удалять ссылку cat, а rm cat работает. Не помню уже что там к чему.
если cat - это симлинк на какой-то каталог, то cat/ - это собственно тот каталог и есть, а вовсе не симлинк.
Ну да, так. Тоже чем-то напоминает грабли
а почему в данной теме даже не поднималась тема гуя?
Но зачем?
Да, но нагуя?
откуда?
командная строка это же неудобно!
а почему в данной теме даже не поднималась тема гуя?потому что если можно использовать gui, то всё тоже самое делается более очевидным образом
всё тоже самое делается более очевидным образомэто при условии что все скрытые и системные файлы заранее были сделаны видимыми
Ну да, так. Тоже чем-то напоминает граблиНу тут по крайней мере у тебя комманда не выполнится. А там можно облажаться с тем что ты хотел сделать, при комплишене может / подставиться.
получаются вот такие два заклинанияНу в том же 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...
Ну если ты просил об этом.
тогда непонятно, почему
rm -Rf dir
не сносило корень, в dir ведь есть ..
тогда непонятно, почемуНу ты ещё скажи, что оно не зацикливалось, ведь в dir есть "."
rm -Rf dir
не сносило корень, в dir ведь есть ..
Потому что оно рекурсивно по "." и ".." не ходит.
shopt -s dotglobэтот код некорректен, восстанавливать необходимо то состояние настроек которое было, а не то, которые думается, что было.
... * ...
shopt -u dotglob
> С find могут быть проблемы, если ты хочешь скормить его вывод кому-то через пайп.
проблемы какого рода?
так-то его удобнее через вложенный вызов использовать, типа: rm -rf `find ...`
ps
что есть еще проблема с -, я помню
этот код некорректен, восстанавливать необходимо то состояние настроек которое было, а не то, которые думается, что было.Ну это смотря где использовать. В своём скрипте вполне корректно. Да и в командной строке тоже, сессия обычно ограничена, а не от кого-то по наследству передаётся.
> С find могут быть проблемы, если ты хочешь скормить его вывод кому-то через пайп.Всякие разные символы могут быть в именах фалов — от пробелов и до переводов строки.
проблемы какого рода?
так-то его удобнее через вложенный вызов использовать, типа: rm -rf `find ...`Это вот как раз самое плохое использование. Даже пробелы в файлах уже вызовут проблему.
psЭто лечится легче, чем пробелы и переводы строки.
что есть еще проблема с -, я помню
Всякие разные символы могут быть в именах фалов — от пробелов и до переводов строки.согласен, про такую гадость я совсем забыл
про это никогда нельзя забывать, это главный бич этого вашего unix-way
главный бич этого вашего unix-wayскорее это бич malformed unstructured текста
Можно, конечно, заставить всех на xml общаться. Единственная проблема в том, что человека сложно, а у всех этих тулзов обычно такой вывод, что и для глаз удобно, это будто бы by design.
тогда непонятно, почемуподожди, не пугайся ты так ты понимаешь, как работает globbing? Это bash когда видит "*" подставляет вместо нее все файлы, что видит, т.е. если в каталоге есть файлы foo, bar, то
rm -Rf dir
не сносило корень, в dir ведь есть ..
rm *
превращается в
и только после этого выполняется.
rm foo bar
Т.е. проблема только в том, что bash, когда видит ".*" подставляет . и .., т.е. rm видит на входе
rm . .. .foo .bar
и это уже из-за его доброты, он их не удаляет. Т.е. сделай "ls .*" и он будет работать с "." и "..". Не знаю, что там было раньше, я так давно не пользовался.
Можно, конечно, заставить всех на xml общаться.терминал может без проблем автоматически переводить "сильно"-форматированный текст в "слабо"-форматированный при показе пользователю
ps
"сильно"-форматированный текст - любой строковый литерал обязан быть заквоченным
"слабо"-форматированный текст - может опускаться квотинг простых строковых литералов
Ты переусложняешь. Так-то достаточно запретить перевод строки в именах файлов
зато так будет надежно работать. А если сделать аккуратно, то и прозрачно для пользователя
Ты переусложняешь. Так-то достаточно запретить перевод строки в именах файловчерез командную строку работается далеко не только с именами файлов
квотинг никогда не работает. мой личный опыт хождения по граблям показывает что на него надеяться нельзя — всё ломается от первого чиха. только строки разделённые \n или \0. если что-то не получается передать как аргумент без квотинга значит нужно передавать как текст через пайп.
зато так будет надежно работать. А если сделать аккуратно, то и прозрачно для пользователяНе понятно, как "так". Ты предлагаешь ввести на уровне ОС понятие "формат текстового файла"? (более продвинутый, что уже есть). Там и так уже есть некоторое понятие "набора строк", можно добавить эскейпинг перевода строки и будет тебе полноценный массив строк без необходимости изголяться с нулевым символом. Но внедрить это повсюду не представляется возможным.
Перестаньте его кормить, он сейчас про павер шел рассказывать начнёт.
Перестаньте его кормить, он сейчас про павер шел рассказывать начнёт.в powershell-е есть интересные мысли, но сделан он топорно. Формат обмена там тоже никак не зафиксирован.
Ты предлагаешь ввести на уровне ОС понятие "формат текстового файла"?я предлагаю ввести жесткий формат обмена данными между программами: xml, json, s-expression, что-то еще. Стандартизовать форматы common-структур: число, набор чего-либо, ссылки и т.д.
> Но внедрить это повсюду не представляется возможным.
Почему нет? Достаточно обеспечить гладкую совместимость с существующими программами. И предоставить бенефиты от поддержки нового формата.
> Там и так уже есть некоторое понятие "набора строк", можно добавить эскейпинг перевода строки и будет тебе полноценный массив строк без необходимости изголяться с нулевым символом.
одного эскейпинга перевода строк недостаточно, еще как минимум требуется признак, что строка поддерживает escaping
я предлагаю ввести жесткий формат обмена данными между программами: xml, json, s-expression, что-то еще. Стандартизовать форматы common-структур: число, набор чего-либо, ссылки и т.д.Мне кажется его могут заинтересовать твои идеи:
у Lennart-а тоже есть своё понимание unix-way?
квотинг никогда не работает.но интернет же как-то работает, что при работе через голый html, что при работе через ajax
Всякие разные символы могут быть в именах фалов — от пробелов и до переводов строки.перевод строки в названии файла? но зачем?
перевод строки в названии файла? но зачем?Может быть. Этого достаточно.
у Lennart-а тоже есть своё понимание unix-way?Ага. Погугли systemd, journald.
Может бытья собственно и спрашиваю, зачем это разрешено файловой системой, а не зачем это использовать.
я собственно и спрашиваю, зачем это разрешено файловой системой, а не зачем это использовать.Скорее не запрещено. На сколько я помню, нельзя только / и \0.
затем, что никаких оснований запрещать их нет. насколько я понимаю в ntfs они тоже не запрещены (в отличие от Windows™)
rm -fr folder
mkdir folder
cd ..
rm -fr folder
mkdir folder
в никсах всегда надо следить за тем, что запущено - это ж не винда
Это вот как раз самое плохое использование. Даже пробелы в файлах уже вызовут проблему.т.е. для случая, когда команду с множеством значений можно заменить на множество команд с одиночным значением стоит использовать такое:
find -mindepth 1 -maepth 1 -print0 | xargs -0 rm -rf --
ps
есть, кстати, стандартная команда, которая набор строк разделенных символом-0 переводит в правильно заэкспейченный набор значений разделенных пробелом?
-print0 | xargsЕсли print0 — то xargs -0 (тоже ноль, не "о").
Если print0 — то xargs -0 (тоже ноль, не "о").согласен, опечатался.
есть, кстати, стандартная команда, которая набор строк разделенных символом-0 переводит в правильно заэкспейченный набор значений разделенных пробелом?Команда вроде не эскейпит. Это же в шеле происходит.
Если она вернёт на stdout "a\ b", То если ты её вызовешь в ``, то получишь 2 аргумента — "a\\" и "b".
Может быть можно поиграться со всякими IFS или как-то так. Надо в мане читать, не помню уже. Может быть можно разделитель поменять в bash.
Оставить комментарий
Dasar
как под *nix-ами принято удалять(копировать и т.д.) всё из папки?Сейчас использую
но это царапает мою тягу к прекрасному