在bash的情况下变量内部变量

时间:2015-03-27 17:02:37

标签: bash

我有一个以下脚本,其中变量($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的情况下如何用变量替换变量?

3 个答案:

答案 0 :(得分: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

请注意,这不会打印文字引号,但不需要(事实上,不应该:{{1}打印的内容}是数据;您关注的引号是语法,而不是数据;因此如果echo打印引号,则表示echo $args无法正常工作BashFAQ 50中给出的理由 - 如上所述 - 我强烈建议阅读。

对于需要引用的内容,引用仍然是正确的,但对于整数值,情况永远不会如此。

qemu $args

在空格之前转义反斜杠与在内容周围放置文字引号具有相同的效果:它仍然确保文件名被视为单个字符串。


如果你想用你的参数运行qemu:

$ ./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

...会正确地做到这一点。

答案 1 :(得分:1)

您可以通过在本地声明ARGS并修复报价

来解决此问题
do_start()
{
    ARGS="-enable-kvm -hda /root/$1.raw -display vnc=:"$1"
    echo "$ARGS"
}

请注意,根据您的参数预期采用的形式,这种方法容易出错,而且@Charles Duffy会显示更强大的方法

答案 2 :(得分:-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