Выполнение оболочки BASH из строки с позиционными параметрами

Когда я пытаюсь запустить приведенный ниже код, оболочка заменяет (потому что они не определены как переменные bash) $4 и $2 пробелами. Мой вопрос заключается в том, как мне не дать bash попытаться оценить позиционные параметры для awk как его переменных? Я попытался поместить двойные и одинарные кавычки вокруг позиционных параметров, однако, это не помешало bash интерпретировать их как локальные переменные вместо строк.

Это то, что возвращается, когда я echo "$x$i$y"

date -r /root/capture/capture11.mp4 | awk '{print }' | awk -F":" '/1/ {print }'

Код:

#!/bin/sh
i=$(cat /etc/hour.conf)
x="date -r /root/capture/capture"
y=".mp4 | awk '{print $4}' | awk -F\":\" '/1/ {print $2}'"
$x$i$y

Любая помощь будет принята с благодарностью!

3 ответа

Решение

$4 удваивается в кавычках. Хотя есть одинарные кавычки, они включены в двойные кавычки. Таким образом, одинарные кавычки являются лишь частью строки, и это не будет сохранять буквальное значение $, Таким образом, вы можете избежать $:

y=".mp4 | awk '{print \$4}' | awk -F\":\" '/1/ {print \$2}'"

Или используйте одинарные кавычки вокруг всей части:

y='.mp4 | awk "{print \$4}" | awk -F':' "/1/ {print \$2}"'

Переменные интерполируются внутри двойных кавычек. Используйте одинарные кавычки или избегайте их как \$2,

Однако способ, которым вы пытаетесь разделить команду на отдельные переменные, не будет работать. Вместо этого вы должны использовать функцию. Тогда вам не нужно разбираться с кавычками и вообще убегать. Например:

do_thing() {
    date -r "/root/capture/capture$1.mp4" | awk '{print $4}' | awk -F':' '/1/ {print $2}'
}

do_thing "$(cat /etc/hour.conf)"

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

Это работает (но ужасно):

$ x=prin; y="tf %f\\n"; z=" 123456789"
$ $x$y$z
123456789.000000

Это не делает то, что вы хотите:

$ z='"foo bar"'; printf $y ; echo
"foo

Вместо одного аргумента foo bar, printf получает два аргумента "foo а также bar",

Другие вопросы по тегам