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

Кажется, это называется Прокрутка:

$ synclient -l | grep Coasting
    CornerCoasting          = 0
    CoastingSpeed           = 20
    CoastingFriction        = 50

Настройте CoastingSpeed и CoastingFriction, чтобы установить скорость прокрутки и скорость остановки прокрутки.

1
07.03.2019, 22:02
3 ответа
  • Переменная без кавычек будет подвергаться расширению переменной, слову -разделяться (на пробелы, табуляции и новые строки по умолчанию ), а каждое сгенерированное слово, в свою очередь, будет подвергаться генерации имени файла (подстановке ).
  • Значение переменной, заключенной в двойные кавычки, будет расширено, но оболочка не будет -выполнять разбиение или подстановку слова в расширенном значении.
  • Переменная в одинарных кавычках вообще не раскрывалась.

Пример:

$ ls
script.sh
$ var='* *'
$ echo $var
script.sh script.sh
$ echo "$var"
* *
$ echo '$var'
$var

В вашем коде есть две проблемы, из-за которых значение в $extensionрасширяется до содержащегося в нем шаблона подстановки, а также приводит к преждевременному сопоставлению шаблона подстановки с именами файлов (вы хотите передать его как -— это ffmpeg -i, который выполняет внутреннее расширение глобуса ).

Первый — это вызов вашей функции:

runprintcommand ffmpeg -loglevel verbose -pattern_type glob -i ${extension} "$movieName" ;

Здесь ${extension}не заключено в кавычки, поэтому вы определенно получите (разбиение на слова -и )подстановку имени файла, происходящую по его значению.

Вторая проблема связана с самой функцией:

function runprintcommand() {
    echo "Command to run: (Note: '\\' escape character may not be printed)" ;
    echo "$*" ;
    $* ;    
}

Здесь вы используете $*без кавычек, что снова (разбивает значение на слова, а затем )расширяет глобус, даже если вы дважды -цитируете ${extension}в вызове функции.

Вместо простого $*используйте"$@"(с двойными кавычками ). Это будет расширено до отдельно цитируемых позиционных параметров функции.

В этом разница между "$@"и"$*":

  • "$*"— это одинарная двойная -строка в кавычках . Обычно это нельзя использовать для выполнения команды с аргументами.
  • "$@"— это список слов в двойных кавычках . Это можно использовать для выполнения команды с аргументами.
7
27.01.2020, 23:15

Поскольку я нашел альтернативный синтаксис для этого, я записываю его здесь.

Использование флага для отключения подстановки оболочки(http://tldp.org/LDP/abs/html/globbingref.html)предотвращает расширение:

set -f ; # disable glob (prevent expansion on '*.jpg' to turn in "1.jpg 2.jpg 3.jpg...")
ffmpeg -pattern_type glob -i ${extension} movie.mp4 ;
set +f ; # restore
0
27.01.2020, 23:15

Чтобы остановить подстановку оболочки, можно заключить расширение переменной в кавычки. (Это также останавливает разбиение слов, что обычно также является тем, что вам нужно ). Это, конечно, не мешает самой команде обрабатывать glob -как шаблоны. ffmpegделает это для -i, и то же самое делает, например. find -name. На примере последнего:

$ touch a.foo b.foo c.bar
$ extension=foo
$ set -x
$ find. -name "*.$extension"
+ find. -name '*.foo'
./b.foo
./a.foo

(Строка, начинающаяся с +, взята из set -xи показывает команду, которую оболочка действительно выполнила.)

Хотя с помощью set -fможно остановить подстановку, это также не помогает при разделении слов. Если бы переменная содержала пробелы, раскрытие без кавычек было бы нарушено даже с set -f.

1
27.01.2020, 23:15

Теги

Похожие вопросы