Чому у mkdir за замовчуванням не встановлено прапор -p, що дозволяє створювати вкладені каталоги?


11

Я не бачу причини, за якою -pпрапор mkdirне повинен бути встановлений за замовчуванням.

  -p, --parents     no error if existing, make parent directories as needed

Це неруйнівна команда з того, що я бачу. Чи пропустив я щось важливе у тому, як це працює?

По-друге, чи існує простий спосіб зробити це поведінкою за замовчуванням mkdir?


2
це в вашому .bashrc: alias mkdir="mkdir -p".
— Кевін

Після усієї дискусії я вирішив піти з псевдонімомmkdp
— Treffynnon

Відповіді:


6

Це необов'язкова функція, яка не завжди бажана, особливо в сценаріях. Розгляньте такі недоліки у випадку сценаріїв:

  • Про те, що каталог вже існує, не повідомляється: Якщо сценарій повинен містити деякі файли в новоствореному каталозі, а цей каталог вже існує і містить файли, сценарій може зробити безлад. (Пізніше буде важко відфільтрувати файли, розміщені там за сценарієм.)
  • Зворотного боку вищезазначеного, деякий скрипт (або його частина) може залежати від структури каталогу, створеної раніше (можливо, іншим пакетом / сценарієм). Наприклад, сценарій встановлення пакета може знадобитися помістити бібліотеки в підкаталог /usr/local/lib/GreatSoftware/ImportantPartOfIt, але бібліотеки залежать від / посилання на матеріал під /usr/local/lib/GreatSoftware. Якщо цього немає, сценарій не повинен продовжуватися.

Родова поведінка mkdirробить її легкою і природною, оскільки про такі ситуації повідомляється і їх можна зловити відразу.


Ви можете зробити псевдонім для нього, якщо хочете завжди використовувати mkdir -pу своїх оболонках:

alias mkdir='mkdir -p'

(Це має перейти до вашої .bashrcабо будь-якої іншої конфігурації, яку використовує ваша оболонка.)


1
Я б не пропонував псевдоніму стандартну команду, щоб вона вела себе нестандартним чином. Це зробило б сценарії не портативними і може заплутати читачів. Створення нового псевдоніма або функції, як, alias mkdp="mkdir -p"було б доцільніше.
— jlliagre

2
@jlliagre Ні, це не вплине на сценарії. Псевдоніми, визначені локально .bashrc, не (як правило) впливають на їхнє середовище.
— rozcietrzewiacz

Дійсно, але ти пропустив мою думку. Здавання стандартної команди для зміни своєї поведінки, навіть для власного використання, не є рекомендованою практикою. Найгірший приклад - всюдисущий alias rm='rm -i'.
— jlliagre

1
@jlliagre Хто не рекомендує? ;) Але так, я згоден, я б скоріше використовував інший псевдонім - але з практичних, а не з ідеологічних причин. Я також не думаю, що rm -iпсевдонім завжди поганий - хоча це може призвести до шкідливих звичок. Звичайно, не всі командні псевдоніми однаково хороші / погані - розгляньте ls="ls --color=auto"або, ssh="TERM=xterm ssh"наприклад.
— rozcietrzewiacz

У моїй рекомендації немає нічого ідеологічного. Псевдонім rm опосередковано відповідає за багато втрачених файлів (я зустрічав безліч жертв цього псевдоніма). Я підозрював, що mkdir у значно меншій мірі має небажані побічні ефекти. Звичайно, я не проти косметичних, не поведінкових змін, як твої приклади ssh та ls.
— jlliagre

16

Звичайно, можна стверджувати, що створення батьківського каталогу має бути за замовчуванням, а для запобігання створенню каталогу, якщо його не існує, може бути використаний певний варіант перевірки.

Але причина, чому навпаки, - це лише історія. Базова версія mkdir не створювала батьківських каталогів. Ось чому дистрибутив X11 поставився разом із командою на ім'я mkdirhier, яка змогла виконати це завдання: перевірити, чи існують батьківські каталоги та створити їх, якщо це необхідно.

Пізніше ця функціональність була додана до команди mkdir у багатьох версіях UNIX (я не знаю, чи є вона зараз у стандарті POSIX). Для підтримки сумісності ця функція була доступна при включенні прапора опції: -p.

Чому погано його включати за замовчуванням? Сценарії можуть покладатися на помилку mkdir, якщо батьківський каталог не існує. Тим більше, що користувач root може створювати дерева директорій за замовчуванням небезпечно.

Приклад:

 if mkdir /backup/$(uname -n)/$(date +%Y%m%d)
  then
    perform_backup ...

У цьому прикладі буде створено каталог, і резервне копіювання виконується навіть у тому випадку, коли файлова система /backupне змонтована і батьківська /backup/$(uname -n)не існує, якщо за замовчуванням було б навпаки.

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


2
Мені подобається приклад монтажу, який ви тут використовували. Я не думав про той конкретний сценарій.
— Treffynnon

1
Параметри -p (і -m) були введені системою V в 1983 році. Обидва, безумовно, є частиною стандарту POSIX.
— jlliagre

4

Я думаю, це якась філософія. Гола команда mkdir (1) (без опцій) представляє системний виклик mkdir (2) , забезпечуючи її функціональність у оболонці, не роблячи нічого більш-менш.


4

На початку була лише гола mkdirкоманда. Відповідно до принципів проектування Unix, ця проста команда виконала одне просте завдання: створення каталогу.

Пізніше mkdirнабула -pможливість обробляти загальний випадок використання, коли абонент хоче створити нуль, один або кілька каталогів, щоб переконатися, що існує певний шлях. Це не було зроблено операцію за замовчуванням з кількох причин. По-перше, не всі системи мали цю більш складну функцію, і необхідність цього -pпараметра означала, що сценарії, які використовували її, отримували б розумне повідомлення про помилку (щось на зразок mkdir: invalid option -z), а не як не дивно, не час від часу створюючи каталоги. По-друге, і найголовніше, що поведінка mkdir -pне є сумісною заміною mkdirу всіх випадках.

Зокрема, на більшості файлових систем mkdir- це атомна операція . Якщо програма запускається mkdir playgroundі команда успішна, програма знає, що вона створила playgroundкаталог. Це дозволяє програмі трактувати новий каталог як його ексклюзивний майданчик: якщо інший екземпляр цієї ж програми працює одночасно, його виклик mkdir playgroundне вдасться. Це властивість, очевидно, не надається, mkdir -pоскільки дозволяє аргументувати.

Якби mkdir -pвін існував з самого початку, він міг би бути створений за замовчуванням, з чимось на зразок mkdir -aкоманди створення одного каталогу. Але це не випливало б із звичайної філософії дизайну Unix: більшість основних утиліт - це прості обгортки навколо основних примітивів, з фантазійною поведінкою (як створення декількох каталогів за один раз), які вимагають фантазійних варіантів.


2

Для мене проблема полягає в тому, що поведінка опції -p, якщо вона була б за замовчуванням, по суті є побічним ефектом. Це додає складності команді, роблячи щось додаткове до того, що ви її просили зробити. Це ще одна невидима річ, яку потрібно пам’ятати. Одне з основних правил практичного звучання програмування - уникати побічних ефектів.

Сучасні мови програмування настільки потужні, що складати будь-яку складну команду вам може знадобитися з примітивів, які надає мова. Це передбачає прийняття свідомого рішення про те, яка поведінка вимагається, а також залишає конкретні, видимі записи про зроблене.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.