bash에서 eval을 사용하여 공백이 포함된 값을 변수에 할당하는 방법

bash에서 eval을 사용하여 공백이 포함된 값을 변수에 할당하는 방법

변수에 동적으로 값을 할당하고 싶습니다 eval. 다음 더미 예제가 작동합니다.

var_name="fruit"
var_value="orange"
eval $(echo $var_name=$var_value)
echo $fruit
orange

그러나 변수 값에 공백이 포함되어 있으면 eval큰따옴표 사이에 있어도 오류가 반환됩니다.$var_value

var_name="fruit"
var_value="blue orange"
eval $(echo $var_name="$var_value")
bash: orange : command not found

이 문제를 해결할 방법이 있나요?

답변1

평가판을 사용하지 말고 사용하십시오.declare

$ declare "$var_name=$var_value"
$ echo "fruit: >$fruit<"
fruit: >blue orange<

답변2

eval이 목적 으로 사용하지 마십시오 declare.

var_name="fruit"
var_value="blue orange"
declare "$var_name=$var_value"

첫 번째 단어뿐만 아니라 그 이후의 모든 항목이 =값으로 간주되기 때문에 단어 분할은 문제가 되지 않습니다 .declare

4.3 에서는 bash명명된 참조를 사용하면 이 작업이 좀 더 쉬워집니다.

$ declare -n var_name=fruit
$ var_name="blue orange"
$ echo $fruit
blue orange

할 수 있는작업 해 보도록 하겠습니다 eval. 하지만 여전히 그렇게 해서는 안됩니다 :) eval사용하는 것은 나쁜 습관입니다.

$ eval "$(printf "%q=%q" "$var_name" "$var_value")"

답변3

이를 사용하는 좋은 방법 은 테스트로 eval대체하는 것입니다 . 그리고 동일하게 작동합니다(특정 구현 에 의해 만들어진 확장을 제외하면 (예: 특정 조건에서) ).echoechoeval\xechobash

두 명령 모두 공백을 사용하여 인수를 연결합니다. 차이점은 다음과 같습니다.echo 보여주다동시에 결과eval 평가하다/설명하다쉘 코드의 결과.

그럼 어떤 쉘코드가 있는지 살펴보자

eval $(echo $var_name=$var_value)

평가하고 다음을 실행할 수 있습니다.

$ echo $(echo $var_name=$var_value)
fruit=blue orange

이것은 당신이 원하는 것이 아닙니다. 당신이 원하는 것은 다음과 같습니다.

fruit=$var_value

또한 $(echo ...)여기서 사용하는 것은 의미가 없습니다.

위의 내용을 출력하려면 다음을 실행해야 합니다.

$ echo "$var_name=\$var_value"
fruit=$var_value

그래서 간단하게 설명하면 다음과 같습니다.

eval "$var_name=\$var_value"

개별 배열 요소를 설정하는 데에도 사용할 수 있습니다.

var_name='myarray[23]'
var_value='something'
eval "$var_name=\$var_value"

다른 사람들이 말했듯이 코드가 구체적인지 신경 쓰지 않으면 bash다음을 사용할 수 있습니다 declare.

declare "$var_name=$var_value"

하지만 부작용도 있으니 주의하세요.

변수의 범위를 변수를 실행하는 함수로 제한합니다. 따라서 다음과 같은 상황에서는 사용할 수 없습니다.

setvar() {
  var_name=$1 var_value=$2
  declare "$var_name=$var_value"
}
setvar foo bar

foo이는 지역 변수를 선언하므로 setvar쓸모가 없습니다.

bash-4.2선언 -g하는 옵션이 추가되었습니다 .declare글로벌setvar하지만 그것은 우리가 원하는 것도 아닙니다.글로벌호출자가 함수인 경우 var는 다음과 같이 호출자의 var와 반대입니다.

setvar() {
  var_name=$1 var_value=$2
  declare -g "$var_name=$var_value"
}
foo() {
  local myvar
  setvar myvar 'some value'
  echo "1: $myvar"
}
foo
echo "2: $myvar"

그러면 다음이 출력됩니다.

1:
2: some value

또한 declare호출되는 동안 declare(실제로 bashKorn 쉘 내장 개념을 차용함 typeset) declare변수가 이미 설정된 경우 새 변수가 선언되지 않으며 할당이 수행되는 방식은 변수 유형에 따라 다릅니다.

예를 들어:

varname=foo
varvalue='([PATH=1000]=something)'
declare "$varname=$varvalue"

varname이전에 다음과 같이 선언된 경우스칼라,대량으로또는연관 배열.

또한 콘텐츠가 엄격하게 통제되지 않는 것 declare보다 더 안전하지는 않습니다 .eval$varname

예를 들어 , eval "$varname=\$varvalue"및 가 포함된 경우 declare "$varname=$varvalue"둘 다 시스템을 다시 시작합니다.$varnamea[$(reboot)1]

답변4

죽은 참조를 사용하십시오. 아포스트로피.
eval $(echo $var_name='$var_value')
그것은 나에게 효과적이었습니다.

관련 정보