공백이 포함된 경로 이름 변수를 사용하여 최종 명령을 중단하지 않고 새 명령 변수를 생성하시겠습니까?

공백이 포함된 경로 이름 변수를 사용하여 최종 명령을 중단하지 않고 새 명령 변수를 생성하시겠습니까?

쉘 인용 및 파일 이름의 공백에 대한 다른 많은 질문을 읽었으며 이러한 제안은 이 경우 작동하지 않는 것 같습니다.

이스케이프된 공백이 있는 문자열이 포함된 변수를 다른 변수에 넣으면 최종 출력에서 ​​공백이 이스케이프 해제됩니다.

스크립트는 사용자 입력 및 하드 코딩된 값을 기반으로 명령을 조합하고 변수에 저장된 명령을 표시한 후 실행합니다.

#!/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-installISO/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변수 경로 이름에서 공백을 이스케이프하는 올바른 구문은 무엇입니까?아직도 탈출하다location최종 명령이 포함된 변수에 언제 추가되나요?

답변1

저것:

$install_cmd;

무언가에 대해 Split+Glob 연산자를 호출 하고 결과 단어가 간단한 명령의 예상 매개변수를 형성할 것이라고 기대하는 $install_cmd것은 거의 의미가 없습니다 .

bash여기에서는 연결된 섹션의 언어로 코드를 작성하고 궁극적으로 쉘이 이를 해석하도록 지시 할 수 있습니다 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:과 출력을 추가했습니다 . 실행은 일부 시스템 호출을 사용하여 수행되지만 출력 은 이를 bash에서 해석하면 동일한 시스템 호출이 발생하는 일부 셸 코드로 렌더링됩니다.Running:evalexecve("/path/to/virt-install", ["virt-install", "-n"...], environ)bashxtrace


또는 여러 매개변수를 보유할 수 있는 변수 유형을 사용하여 간단한 명령(배열)의 매개변수를 구축하고 해당 배열의 요소로 구성된 명령을 호출합니다.

  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는 다음과 같습니다.체재. 변경 가능한 데이터가 포함되어서는 안 됩니다.

쉘 코드에는 이중 해석이 없으므로 명령 주입 취약점의 위험을 방지하므로 바람직합니다.

관련 정보