동일한 파일에 중첩된 변수가 포함된 파일에서 변수 읽기

동일한 파일에 중첩된 변수가 포함된 파일에서 변수 읽기

당신이 잘 지내기를 바랍니다.

조금 혼란스러워요 ...

다음과 같은 파일이 있습니다.

var1:value1
var2:value2
...
varn:blabla/$var2/blabla

파일을 읽을 때 문제가 없습니다. 모든 줄을 가져오고 모든 변수를 인스턴스화할 수 있습니다.

간단히 말해서, 이것이 제가 함수에서 하는 일입니다:

while IFS=":" read -r f1 f2
do
    if [ ! -z $f1 ] && [ ! -z $f2 ]; then

        f2=eval $f2
        export $f1=$f2

    fi
done < $fileName

제외하고는 잘 작동합니다varn...

알겠어요blabla/$var2/blabla

대신에:

blabla/value2/blabla...

이로 인해 Varn이 경로로 간주되므로 내 스크립트가 명령을 시작할 수 없습니다.

실제 매개변수 파일은 다음과 같습니다.

<deleted some parameters>
version:1.7.0

MongoInstall:/apps/deliverable_${version}/mongo

실행하는 동안 다음을 얻습니다.

+ export 'MongoInstall=/ec/local/nasstat/apps/deliverable_${version}/mongo'
+ MongoInstall='/ec/local/nasstat/apps/deliverable_${version}/mongo'

...

그런 다음...

+ '/apps/deliverable_${version}/mongo/installation_mongo_1.7.0.sh' env stop
./mongotransfer.sh: line 54: /apps/deliverable_${version}/mongo/installation_mongo_1.7.0.sh: No such file or directory

내가 얻고 싶은 것은 다음과 같습니다.

/apps/deliverable_1.7.0/mongo/installation_mongo_1.7.0.sh

감사해요

답변1

로 전환할 수 있는 옵션이 있는 경우 zsh다음을 수행할 수 있습니다.

set -o extendedglob -o nounset
unset MongoInstall
while IFS= read -r line; do
  [[ $line = (#b)([[:IDENT:]]##):(*) ]] &&
    : ${(P)match[1]::=${(e)match[2]}}
done < parameter-file
printf 'MongoInstall="%s"\n' $MongoInstall

거기에서 코드를 즐겁게 평가하는 e만큼 이 플래그를 주의하십시오 . eval예를 들어, 매개변수 파일에 가 포함되어 있으면 var=$(reboot)다시 시작됩니다.

더 안전한 접근 방식은 확장을 수동으로 수행하는 것입니다.

MongoInstall=$(
  perl -wlne '
    if (/^(\w+):(.*)/) {
      $var = $1; $value = $2;
      $value =~ s/\$\{(\w+)\}/$var{$1}/g;
      $var{$var} = $value;
    }
    END {print $var{MongoInstall}}' < parameter-file
)

또는 다음과 같습니다 zsh:

set -o extendedglob -o nounset
typeset -A vars
while IFS= read -r line; do
  if [[ $line = (#b)([[:IDENT:]]##):(*) ]]; then
    var=$match[1] value=$match[2]
    value=${value//(#b)\${([[:IDENT:]]##)}/$vars[$match[1]]}
    vars[$var]=$value
  fi
done < parameter-file
print -r -- $vars[MongoInstall]

에서는 bash아마도 다음과 같이 작성하려고 할 것입니다.

while IFS=: read -r f1 f2
do
  if [ -n "$f1" ] && [ -n "$f2" ]; then
    eval "$f1=\"$f2\""
  fi
done < parameter-file

가상의 줄은 s를 parameter-file포함하지 않으며 "로 끝나지 않습니다 :. 일반적으로 $f1유효한 변수 이름이나 <contents-of-f1>="<contents-of-f2>"유효한 코드가 포함되어 있는지 확인하려고 시도하지 않습니다 .bash

귀하의 코드에서는 의미가 없으며 해당 환경에서 (인용되지 않은 분할 + glob에 따라) f2=eval $f2저장된 명령을 실행하려고합니다 .$f2f2=eval

export이러한 변수를 사용해도 나중에 실행되는 명령의 환경을 오염시키는 것 외에는 아무런 효과가 없습니다.

따옴표 없이 매개변수를 확장하는 것도 올바르지 않습니다 bash. 특히 [ -z( [ ! -z x ]is [ -n x ]btw ).

관련 정보