我有一个以下脚本,其中变量($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 :(得分: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