我读过许多关于shell引用和文件名中空格的其他问题,这些建议在这种情况下似乎行不通。
Putting一个带有字符串的变量,在另一个变量un-中包含一个转义空间,它将在最终输出中转义空间。
此脚本从用户输入和硬编码值组合一个命令,显示存储在变量中的命令,然后运行它:
#!/bin/bash
memory="4096"
cpus="--cpu=host --vcpus=2"
type="--os-type=linux"
variant="--os-variant=debiantesting"
graphics="--graphics spice"
network="--network bridge=vmbr0"
disk="--disk path=/dev/$chosen_vg_name/$lv_name"
#This line is the problem:
location="--cdrom /share/media/Linux\ ISO/debian11-server.iso";
# Run the command based on the supplied variable values:
install_cmd="virt-install -n $vm_name --memory $memory $cpus $type $variant $disk $location $graphics $network";
printf "$install_cmd\n";
$install_cmd;
exit 0;我知道发生了什么。location变量中文件路径中的空格在添加到install_cmd变量时不会被转义,因此virt-install命令认为ISO/debian11-server.iso是一个未知的参数。
我也尝试过:
location='--cdrom /share/media/Linux ISO/debian11-server.iso';
location="--cdrom "/share/media/Linux ISO/debian11-server.iso"";
location='--cdrom /share/media/Linux\ ISO/debian11-server.iso';
location='--cdrom /share/media/Linux\\ ISO/debian11-server.iso';
location="--cdrom /share/media/Linux\\ ISO/debian11-server.iso";location变量中路径名中的空格转义的正确语法是什么,以便当<#>stays被添加到包含最终命令的变量中时,location转义了?
发布于 2022-02-25 08:00:26
这一点:
$install_cmd;
是调用split+glob运算符对$install_cmd的内容,并希望得到的单词形成一个简单的命令的预期参数,这几乎没有意义。
在这里,您可能希望用bash语言以连接的部分构建代码,并最终告诉shell用eval来解释它,这很危险,因为很难避免命令注入漏洞。这必须是:
memory=4096
cpus='--cpu=host --vcpus=2'
type='--os-type=linux'
variant='--os-variant=debiantesting'
graphics='--graphics spice'
network='--network bridge=vmbr0'
disk='--disk "path=/dev/$chosen_vg_name/$lv_name"'
location='--cdrom "/share/media/Linux ISO/debian11-server.iso"'
install_cmd="virt-install -n $vm_name --memory $memory $cpus $type $variant $disk $location $graphics $network"
printf >&2 'Interpreting: %s\n' "$install_cmd"
eval "(PS4='Running: '; set -o xtrace; $install_cmd)"(请参见$chosen_vg_name/$lv_name在这种情况下是如何扩展到eval上的)。
上面,我添加了一些Interpreting:和Running:输出,以显示shell将通过eval解释哪些代码以及将运行什么结果命令。运行将使用一些execve("/path/to/virt-install", ["virt-install", "-n"...], environ)系统调用,然而,bash's xtrace输出将呈现为某些shell代码,如果由bash解释,这些代码将导致相同的系统调用。
或者使用可以容纳多个参数的变量类型构建简单命令的参数:数组,并调用由该数组元素组成的命令:
memory=4096
cpus=(--cpu=host --vcpus=2)
type=(--os-type=linux)
variant=(--os-variant=debiantesting)
graphics=(--graphics spice)
network=(--network bridge=vmbr0)
disk=(--disk "path=/dev/$chosen_vg_name/$lv_name")
location=(--cdrom '/share/media/Linux ISO/debian11-server.iso')
install_cmd=(
virt-install -n "$vm_name" --memory "$memory"
"${cpus[@]}" "${type[@]}" "${variant[@]}" "${disk[@]}"
"${location[@]}" "${graphics[@]}" "${network[@]}"
)
(PS4='Running: '; set -o xtrace; "${install_cmd[@]}")(在那里,$chosen_vg_name/$lv_name是在分配给$disk数组时展开的)。
还请记住,printf的第一个参数是格式。它不应该包含可变数据。
没有对shell代码的双重解释,这避免了命令注入漏洞的风险,因此更可取。
https://unix.stackexchange.com/questions/692078
复制相似问题