Например:
me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR
и используя \
escape-символ:
me$ FOO="BAR \* BAR"
me$ echo $FOO
BAR \* BAR
Я, очевидно, делаю что-то глупое.
Как мне получить вывод BAR * BAR
?
Цитирование при настройке $FOO
недостаточно. Вам также нужно заключить в кавычки переменную:
me$ FOO="BAR * BAR"
me$ echo "$FOO"
BAR * BAR
КОРОТКИЙ ОТВЕТ
Как уже говорили другие - вы всегда должны указывать переменные, чтобы избежать странного поведения. Поэтому используйте echo "$ foo" вместо echo $ foo .
ДОЛГО ОТВЕТ
Я думаю, что этот пример требует дальнейшего объяснения, потому что происходит больше, чем может показаться на первый взгляд.
Я вижу, в чём состоит ваше замешательство, потому что после запуска вашего первого примера вы, вероятно, подумали про себя, что оболочка явно делает:
Итак, из вашего первого примера:
После расширения параметра эквивалентно:
И после расширения имени файла эквивалентно:
И если вы просто наберете
echo BAR * BAR
в командной строке, вы увидите, что они эквивалентны.Так что вы, вероятно, подумали про себя: «если я уйду от *, я могу предотвратить расширение имени файла»
Итак, из вашего второго примера:
После расширения параметра должно быть эквивалентно:
И после расширения имени файла должно быть эквивалентно:
И если вы попытаетесь набрать «echo BAR \ * BAR» непосредственно в командной строке, он действительно выведет «BAR * BAR», потому что расширение имени файла предотвращается экранированием.
Так почему же использование $ foo не работает?
Это происходит потому, что происходит третье расширение - удаление цитаты. Из bash ручное удаление цитаты есть:
Итак, что происходит, когда вы вводите команду непосредственно в командной строке, escape-символ не является результатом предыдущего расширения, поэтому BASH удаляет его перед отправкой в команду echo, но во 2-м примере "\ *" был результат предыдущего расширения параметра, поэтому он НЕ удаляется. В результате эхо получает «\ *», и это то, что он печатает.
Обратите внимание на разницу между первым примером: «*» не входит в символы, которые будут удалены при удалении цитаты.
Я надеюсь это имеет смысл. В конце концов вывод тот же - просто используйте кавычки. Я просто подумал, что объясню, почему экранирование, которое по логике должно сработать, если в игру включены только расширение параметров и имен файлов, не работает.
Для полного объяснения расширений BASH обратитесь к:
http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions
источник
Я добавлю немного к этой старой теме.
Обычно вы бы использовали
Однако у меня были проблемы даже с этим синтаксисом. Рассмотрим следующий скрипт.
Эти
*
потребности должны быть переданы дословноcurl
, но возникают те же проблемы. Приведенный выше пример не будет работать (он будет расширен до имен файлов в текущем каталоге) и не будет работать\*
. Вы также не можете$curl_opts
заключить в кавычки, потому что это будет признано как единственная (недействительная) опцияcurl
.Поэтому я бы порекомендовал использовать
bash
переменную,$GLOBIGNORE
чтобы вообще предотвратить расширение имени файла, если он применяется к глобальному шаблону, или использоватьset -f
встроенный флаг.Применяя к вашему первоначальному примеру:
источник
SELECT * FROM etc.
, это единственный способ, который работает.источник
источник
Возможно, стоит привыкнуть использовать
printf
вместоecho
командной строки.В этом примере это не дает большой выгоды, но может быть более полезным при более сложном выводе.
источник