나는 당신의 의미를 취할 때, 이러한 답변 중 어느 것이 맞는지 믿지 않습니다. eval
어떤 식으로도 필요하지 않으며 변수를 두 번 평가해야 할 필요도 없습니다.
사실 @Gilles는 매우 가까워 지지만 값을 무시하는 문제와 값이 두 번 이상 필요한 경우 어떻게 사용해야하는지 다루지 않습니다. 결국 템플릿을 두 번 이상 사용해야합니까?
나는 그것이 당신이 그들을 평가하는 순서가 중요하다고 생각합니다. 다음을 고려하세요:
상단
여기에 몇 가지 기본값을 설정하고 호출 될 때 인쇄 할 준비를합니다.
#!/bin/sh
_top_of_script_pr() (
IFS="$nl" ; set -f #only split at newlines and don't expand paths
printf %s\\n ${strings}
) 3<<-TEMPLATES
${nl=
}
${PLACE:="your mother's house"}
${EVENT:="the unspeakable."}
${ACTION:="heroin"}
${RESULT:="succeed."}
${strings:="
I went to ${PLACE} and saw ${EVENT}
If you do ${ACTION} you will ${RESULT}
"}
#END
TEMPLATES
가운데
여기에서 결과에 따라 인쇄 기능을 호출 할 다른 기능을 정의합니다.
EVENT="Disney on Ice."
_more_important_function() { #...some logic...
[ $((1+one)) -ne 2 ] && ACTION="remedial mathematics"
_top_of_script_pr
}
_less_important_function() { #...more logic...
one=2
: "${ACTION:="calligraphy"}"
_top_of_script_pr
}
바닥
이제 모든 설정이 완료되었으므로 여기에서 결과를 실행하고 가져올 수 있습니다.
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
결과
잠시 이유를 살펴 보 겠지만 위의 내용을 실행하면 다음과 같은 결과가 나타납니다.
_less_important_function()'s
첫 실행 :
나는 당신의 어머니의 집에 가서 Disney on Ice를 보았습니다 .
당신이 경우에 서예를 당신은 성공합니다.
그때 _more_important_function():
나는 묘지에 가서 Disney on Ice를 보았습니다.
당신이 경우에 치료하는 수학을 당신은 성공합니다.
_less_important_function()
다시:
나는 묘지에 가서 Disney on Ice를 보았습니다.
교정 수학을하면 후회하게됩니다.
작동 방식 :
여기서 핵심 기능은 다음과 같은 개념입니다 conditional ${parameter} expansion.
. 변수를 설정하지 않거나 null 형식으로 만 변수를 값으로 설정할 수 있습니다.
${var_name
: =desired_value}
대신 설정되지 않은 변수 만 설정하려는 경우 :colon
및 null 값은 그대로 유지됩니다.
범위 :
당신은 위의 예제에서 알 수 있습니다 $PLACE
과 $RESULT
를 통해 설정할 때 바뀌지 parameter expansion
하더라도 _top_of_script_pr()
이미 호출 된 아마 그 그것의 실행 설정. 이 작품은 즉 그 이유는 _top_of_script_pr()
A는 ( subshelled )
기능 - 나는 그것을 둘러싸 parens
댄 아니라 { curly braces }
다른 사람을 위해 사용. 서브 쉘에서 호출되기 때문에 설정하는 모든 변수 locally scoped
는 상위 쉘로 돌아가고 해당 값이 사라집니다.
그러나 _more_important_function()
설정 하면 설정 $ACTION
은 globally scoped
다음을 통해서만 설정 되므로 _less_important_function()'s
두 번째 평가에 영향을 미칩니다.$ACTION
_less_important_function()
$ACTION
${parameter:=expansion}.
:없는
그리고 나는 최고의 사용 왜 :colon?
음을의 man
페이지가 당신을 말할 것이다 : does nothing, gracefully.
당신은 참조 parameter expansion
를 - 그것은 같은 소리 정확히 expands
의 값에 ${parameter}.
따라서 함께 우리가 변수를 설정할 때 ${parameter:=expansion}
우리는 그 값으로 남겨 - 어떤 쉘 의지 인라인 실행을 시도하십시오. 실행하려고하면 the cemetery
오류가 발생합니다. PLACE="${PLACE:="the cemetery"}"
동일한 결과를 생성하지만이 경우에도 중복되며 쉘을 선호합니다.: ${did:=nothing, gracefully}.
그것은 당신이 이것을 할 수있게합니다 :
echo ${var:=something or other}
echo $var
something or other
something or other
여기 문서
그리고 null 또는 unset 변수의 인라인 정의도 다음과 같은 이유입니다.
<<HEREDOC echo $yo
${yo=yoyo}
HEREDOC
yoyo
를 생각하는 가장 좋은 방법 here-document
은 입력 파일 디스크립터로 스트리밍되는 실제 파일입니다. 다소간 그것이 그 자체이지만, 다른 쉘은 약간 다르게 구현합니다.
어쨌든, 인용하지 않으면 <<LIMITER
스트리밍 되고 평가됩니다. expansion.
따라서 here-document
캔에 변수를 선언하면 작동하지만 expansion
아직 설정되지 않은 변수 만 설정하도록 제한합니다. 그러나 템플릿 인쇄 기능을 호출 할 때 항상 기본값이 설정되므로 설명한대로 요구 사항에 완벽하게 맞습니다.
왜 안돼 eval?
제가 제시 한 예는 안전하고 효과적인 수락 방법을 제공 parameters.
합니다. 범위 를 다루기 때문에 set via 내의 모든 변수 ${parameter:=expansion}
는 외부에서 정의 할 수 있습니다. 따라서이 모든 것을 template_pr.sh라는 스크립트에 넣고 실행하면 :
% RESULT=something_else template_pr.sh
당신은 얻을 것이다 :
네 엄마 집에 가서 Disney on Ice를 봤어
당신이 서예를하면 당신은 something_else
나는 묘지에 가서 Disney on Ice를 보았습니다.
교정 수학을하는 경우에는 something_else
나는 묘지에 가서 Disney on Ice를 보았습니다.
교정 수학을하는 경우에는 something_else
이 같은 문자 그대로 스크립트에서 설정 한 해당 변수에 대한 작동하지 않을 것입니다 $EVENT, $ACTION,
그리고 $one,
난 단지 차이를 보여주기 위해 그런 식으로 사람들을 정의하지만.
어쨌든, evaled
명령문 에 알 수없는 입력을 받아들이는 것은 본질적으로 안전하지 않지만, parameter expansion
특별히 그렇게하도록 설계되었습니다.