Предположение с двойными кавычками, одинарными кавычками и без кавычек

в bash :

использование двойных кавычек

echo "*" #Globbing is never done
echo "$variable" # Variable expansion is always done
echo "$(command)" # command expansion is always done

использование одинарных кавычек

echo '*' #Globbing is never done 
echo '$variable' # Variable expansion is never done
echo '$(command)' # command expansion is never done

без кавычек

echo * #Globbing always done.
echo $variable; # Variable expansion is always done
echo $(command) # command expansion is always done

будет ли это применяться для всех команд?

6 ответов


похоже, вы ищете исключения, и я предполагаю, что у вас есть некоторые на уме. Я собираюсь сделать предположение, что set -f/set -o noglob исключаются из этого дела?

при использовании dd command, globbing не произойдет, даже если без кавычек.

$ ls *.txt
blah.txt  file1.txt  file2.txt  file.txt  logfile.txt
$ dd if=*.txt of=glob.txt
dd: failed to open ‘*.txt’: No such file or directory

опровержение и ложные срабатывания

вот несколько примеров, которые odd, но следовать расширение

variable='2010-09-08 12:34:56' echo "$variable" | xargs date +%s -d date: extra operand '12:34:56'

дополнительный операнд показывает, что происходит расширение переменной, вы теряете кавычки в трубе. $ date +%s -d 2010-09-08 12:34:56 date: extra operand ‘12:34:56’

это также происходит, если вы создаете скрипт echo а затем разверните цитируемую переменную во время передачи. Он расширяется и работает, как и ожидалось. Итак, проблема не в xargs, а в вашем расширении перед трубой, которая является нормальной.

  1. Eval... эвалс цель сделать расширение его args до запуска команды. Расширение также происходит с bash -c, за исключением одного аргумента. Итак, опять же, это не проблема расширения, а проблема использования команды.

cmd='printf "%s\n" "$(date -d "$variable" +%c)"' bash -c $cmd

работает так же, как расширенная версия

$ bash -c printf "%s\n" "$(date -d "$variable" +%c)" printf: usage: printf [-v var] format [arguments]

  1. мне очень понравилось Hauri долларов'...' и."$ ..- информация...однако мы говорим не об этом. Они на самом деле ведут себя как человек bash Пейдж говорит, что должны. $ "так же отличается от", как (()) от $(())

  2. Я был в восторге от этого, так что... $ ls mclark.txt qt sign_in.txt skel.bash $ zip m*t.zip *t $ ls *.zip m*t.zip

однако это тоже неправильно - splat расширяется, но при отсутствии соответствия zip использует его как литерал. Я нашел несколько команд, которые сделали это, но если было совпадение (я добавил my.zip позже) он использует сопоставленное расширение (ошибка была брошена, B/C my.zip был текстовым файлом для целей тестирования).


есть несколько сил на месте. В общем, вы можете предположить, что одинарные кавычки скрывают содержимое от расширения bash. Двойные кавычки-это группа ценностей, которые могут иметь белого пространства, так что баш видит их как одно логическое устройство, а также отключить подстановку. Есть много предостережений...

заключая символы в двойные кавычки сохраняет буквальное значение все символы в кавычках, за исключением$,', \ и, когда расширение истории включен,!. Символы $ и ' сохранить их особый смысл в двойных кавычках. Обратная косая черта сохраняется свое особое значение только при соблюдении одного из следующих символы: $, ', ", \, или . Двойная цитата может быть процитирована в двойных кавычках, предшествуя ему обратной косой чертой. Если включено, расширение истории будет выполнено, если ! появившись в двойном кавычки экранируются с помощью обратной косой черты. Обратная косая черта перед передачей ! не является удаленный.

см. раздел цитирование из man bash

этот пример ниже, будет либо запутать вас дальше или сделать его более ясным.

$ echo "*test*"
*test*

$ echo '*test*'
*test*

$ msg=$(echo '*test*')
$ echo '$msg'
$msg

$ echo "$msg"
*test*

$ echo $msg
speedtest test1 test2 test3 test4 test5 testdir

обратите внимание, что если бы не было совпадений, он бы напечатал *test* не пустая строка, как прокомментировал Хастур.

некоторые другие интересные лакомые кусочки

обратите внимание, что это не работает

$ echo 'single quotes don\'t escape'

но это работает

$ echo "\"double quotes\" escape"

но вы можете использовать одно в другом без побег

$ echo '"' "'"

короткий ответ: да

этот asumptions являются в основном правда, всегда!

