В чем разница, имеющая двойные кавычки или нет в bash

У меня есть несколько сценариев bash, один из которых имеет следующий контент:

#!/bin/bash source $(dirname ${BASH_SOURCE[0]})/script.sh 

в то время как другой имеет следующее содержание:

 #!/bin/bash source "$(dirname ${BASH_SOURCE[0]})/script.sh" 

Как эти сценарии ведут себя по-разному и почему? В чем разница?

  • Не удалось получить команду для работы с bash -c
  • команда: ls / etc | сортировать | grep d * не дает результатов, но ls / etc | сортировать | grep p * перечисляет всю директорию
  • Почему команда grep игнорирует период в строке поиска?
  • Escaping * с регулярными выражениями и Grep
  • Параметр синтаксического анализа скрипта Bash с кавычками
  • Регулярное выражение с использованием \\ vs с использованием \
  • как выразить строку в оболочке?
  • Есть ли причина, чтобы указать статус выхода $? переменная?
  • 3 Solutions collect form web for “В чем разница, имеющая двойные кавычки или нет в bash”

    Основное различие заключается в том, что цитируемая версия не подвержена разбиению поля оболочкой.

    С двойными кавычками результат расширения команды будет подаваться как один параметр в команду source . Без кавычек он будет разбит на несколько параметров, в зависимости от значения IFS которое по умолчанию содержит пространство, TAB и новую строку.

    Если имя каталога не содержит таких пробелов, то разбиение поля не происходит.

    Как правило, лучше использовать двойные кавычки с подстановками команд и расширениями переменных.

    Без кавычек строка подвержена разбиению и глобализации слов . См. Также BashPitfalls # 14 .

    сравнить

     $ echo $(printf 'foo\nbar\nquux\n*') foo bar quux ssh-13yzvBMwVYgn ssh-3JIxkphQ07Ei ssh-6YC5dbnk1wOc 

    с

     $ echo "$(printf 'foo\nbar\nquux\n*')" foo bar quux * 

    Когда происходит разбиение слов, первый символ IFS действует как разделитель (который по умолчанию является пространством).

    Почти во всех ситуациях вы хотите добавить кавычки. Есть несколько исключений, например

    • В выражениях, где слово splitting / globbing не происходит, например, простые (не-массивные) назначения и оператор case . Все безопасны:

      • foo=*
      • foo=${bar}qux${quux}
      • foo=$(bar "${quux}")
      • case ${var} in

      Это, однако, не (если то, что вам нужно, – это один элемент с буквальным символом звездочки):

      • foo=( * )
    • Когда вы специально хотите разделить слово, например, перебирать токены в строке с разделителями пробелов (с отключенным отключением). Однако, если возможно, используйте массив.

    Вероятнее всего, самым важным отличием будет то, что каталог, в котором находится скрипт, имеет место в нем. В этом случае первая строка, без двойных кавычек, потерпит неудачу. Это было бы результатом «расщепления слов», которое bash делает для некотируемых строк.

    Предположим, что результатом dirname ${BASH_SOURCE[0]} является /home/jr/bin . Рассмотрим строку без кавычек:

     source $(dirname ${BASH_SOURCE[0]})/script.sh 

    В этом случае bash увидит команду:

     source /home/jr/bin/script.sh 

    После разделения слов source команда видит имя скрипта /home/j и аргумент скрипту r/bin/script.sh . Скорее всего, скрипта нет, и bash вернет сообщение об ошибке:

     bash: /bin/j: No such file or directory 

    Теперь рассмотрим, что происходит с двойными кавычками:

     source "$(dirname ${BASH_SOURCE[0]})/script.sh" 

    В этом случае команда source будет искать сценарий с именем /home/jr/bin/script.sh и попытаться его /home/jr/bin/script.sh .

    Для полноты рассмотрим одинарные кавычки:

     source '$(dirname ${BASH_SOURCE[0]})/script.sh' 

    В этом случае, в отличие от предыдущих двух, dirname никогда не выполняется. $(dirname ${BASH_SOURCE[0]})/script.sh команда попытается установить команду с литеральным именем $(dirname ${BASH_SOURCE[0]})/script.sh . Вероятно, нет такого файла, и bash выдаст сообщение об ошибке.

    Как bash рассматривает строки в двойных кавычках, подробно описывается в man bash :

      Enclosing characters in double quotes preserves the literal value of all characters within the quotes, with the exception of $, `, \, and, when history expansion is enabled, !. The characters $ and ` retain their special meaning within double quotes. The backslash retains its special meaning only when followed by one of the following characters: $, `, ", \, or <newline>. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ! appearing in double quotes is escaped using a backslash. The backslash preceding the ! is not removed. 
    Interesting Posts

    Как настроить nginx для динамического чтения папок, учетных записей пользователей / доменов?

    Как предполагается использовать sudo?

    Как заменить строку в файлах, используя звездочку в форме поиска

    Калибровка сенсорного экрана для приложений SDL?

    Получение списка сетей Wi-Fi рядом с адаптером в режиме AP

    Как предоставить права пользователя root?

    Легкий способ восстановления вашей ПАНЕЛИ

    Как отформатировать число с плавающей запятой с точностью до 2 значащих цифр в bash?

    Различные программы, не работающие после yum, устанавливают некоторые пакеты

    nohup размещает каждый процесс на одном ядре специально

    Как я могу заставить GRUB правильно настроить экран?

    Запуск backintime на диске

    Как установить клиент OpenVPN на RHEL 7.3?

    Лучший совет по решению для резервного копирования на NAS через WAN

    Простой сценарий оболочки с арифметической проблемой … ** дает мне проблемы

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