2015-03-27 3 views
0

У меня есть следующий сценарий, где переменные ($1) внутри переменной ($ARG) должен быть заменен:переменной внутри переменной в случае Баш

#! /bin/bash 

ARGS="-enable-kvm -hda /root/"$1".raw -display vnc=:"$1"" 

do_start() 
{ 
      echo $ARGS 
} 

case "$1" in 
    start) 
     for i in {1..5}; do 
      do_start $i 
     done 
     ;; 
esac 

Однако, если я выполнить скрипт с ./scriptname start затем выход следующей :

-enable-kvm -hda /root/start.raw -display vnc=:start 
-enable-kvm -hda /root/start.raw -display vnc=:start 
-enable-kvm -hda /root/start.raw -display vnc=:start 
-enable-kvm -hda /root/start.raw -display vnc=:start 
-enable-kvm -hda /root/start.raw -display vnc=:start 

Как заменить переменную внутреннюю переменную в случае bash?

+0

место двойные кавычки '$ ARGS' в определении' do_start() ' – Pankrates

+1

Или, скорее, нет. См. BashFAQ # 50: http://mywiki.wooledge.org/BashFAQ/050 –

ответ

1

Вы можете это исправить, объявив ARGS локально и фиксируя ваших котировки

do_start() 
{ 
    ARGS="-enable-kvm -hda /root/$1.raw -display vnc=:"$1" 
    echo "$ARGS" 
} 

Обратите внимание, что в зависимости от формы ваших аргументов, как ожидается, принять этот подход склонен к ошибкам и более надежный способ показан @Charles Duffy

+0

Это не делает команду фактически _work_, когда '$ 1' содержит пробелы, символы glob и т. Д. (И какова была точка цитирования' $ 1' расширение в первую очередь, если бы оно не могло?) –

+0

согласился, и совсем другое решение, вероятно, - путь.Я просто показывал, как исправить это в текущей области и определении. – Pankrates

+0

Еще одно незначительное примечание, кстати - 'ARGS' на самом деле объявляется глобальным здесь, хотя это объявление находится внутри функции. Использование 'local' или' declare' (внутри функции) сделает его _actually_ local. –

4

Использование переменной массива, в BashFAQ #50, определяется внутри контекст, в котором вы знаете значение для $i:

#!/bin/bash 

do_start() { 
    local -a args=(-enable-kvm -hda "/root/$1.raw" -display vnc=:"$1") 
    printf '%q ' "${args[@]}"; echo # print args for the VM in shell-quoted form 
    qemu "${args[@]}"    # actually start the VM 
} 

case "$1" in 
    start) 
    for ((i=1; i<=5; i++)); do 
     do_start "$i" 
    done 
    ;; 
esac 

Обратите внимание, что это не будет печатать литеральные кавычки, но ему не требуется (и, в действительности, не должно: Содержимое, напечатанное echo, является данными; котировки, которые вам нужны, - синтаксические, а не данные; поэтому, если напечатанные цитаты echo $args, это будет означать, что qemu $args не будет работать корректно по причинам, указанным в BashFAQ 50, как указано выше, что я настоятельно рекомендую прочитать).

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

$ ./run-script start 
-enable-kvm -hda /root/1.raw -display vnc=:1 
-enable-kvm -hda /root/2.raw -display vnc=:2 
-enable-kvm -hda /root/3.raw -display vnc=:3 
-enable-kvm -hda /root/4.raw -display vnc=:4 
-enable-kvm -hda /root/4.raw -display vnc=:5 

Экранирования обратного косой черты перед пространством имеет тот же эффект, поставив буквенные кавычки содержания: Он по-прежнему гарантирует, что имя файл рассматривается как одна строки.


Если после этого вы хотите запустить QEMU с аргументами:

qemu "${args[@]}" 

... будет делать трюк правильно.

-1

Сначала вам нужно сменить двойные кавычки на одиночные кавычки, чтобы $1 не исчезли при первоначальном назначении. Затем, чтобы оценить его в то время, когда вы этого хотите, вы можете использовать команду eval.

#! /bin/bash 

args=' -enable-kvm -hda "/root/$1.raw" -display vnc=:"$1" ' 

do_start() 
{ 
    #echo "1=$1" 
    eval "echo $args" 
} 

case "$1" in 
    start) 
     for i in {1..5}; do 
      do_start $i 
     done 
     ;; 
esac 

Результаты:

$ ./foo.sh start 
-enable-kvm -hda /root/1.raw -display vnc=:1 
-enable-kvm -hda /root/2.raw -display vnc=:2 
-enable-kvm -hda /root/3.raw -display vnc=:3 
-enable-kvm -hda /root/4.raw -display vnc=:4 
-enable-kvm -hda /root/5.raw -display vnc=:5 
+0

Опасная территория с использованием eval ... – arco444

+0

Зачем нужен лишний риск для безопасности? http://mywiki.wooledge.org/BashFAQ/048 –

+0

... если вы позволите ненадежным пользователям установить номера портов, например, рассмотрите ход событий, если был указан номер порта, содержащий «123 $ (rm -rf.)) ' –

Смежные вопросы