variable='2010-09-08 12:34:56' 
vname=variable
date -d "$variable" +%s
1283942096

date -d "${!vname}" +%s
1283942096

date -d $variable +%s
date: extra operand '+%s'
Try 'date --help' for more information.

date -d '$variable' +%s
date: invalid date '$variable'

date -d ${!vname} +%s
date: extra operand '+%s'
Try 'date --help' for more information.

но

  1. некоторые команды, такие как xargs работа именно о расширения и распределения параметров.

    echo "$variable" | xargs date +%s -d
    date: extra operand '12:34:56'
    Try 'date --help' for more information.
    

    вы должны использовать -0 arg to xargs:

    echo "$variable" | xargs -0 date +%s -d
    1283942096
    
  2. Builtin команды могут использовать args по-разному, особенно eval:

    cmd='printf "%s\n" $(date -d "$variable" +%c)'
    eval $cmd
    Wed
    Sep
    8
    12:34:56
    2010
    
    cmd='printf "%s\n" "$(date -d "$variable" +%c)"'
    eval "$cmd"
    Wed Sep  8 12:34:56 2010
    
    eval $cmd
    Wed Sep  8 12:34:56 2010
    
    bash -c "$cmd"
    Mon May 16 00:00:00 2016
    
    bash -c $cmd
    printf: usage: printf [-v var] format [arguments]
    
  3. синтаксис смешной вещи под bash не ограничивается "..", '..' и ${}

    • $'...' позволяет печатать специальные символы, но не разворачивать переменные:

      echo $'This\tis\ta string containing ${variable}'
      This    is  a string containing ${variable}
      
    • Backticks: для совместимости, backtick всегда поддержаны. Если не очень читаемый, вы можете увидеть это в некоторых скриптах:

      echo `date +%c -d "${!vname}"`
      Wed Sep 8 12:34:56 2010
      
    • Syntaxe $"..." может использоваться для локализации:

      export TEXTDOMAIN=bash
      export LANG=fr_CH.utf-8
      echo $"Running"
      En cours d'exécution
      

Если ничего не соответствует *.хтх пока a.txt файл mv a.txt *.xtx вы получите неожиданный результат. То же самое относится и к другим вещам, таким как cp, и даже это рассматривает его как цитируемое:

$ ls *.xtx
/bin/ls: cannot access *.xtx: No such file or directory
$ echo "A" > *.xtx
$ ls *.xtx
*.xtx
$

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


будет ли это применяться для всех команд?

Да.

из справочных руководств Bash:

3.1.2.2 Одинарные Кавычки

заключая символы в одинарные кавычки (') сохраняет буквальное значение каждого символа в кавычках. Одна цитата не может происходят между одинарными кавычками, даже если им предшествует обратная косая черта.

и

3.1.2.3 Двойные Кавычки

содержащие символы в двойные кавычки (") сохраняет буквальное значение всех символов в кавычках, за исключением $, ',\, и, когда расширение истории включено,!. Характер $ и ' сохраняют свое особое значение в двойных кавычках (см. Оболочки Расширения). Обратная косая черта сохраняет свое особое значение только когда за ним следует один из следующих символов:$, `, ", \, или строки. В двойных кавычках обратные косые черты, за которыми следует одна из этих символов удаляются. Обратные косые черты предшествующих символов без особого смысла остаются немодифицированными. Двойная цитата может быть цитируется в двойных кавычках, предшествуя ему обратной косой чертой. Если включено, расширение истории будет выполнено, если только ! появляющийся в двойных кавычках экранируется с помощью обратной косой черты. Обратная косая черта, предшествующая то ! не удаляется.

специальные параметры * и @ имеют особое значение, когда в двойной котировки (см. Расширение Параметров Оболочки).


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

чтение раздела "цитирование" man-страниц также интересно. Это раздел из страницы bash man, касающийся одинарных и двойных кавычек: (что в значительной степени совпадает с содержанием справочного руководства)

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

заключая символы в двойные кавычки сохраняет буквальное значение все символы в кавычках, за исключением$,`, \ и, когда расширение истории включено,!. Символы $ и ` сохраняют свое особое значение в двойных кавычках. Обратная косая черта сохраняет свое особое значение только при соблюдении одного из следующий символы: $, `, ", \, или . Двойная цитата может быть цитируется в двойных кавычках, предшествуя ему обратной косой чертой. Если включено, расширение истории будет выполнено, если только ! появление в двойных кавычках экранируется с помощью обратной косой черты. Этот "\"в начале ! не удаляется.