Чому у 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.