Як mkdir лише у тому випадку, якщо dir вже не існує?


1987

Я пишу сценарій оболонки для запуску під KornShell (ksh) на AIX. Я хотів би скористатися mkdirкомандою для створення каталогу. Але каталог вже може існувати, і в цьому випадку я нічого не хочу робити. Тому я хочу або перевірити, чи не існує каталогу, або придушити помилку "Файл існує", яка mkdirвидається при спробі створення існуючого каталогу.

Будь-які думки про те, як найкраще це зробити?

Відповіді:


3293

Спробуйте mkdir -p:

mkdir -p foo

Зауважте, що це також створить проміжні каталоги, які не існують; наприклад,

mkdir -p foo/bar/baz

створюватимуть каталоги foo, foo/barа foo/bar/bazякщо їх не існує.

Деякі варіанти, такі як GNU, mkdirвключають mkdir --parentsпсевдонім, який можна прочитати більше, але це не вказано в специфікації POSIX / Single Unix і не доступне на багатьох поширених платформах, таких як macOS, різні BSD та різні комерційні Unixes, тому цього слід уникати.

Якщо ви хочете помилки, коли батьківських каталогів не існує, і ви хочете створити каталог, якщо він не існує, тоді ви можете testспочатку існувати в каталозі:

[ -d foo ] || mkdir foo

11
скорочений приклад, який ви використовуєте, - це саме те, чого ви не повинні робити. Це обернення логіки для економії простору кодування, але він повинен використовувати! та && та мати більше сенсу для тих, хто його читає.
Майк Q

16
@AndreasLarsen Це питання стосується mkdirUnix-подібних систем, а не Windows. -pнеобхідний для відповідності специфікації POSIX / Single Unix, тому все, що має намір відповідати цим специфікаціям, підтримуватиме -p. Windows зовсім інший, якщо ви не використовуєте емуляційний шар POSIX, як Cygwin або MSYS.
Брайан Кемпбелл

22
Я відкрив для себе щось цікаве сьогодні mkdir -p, ви можете використовувати дужки! {}створити "складне" дерево каталогів у команді. Дивіться тут: technosophos.com/2010/04/15/…
herve

12
@MikeQ я вважаю за краще, ||а не &&тому, що тоді вся лінія має правильний статус виходу. Важливо, якщо ваша оболонка працює errexitабо якщо ця лінія є останньою у функції, регістр комутатора, будь-що
rudimeier

9
@herve Це не має нічого спільного mkdir; оболонка розширює такий вираз до дискретного списку аргументів, які передаються mkdir.
чепнер

176

Це має працювати:

$ mkdir -p dir

або:

if [[ ! -e $dir ]]; then
    mkdir $dir
elif [[ ! -d $dir ]]; then
    echo "$dir already exists but is not a directory" 1>&2
fi

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


Я не думаю, що в korn є -d оператор, а -e використовується для обох файлів / каталогів і просто перевіряє існування. Крім того, всі вони повертають 0 після успіху, так що! є зайвим. Виправте мене, якщо я помиляюся.
alkar

1
помилка в обох підрахунках, AFAIK. тести повертаються справді на успіх, і -d теж існує (принаймні, на MacOS X)
Alnitak

5
можливо, варто згадати, що це не зовсім безпечно для потоків. між часом, коли ви перевіряєте, чи існує каталог, і часом, коли ви намагаєтесь написати, все може змінитися.
Джастін Л.


73

Визначення складних дерев каталогів однією командою

mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}

немає помилок, якщо вони є, зробіть батьківські каталоги за потребою
Fedir RYKHTIK

18
Майте на увазі, що це не mkdirсама особливість , а оболонка, яка виконує команду. Це називається brace extension - AFAIK, підтримують його лише Bash, ksh, zsh і оболонка C.
Даніель Каміль Козар

3
якщо у вас є пробіли навколо коми, ви можете (отримаєте) несподіваний результат. Остерігайся.
Atlas7

1
@ Atlas7 заявив, що вам потрібно буде уникнути символів, які зазвичай є частиною регулярного вираження. (тобто замість того, що folder nameвам потрібно використовувати folder\ name)
Джон Гамільтон

