Рассмотрим следующий сценарий:
TODAY=$(date -j +"%j # %Y.%m.%d # %H.%M.%S")
LAUNCHPAD_LOCATION=$(getconf DARWIN_USER_DIR)com.apple.dock.launchpad
LAUNCHPAD_DESTINATION = "/Users/tobias/[DEVELOPMENT # ROOT]/LOCAL/PROJECTS/sh # TK-Launchpad.DB/"$TODAY""
mkdir "$TODAY"
mkdir "$LAUNCHPAD_DESTINATION"
cp -Rv $LAUNCHPAD_LOCATION $LAUNCHPAD_DESTINATION
Что не так с этим сценарием? Он должен скопировать папку Launchpad.db на недавнюю дату, отформатированную в $TODAY, но этого не происходит. И да, мне нужны места для дальнейшей обработки файлов и эстетических целей.
Я попытался скопировать файл launchpad.db во временную папку без пробелов и скобок, а затем переместить результат в новую папку с пробелами и скобками.
TODAY_1=$(date -j +"%j_#_%Y.%m.%d_#_%H.%M.%S")
TODAY_2=$(date -j +"%j # %Y.%m.%d # %H.%M.%S")
LAUNCHPAD_LOCATION=$(getconf DARWIN_USER_DIR)com.apple.dock.launchpad
LAUNCHPAD_DESTINATION_1 = "/Users/tobias/DEVELOPMENT_#_ROOT/LOCAL/PROJECTS/sh_#_TK-Launchpad.DB/"$TODAY_1""
LAUNCHPAD_DESTINATION_2 = "/Users/tobias/[DEVELOPMENT # ROOT]/LOCAL/PROJECTS/sh # TK-Launchpad.DB/"$TODAY_2""
cp -Rv $LAUNCHPAD_LOCATION $LAUNCHPAD_DESTINATION_1
mv -v "$LAUNCHPAD_DESTINATION_1" "$LAUNCHPAD_DESTINATION_2"
Теперь я почти получаю результат, но теперь у меня проблема с этой надоедливой подпапкой, и я не могу избавиться от нее.
Кстати: есть ли более простое решение и, возможно, рабочее?
скопируйте/вставьте свой скрипт в shellcheck.net и прочитайте correct-bash-and-shell-script-variable-capitalization .
Очень редко сценарий выходит из строя молча, без каких-либо сообщений об ошибках (и вы не описали ни одного сообщения). Кроме того, вы не показали выполнение с включенной трассировкой (т. е. set -x
), поэтому мы также не можем видеть содержимое ваших переменных. Наконец, как сказал Эд Мортон, определитесь, на каком языке написан сценарий — sh или zsh.
@EdMorton: Насколько я знаю, sh — это оболочка, выполняющая стандартную оболочку системы. В моем случае это ЗШ.
@ELSanchez нет, sh - это оболочка, Bourne Shell (отличается от Bash, Bourne Again Shell и отличается от zsh). В любой системе возможно использовать псевдоним sh
для какой-либо другой оболочки, но не рассчитывайте на это, поскольку это часто приводит к изменению поведения любой оболочки, к которой он привязан, так, например, bash будет вести себя по-разному, если он называется bash или называется как sh (я понятия не имею, как с этим справляется zsh, и я понятия не имею, имеет ли sh в вашей системе псевдоним bash или zsh или это действительно просто sh). Выберите шебанг для любого языка оболочки, на котором написан ваш сценарий.
@user1934428: user1934428: Извините за отсутствие оператора ошибки или выходных данных оболочки. Я скопировал только части своего сценария и забыл об этом, пытаясь разобраться с цитированием.
Дополняя ответ ЭдМортона: если вы помечаете вопрос sh, вы явно запрашиваете бортовую оболочку. Если вы помечаете оболочку вопроса (и никакой другой тег оболочки), это означает, что вас интересует поведение оболочки POSIX. Для других оболочек укажите хотя бы имя оболочки, которую вы собираетесь использовать. Следовательно, вы можете пометить здесь только zsh или zsh и Shell (чтобы привлечь более широкую аудиторию), но тег sh не имеет смысла и его следует удалить.
Ничего страшного, что вы что-то забываете, но учтите, что вы можете редактировать вопросы и добавлять недостающие детали. Если вы этого не сделаете, вы рискуете, что вопрос будет закрыт модераторами.
Основная причина этого заключается в том, что он неправильно обрабатывает пробелы и специальные символы, такие как скобки, в пути к файлу. Помните, что всякий раз, когда вы используете переменную или путь, содержащие пробелы, всегда старайтесь заключать их в двойные кавычки, чтобы гарантировать, что оболочка обрабатывает их как один объект. Попробуйте это:
TODAY=$(date +"%j # %Y.%m.%d # %H.%M.%S")
LAUNCHPAD_LOCATION = "$(getconf DARWIN_USER_DIR)/com.apple.dock.launchpad"
LAUNCHPAD_DESTINATION = "/Users/tobias/[DEVELOPMENT # ROOT]/LOCAL/PROJECTS/sh # TK-Launchpad.DB/$TODAY"
mkdir -p "$LAUNCHPAD_DESTINATION"
cp -Rv "$LAUNCHPAD_LOCATION" "$LAUNCHPAD_DESTINATION"
Надеюсь, теперь он разрешит ваш вопрос. В случае, если вы обнаружите какие-либо сомнения, спросите еще раз.
Правильное цитирование – вот решение. Я могу понять, почему все против использования пробелов в именах файлов, но если я смогу правильно обрабатывать кавычки, которые могут оказаться очень сложными, то я думаю, что это не проблема, и это выглядит красиво.
@ElSanchez: Если вы действительно будете использовать zsh, как вы утверждали в своем вопросе, кавычки излишни, потому что zsh разбивает слова перед раскрытием параметра. Если цитирование помогло, я делаю вывод, что вы запускаете этот скрипт не как скрипт zsh.
@ user1934428: Моя строка shebang: #!/bin/sh . Я использую macOS Monterey. Системная оболочка — zsh, она связана с sh. Или другими словами: sh — это ссылка на zsh. Я пытаюсь быть толерантным к оболочке, и поэтому мой мозг говорит: #!/bin/env sh . Но в другой статье (stackoverflow.com/questions/53116226/…) говорится, что это не рекомендуется.
@ElSanchez: Но zsh не ведет себя как обычный zsh. Поскольку он называется sh
, он работает в режиме совместимости с POSIX, что означает, что он пытается действовать аналогично POSIX. В данном случае действительно кавычки нужны. В этом случае я бы пометил вопрос только оболочкой; не помешает упомянуть в тексте, что ваша оболочка POSIX представляет собой zsh в режиме POSIX. Я лично не одобряю такую установку. Какой смысл быть «толерантным к оболочке» и что именно это должно означать? Я использую zsh, потому что мне нравятся его возможности, а не для имитации более простой оболочки POSIX.
@user1934428: user1934428: Я хочу быть максимально совместимым с «каждой» оболочкой, даже если zsh не установлен. Вот что я имею в виду под устойчивостью к оболочке. Поэтому я думаю, что с помощью #!/bin/sh эта цель будет достигнута.