Кажется, что расширение параметра отсутствует

В настоящее время я изучаю, как писать простые скрипты, и не могу решить мою задачу.

У меня есть следующая команда в моем скрипте …

touch ${DIRECTORY}/${FILE} 

Эта команда появляется несколько раз в моем скрипте и отлично работает во всех случаях, кроме одного. По какой-то причине, в какой-то момент, он решает включить слэш в имя файла, которое он пытается создать, и я получаю ошибку …

 cannot touch `/myfile.dat': Permission denied 

Сначала я подумал, что это просто возможно до моей неопытности (что, вероятно, так и есть), но после небольшого исследования я видел, что эта строка используется в бесчисленных примерах, работающих правильно. Я не могу понять – одна и та же строка отлично работает в нескольких других местах моего скрипта!

Кто-нибудь хочет пролить свет на это? Это непоследовательность, которая меня очень раздражает. Могут ли команды, окружающие эту конкретную команду, влиять на ее результат?

  • Переменная в Bash, содержащая кавычки и пробелы
  • Может ли «>» включаться в переменную bash?
  • Bash: передача фигурных скобок в качестве аргументов функции bash
  • Комбинация строки Bash, используемая для создания списка параметров
  • Почему мои вкладки не расширяются в TIMEFORMAT?
  • Как положить $ @ в кавычки?
  • Невозможно использовать аргумент в сценарии расчета даты bash
  • Bash [[соответствие шаблону не работает
  • 2 Solutions collect form web for “Кажется, что расширение параметра отсутствует”

    Похоже, ${DIRECTORY} пуст. В этом случае touch ${DIRECTORY}/${FILE} расширяется, чтобы touch /${FILE}

    Возможно, что-то происходит.

    • Может быть, вы написали DIRECTORY ошибкой, поэтому скрипт запускает что-то вроде touch ${DRIECTORY}/${FILE} . Поскольку DIRECTORY не задана, если $FILE является myfile.dat , это расширяется, чтобы touch /${FILE} (переменная unset обрабатывается так, как если бы она была пустой).
      Вы можете отключить оболочку с сообщением об ошибке, если вы попытаетесь развернуть неустановленную переменную. Положите set -u в начало скрипта (после строки #! ). Вы можете переключаться между ошибками unset-triggers и unset-is-empty с помощью set -u и set +u .
    • Возможно, переменная DIRECTORY в данный момент не установлена ​​или пуста. См. Предыдущий пункт.
    • Возможно, вы случайно поставили дополнительное пространство: touch ${DIRECTORY} /${FILE} . Затем команда touch получает два параметра, она работает на ${DIRECTORY} (что, поскольку это, по-видимому, имя существующего каталога, устанавливает время модификации этого каталога на текущее время), затем он задыхается /${FILE} .
    • Возможно, есть дополнительное пространство в конце значения DIRECTORY . Например, если значением переменной является /some/path с пробелом в конце, то touch получает два параметра: /some/path и /myfile.dat . См. Предыдущий пункт.

    Ваш скрипт не будет работать, если DIRECTORY или FILE содержат любой пробельный символ или символ подстановки \[?* . Это связано с тем, что, когда вы пишете, например, $FOO , это не просто расширяется до значения переменной: это значение затем разбивается на слова в каждой пробельной последовательности, и каждое слово интерпретируется как шаблон подстановочного знака и заменяется соответствующими именами файлов (если имя файла не совпадает, шаблон остается в покое). Всегда используйте двойные кавычки вокруг переменных подстановок (и аналогичных подстановок). Внутри двойных кавычек "$FOO" расширяется до значения FOO без дальнейшего искажения.

     touch "$DIRECTORY/$FILE" 

    (См. Также $ VAR vs $ {VAR} и цитировать или не цитировать )

    Чтобы лучше понять, что делает скрипт, поставьте set -x после #! линия. Это включало режим отладки, когда оболочка печатает каждую команду перед ее выполнением. Вы можете включать и отключать трассировку отладки с помощью set -x и set +x .

    Linux и Unix - лучшая ОС в мире.