1
Це не відповідь; це окрема тема, яка була б більш доречною як коментар.
Кріс Пейдж

40

Якщо ви не хочете показувати жодне повідомлення про помилку:

[ -d newdir ] || mkdir newdir

Якщо ви хочете показати власне повідомлення про помилку:

[ -d newdir ] && echo "Directory Exists" || mkdir newdir

20

Стара старалась і правда

mkdir /tmp/qq >/dev/null 2>&1

зробить те, що ви хочете, ні в одному із перегонових умов у багатьох інших рішень немає.

Іноді найпростіші (і найпотворніші) рішення - найкращі.


5
Це не вдасться, якщо "tmp" не існувало. і це не дає вам ніякого підтвердження.
Майк Q

15

mkdir fooпрацює, навіть якщо каталог існує. Щоб він працював лише в тому випадку, якщо каталог з назвою "foo" не існує, спробуйте використовувати -pпрапор.

Приклад: -

mkdir -p foo

Це створить каталог з назвою "foo", лише якщо він не існує. :)


2
Як згадував @BrianCampbell, це також створить будь-які інші каталоги на шляху. Це може бути небезпечно, якщо, наприклад, гучність відключена, оскільки це може створювати каталоги в точці монтажу.
uliwitness


10

Або якщо ви хочете спочатку перевірити наявність:

if [[ ! -e /path/to/newdir ]]; then
            mkdir /path/to/newdir
fi

-e - це тест існуючої оболонки кукурудзи.

Ви також можете спробувати посібник з googling з кукурудзяної оболонки.


10

mkdir більше не підтримує -p перемикач у системах Windows 8+.

Ви можете скористатися цим:

IF NOT EXIST dir_name MKDIR dir_name

10
OP стосувався AIX kornshell ... нічого спільного з Windows, чи не так?
Дж. Чомель

9

Посилання на сторінку людини man mkdirдля варіанта -p

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

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

Правильне використання

mkdir -p /tmp/newdir/anotherdir

Після виконання команди ви можете бачити newdirта anotherdirстворювати під / tmp. Ви можете видавати цю команду стільки разів, скільки завжди є команда exit(0). З цієї причини більшість людей використовують цю команду в скриптах оболонки перед тим, як використовувати ці фактичні шляхи.


8

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

1) dir = / home / dir_name

if [ ! -d $dir ]
then
     mkdir $dir
else
     echo "Directory exists"  
fi

2) Ви можете використовувати каталог mkdir з опцією -p для створення каталогу. Він перевірить, чи каталог недоступний, буде.

mkdir -p $dir

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

mkdir -p /home/parent_dir /home/parent_dir/child1 /home/parent_dir/child2

Чи є якась перевага у використанні if циклу !? чому б хтось обрав цей варіант над -p ?!
pedram bashiri

1
Я поділився з вами способами створення папок, коли папки не існує. Це залежить від вимоги до тієї. Якщо у вас є випадок використання, коли вам потрібно перевірити, чи папка не існує, і ви хочете відслідковувати це, щоб ви могли перейти до рішення 1. Якщо це не має значення, ви можете перейти до рішення 2, воно створить папку якщо його не існує
AbhinavVaidya8

Я не бачив циклу.
Аміт Найду

3

Це проста функція (bash shell), яка дозволяє створити каталог, якщо він не існує.

#----------------------------------
# Create a directory if it doesn't exist
#------------------------------------
createDirectory() {
    if [ ! -d $1 ]
        then
        mkdir -p $1
    fi
}

Ви можете вказати вищевказану функцію як:

createDirectory / tmp / fooDir / BarDir

Сказане створює fooDir і BarDir, якщо вони не існують. Зверніть увагу на параметр "-p" у команді mkdir, яка створює каталоги рекурсивно. Сподіваюсь, це допомагає.


2
mkdir -p sam
  • mkdir = Зробити каталог
  • -p = - бабусі
  • (немає помилки, якщо вона існує, складіть батьківські каталоги за потребою)

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