Командный литерал
Командный литерал — это строка, ограниченная обратными кавычками `, или процентный литерал %x. Во время выполнения он заменяется захваченным выводом команды, выполненной в подоболочке.
Для него действуют те же правила экранирования и интерполяции, что и для обычных строк.
Как и в случае с процентными строковыми литералами, допустимыми разделителями для %x являются круглые скобки (), квадратные скобки [], фигурные скобки {}, угловые скобки <> и вертикальные черты ||. За исключением вертикальных черт, все разделители могут быть вложенными; это означает, что начальный разделитель внутри строки экранирует следующий конечный разделитель.
Специальная переменная $? содержит код завершения команды в виде Process::Status. Она доступна только в той же области видимости, что и командный литерал.
`echo foo` # => "foo"
$?.success? # => true
Внутри компилятор преобразует командные литералы в вызовы метода верхнего уровня `(), передавая ему в качестве аргумента строковый литерал с командой: `echo #{argument}` и %x(echo #{argument}) преобразуются в `("echo #{argument}").
Вопросы безопасности
Хотя командные литералы могут быть полезны для простых скриптов, при интерполяции пользовательского ввода следует соблюдать особую осторожность, поскольку это может легко привести к внедрению команд.
user_input = "hello; rm -rf *"
`echo #{user_input}`
Эта команда запишет hello, а затем удалит все файлы и папки в текущем рабочем каталоге.
Чтобы избежать этого, обычно не следует использовать командные литералы с интерполированным пользовательским вводом. Process из стандартной библиотеки предоставляет безопасный способ передавать пользовательский ввод в качестве аргументов команды:
user_input = "hello; rm -rf *"
process = Process.new("echo", [user_input], output: Process::Redirect::Pipe)
process.output.gets_to_end # => "hello; rm -rf *"
process.wait.success? # => true
To the extent possible under law, the persons who contributed to this workhave waived
all copyright and related or neighboring rights to this workby associating CC0 with it.
https://crystal-lang.org/reference/1.2/syntax_and_semantics/literals/command.html