for i in "${arrOfFiles[@]}"; do
# OUTPUT_PATH=some dynamic naming file created earlier
perl -pe 's/%REPLACE ME%/`cat $i`/ge' -i "$OUTPUT_PATH"`
done
내 스크립트가 여기에 걸려 완료되지 않습니다. using은 cat $i
배열에 있는 파일의 올바른 내용을 표시하므로 $i가 작동합니다. 무엇을 제공합니까?
답변1
e
Perl 연산자 flags 를 사용하고 싶지 않습니다 s///
. -e
대체 코드의 오른쪽을 Perl 코드로 평가합니다. cat $i
Perl 코드의 내용을 평가하지 않고 대체할 리터럴 텍스트로 처리하려고 합니다. bash 명령줄에서 작은따옴표를 사용하고 있으므로 cat $i
텍스트는 문자 그대로 perl에 전달되고표현으로 평가: 이는 Perl이 cat
(Perl의 관점에서) 하위 쉘과 그 내용을 실행한다는 것을 의미합니다.$i
진주변수가 전혀 없습니다. 그렇지 않은 경우 use strict
선언되지 않은 변수를 갖는 것은 완전히 합법적이므로 cat
Perl은 인수 없이 호출된 하위 쉘을 열도록 지시할 때 불평하지 않습니다. cat
물론 표준 입력을 기다리는 인수는 없습니다. 이것이 바로 스크립트가 "중지"되는 이유입니다. 기본적으로 다음과 같이 호출합니다.
perl -e '`cat $i`;'
use strict
Perl 코드에 다음을 추가하면 오류가 분명해집니다.
perl -e 'use strict; `cat $i`;'
코드 블록은 다음과 같아야 합니다.
for i in "${arrOfFiles[@]}"; do
perl -pi -e "s/%REPLACE ME%/`cat $i`/g;" "$OUTPUT_PATH"
done
그러나 이는 항상 에 이름이 지정된 파일에서 작동합니다 $OUTPUT_PATH
. 즉, %REPLACE ME%
해당 파일의 텍스트가 파일 배열의 첫 번째 파일 내용으로 대체되고 나머지 파일은 아무것도 대체되지 않습니다. 여기서 정확히 무엇을 하려는지 명확하지 않습니다. Perl의 플래그를 사용하면 -pi
명령줄에 제공된 모든 파일을 인라인 편집하도록 지시할 수 있습니다. 현재는 $OUTPUT_PATH
.
이는 문자열 교체를 수행하는 나쁜 방법일 수도 있습니다. 각 파일의 내용에 문자 수가 제한 없이 포함될 수 있으며 이로 인해 $i
Perl 명령줄이 완전히 손상될 수 있습니다. 단일 /
문자만으로도 Perl 구문 오류가 발생할 수 있으며 주입을 통해 임의의 코드를 실행하는 시퀀스가 있을 수 있습니다. 당신은 경고를 받았습니다.