업데이트된 질문

업데이트된 질문

명령에 전달되어야 하는 매개변수를 동적으로 변경할 수 있는 스크립트가 있습니다(mkv 속성 편집기이 경우). 다음 예제 스크립트를 고려해보세요.

#!/bin/bash

LANG_NAME="eng lish"

MYSETTINGS=()
MYSETTINGS+=("--edit 1")
MYSETTINGS+=("--set \"language=${LANG_NAME}\"")

echo "Count = ${#MYSETTINGS[@]}" # should be 2
set -x # enable to see the invoked command
mkvpropedit ${MYSETTINGS[@]}

이것을 실행하면 콘솔에 들어갑니다.

[~] # ./test.sh
Count = 2
+ mkvpropedit --edit 1 --set '"language=eng' 'lish"'

하지만제 생각에는작은따옴표 없는 최종 호출mkv 속성 편집기,이와 같이:

+ mkvpropedit --edit 1 --set "language=eng lish"

나는 또한 배열을 변수로 에코하려고 시도했고 에코는 작은 따옴표를 제거했지만 변수를 다음과 같이 사용할 수 없었습니다.mkv 속성 편집기작은 따옴표가 다시 나타나기 때문에 ...

물론 변수가 단일 단어(예: )인 경우에도 스크립트가 작동해야 합니다 LANG_NAME="eng". 내 Bash 버전은 3.2입니다(실제로 Busybox).

업데이트된 질문

아마도 아래 예가 내가 하려는 일을 더 잘 설명할 것입니다. 복사할 수 있도록 일부 이름을 변경했습니다.

#!/bin/bash

TITLE_NAME="my title"

MYSETTINGS=()
MYSETTINGS+=("--edit track:2")
MYSETTINGS+=("--set \"name=${TITLE_NAME}\"")

set -x
mkvpropedit file.mkv ${MYSETTINGS[@]} 

이 스크립트를 실행하면 다음과 같은 결과가 나타납니다(잘못된 참조로 인해).

# ./test.sh
+ mkvpropedit file.mkv --edit track:2 --set '"name=my' 'title"'
Error: More than one file name has been given ('file.mkv' and 'title"').

수동으로 실행하는 경우:

# mkvpropedit file.mkv --edit track:2 --set "name=my title"
The file is being analyzed.
The changes are written to the file.
Done.

그래서 이것은 제가 전화하고 싶은 참고 문제입니다.mkv 속성 편집기스크립트에서 배열을 사용합니다.

사용평가하다

현재 작동하는 것으로 보이는 것은 mkvpropeditand 를 file.mkv배열에 삽입하고 결국 호출하는 것입니다. eval "${MYSETTINGS[@]}"하지만 그만한 가치가 있고 안전한가요? 아니요eval 사악한(말장난)?

TITLE_NAME="my title"

MYSETTINGS=(mkvpropedit file.mkv)
MYSETTINGS+=("--edit track:2")
MYSETTINGS+=("--set \"name=${TITLE_NAME}\"")

set -x
eval "${MYSETTINGS[@]}"

반품:

# ./test.sh
+ eval mkvpropedit file.mkv '--edit track:2' '--set "name=my title"'
++ mkvpropedit file.mkv --edit track:2 --set 'name=my title'
The file is being analyzed.
The changes are written to the file.
Done.

답변1

작은따옴표 없음- 이는 를 사용할 때 변수 내용에 대한 쉘의 명시적인 표현일 뿐입니다 set -x. declare -p한 번에 하나의 배열 요소를 사용하거나 인쇄하여 배열 요소를 보는지 확인할 수 있습니다 .

LANG_NAME="eng lish"

MYSETTINGS=()
MYSETTINGS+=("--edit 1")
MYSETTINGS+=("--set \"language=${LANG_NAME}\"")

그 다음에

$ declare -p MYSETTINGS
declare -a MYSETTINGS=([0]="--edit 1" [1]="--set \"language=eng lish\"")

또는

$ printf '>>>%s<<<\n' "${MYSETTINGS[@]}"
>>>--edit 1<<<
>>>--set "language=eng lish"<<<

하지만--edit, 1, --set, 및 를 language=eng lish별도의 토큰으로 명령에 전달하려고 할 것입니다.

  1. 배열 구성 중에 공백이나 전역 문자가 포함된 모든 토큰을 인용하십시오 language="${LANG_NAME}"."language=${LANG_NAME}"

  2. 배열 확장 사용 시 큰따옴표(단어 분할 및 파일 이름 생성 방지 - "split+glob"이라고도 함)

그래서

LANG_NAME="eng lish"

MYSETTINGS=()
MYSETTINGS+=(--edit 1)
MYSETTINGS+=(--set language="${LANG_NAME}")

그 다음에

mkvpropedit file.mkv "${MYSETTINGS[@]}"

큰 따옴표 는 추가 토큰화 없이 각 요소를 별도의 단어로 "${name[@]}"확장하므로 변수 확장 주위에 큰 따옴표를 추가할 필요가 없습니다. 추가 따옴표는 문자 그대로 명령에 전달됩니다.name\"name=${TITLE_NAME}\"

당신은 또한 볼 수 있습니다변수에 저장된 명령을 어떻게 실행할 수 있나요?

답변2

[잘못된] 달러 기호를 탈출하십시오:

MYSETTINGS+=("--set name=\${TITLE_NAME}")

또는:

MYSETTINGS+=('--set name=${TITLE_NAME}')
mkvpropedit file.mkv ${MYSETTINGS[@]}

명령 실행 시 확장에 사용되는 변수

./test.sh
+ mkvpropedit file.mkv --edit track:2 --set 'name=${TITLE_NAME}'
The file is being analyzed.
The changes are written to the file.
Done.

관련 정보