рекурсивный mkdir

Если Вы просто хотите часовой пояс, то часовые пояса хранятся в /usr/share/zoneinfo.

Если Вы хотите смочь получить текущее время для многих различных городов или стран, то можно вытянуть их от Шлюза Даты и времени.

329
06.11.2014, 02:42
3 ответа
$ mkdir -p foo/bar/zoo/andsoforth
554
27.01.2020, 19:26
  • 1
    К вашему сведению-p обозначает "родительский" –  carl crott 22.04.2015, 20:06
  • 2
    Они, возможно, сделали-r вместо этого, как любая другая команда, это невозможно помнить определенные параметры за каждый –  Vedmant 21.03.2016, 04:56
  • 3
    Но mkdir -p не является кросс-платформенным, не работает в каждой оболочке –  Роман Коптев 17.04.2016, 16:40
  • 4
    @РоманКоптев, mkdir -p указан в POSIX, который является самой близкой вещью к тому, чтобы быть полностью портативным. Что лучше Вы ожидаете в сценарии оболочки? –  Wildcard 18.04.2016, 21:54
  • 5
    @StephanBijzitter Да, это - unix.se, не unixandwindows.se. :) –  EEAA 05.10.2016, 22:21

Использование mkdir -p - простой способ для большинства современных ОС:

mkdir -p foo/bar/zoo/andsoforth

Однако, mkdir -p не рекомендуется во многих руководствах. Читайте документацию к GNU make и autoconf о проблемах с использованием mkdir -p:

Кроссплатформенные системы установки и настройки имеют свои безопасные альтернативы для mkdir -p.

CMake для использования в командной строке shell:

 cmake -E make_directory foo/bar/zoo/andsoforth

Autoconf для использования в скрипте с препроцессингом:

AS_MKDIR_P(foo/bar/zoo/andsoforth)

или:

AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)

Но эти решения требуют установки инструментов cmake или autoconf (M4) (и возможной предварительной обработки)

Вы можете использовать также скрипт install-sh с опцией -d:

install-sh -d foo/bar/zoo/andsoforth

Этот скрипт используется в проектах autoconf и automake. Я думаю, что это должно быть самое безопасное решение.

В то время я искал кроссплатформенное решение для стандартного /bin/sh без зависимостей, но не нашел. Поэтому я написал следующий скрипт, который может быть не идеален, но я думаю, что он соответствует большинству кроссплатформенных требований:

#! /bin/sh

cdirname() # cross platform alternative for 'dirname'
{
  # $1 - path
  test $# -eq 1 || { echo "Procedure 'cdirname' must have only one parameter. Scripting error."; exit 1; }
  echo "$1" | sed -n -e '1p' | sed  -e 's#//*#/#g' -e 's#\(.\)/$#\1#' -e 's#^[^/]*$#.#' -e 's#\(.\)/[^/]*$#\1#' -
}

mkd() # cross platform alternative for 'mkdir -p'
{
  # $1 - directory to create
  test $# -eq 1 || { echo "Function 'mkd' can create only one directory (with it's parent directories)."; exit 1; }
  test -d "$1"  && return 0
  test -d "$(cdirname "$1")" || { mkd "$(cdirname "$1")" || return 1; }
  test -d "$1" || { mkdir "$1" || return 1; }
  return 0
}

Этот скрипт можно использовать для старых систем, где отсутствует опция -p для mkdir. В код добавлена

sed-базированная кроссплатформенная версия dirname. Она работает аналогично dirname (корректно с путями /, путями только с базовым именем, путями с трейлингом /, путями с трейлингом \ns и без него). Эта функция не может работать корректно, если путь содержит новые строки или некоторые недопустимые символы для текущей локали. Она также заменяет любую комбинацию / (//, ///) на одну /

Измененная строка mkdir "$1" || return 1 на test -d "$1" || { mkdir "$1" || return 1; } потому что mkdir завершается с ошибкой, если путь существует, а эта проверка необходима для путей, содержащих конструкции типа aaa\. (Если aaa не существует, предыдущая версия создает aaa, а затем пытается создать его снова).

Эта версия mkd не выдает ошибку, если путь уже существует (но все еще имеет возможность выдать такую ошибку при параллельном выполнении) и не может получить несколько каталогов в командной строке.

18
27.01.2020, 19:26

Опция -pв команде mkdirделаетp отсутствием каталогов по мере необходимости (без ошибок, если они существуют):

mkdir -p foo/bar/zoo/andsoforth

Другой способ, например, использовать ошибку &&(, если указанная папка существует):

mkdir foo && mkdir foo/bar && mkdir foo/bar/zoo && mkdir foo/bar/zoo/andsoforth

Оператор цепочки &&используется для объединения команд, так что следующая команда выполняется тогда и только тогда, когда предыдущая команда завершилась без ошибок.

Конечно, первый способ лучше.

1
27.01.2020, 19:26

Теги

Похожие вопросы