이 줄을 대체하기 위해 쉘 스크립트를 작성하겠습니다.
exec "$progdir/$program" ${1+"$@"}
그리고:
exec qemu-arm -L /mnt/c/git/build/linux_arm7/build_arm7/sysroot "$progdir/$program" ${1+"$@"}
파일에서.
/mnt/c/git/build/linux_arm7/build_arm7
이제 이라는 변수에 위치합니다 BUILD_DIRECTORY
. 내가 무엇을 시도하든(따옴표, 다른 구분 기호) 항상 대체 대신 변수로 끝납니다. 예를 들어 나는 이것을 시도했다:
#!/bin/bash
sed_test()
{
sed -i 's|exec "\$progdir\/\$program" \${1+"\$@"}|exec qemu-arm -L ${BUILD_DIRECTORY}\/sysroot "\$progdir\/\$program" \${1+"\$@"}|g' ${BUILD_DIRECTORY}/file
}
파일에 이것을 얻었습니다 :
exec qemu-arm -L ${BUILD_DIRECTORY}/sysroot "$progdir/$program" ${1+"$@"}
이를 올바르게 수행하는 방법은 무엇입니까?
답변1
${BUILD_DIRECTORY}
참조로 인해 변수 확장이 방지됨g
최종 필요없음- 넌 너무 많이 탈출했어
BUILD_DIRECTORY 변수에 공백이 없으면 다음을 사용하십시오.
sed -i 's|exec "$progdir/$program" ${1+"$@"}|exec qemu-arm -L '${BUILD_DIRECTORY}'/sysroot "$progdir/$program" ${1+"$@"}|' ${BUILD_DIRECTORY}/file
주변의 작은따옴표에 유의하세요.${BUILD_DIRECTORY}
BUILD_DIRECTORY에 공백이 있는 경우(예 linux arm7
: ) 릴레이 문자열을 사용합니다(명령 분할).
sed -e 's|exec "$progdir/$program" ${1+"$@"}|exec qemu-arm -L BUILD_DIRECTORY/sysroot "$progdir/$program" ${1+"$@"}|'
-e "s|BUILD_DIRECTORY|${BUILD_DIRECTORY}|"
"${BUILD_DIRECTORY}/file"
생산하다
exec qemu-arm -L /mnt/c/git/build/linux arm7/build_arm7/sysroot "$progdir/$program" ${1+"$@"}
답변2
그리고 :zsh
perl
SRC='exec "$progdir/$program" ${1+"$@"}' \
DST='exec qemu-arm -L '${(qq)BUILD_DIRECTORY}' "$progdir/$program" ${1+"$@"}' \
perl -pi -e 's/\Q$ENV{SRC}\E/$ENV{DST}/g' -- "$BUILD_DIRECTORY/file"
Bourne과 같은 쉘 코드를 편집하고 있으므로 결과가 유효한 쉘 코드인지 확인해야 합니다. 따라서 , , , 공백 과 같은 쉘 구문의 특수 문자가 포함되어 있어도 결과를 구문 분석할 때 해당 값이 인수로 전달되는 $BUILD_DIRECTORY
방식으로 변수의 내용을 삽입 해야 합니다 . .sh
qemu-arm
;
?
'
가장 좋은 방법은 가장 안전한 인용 모드인 작은따옴표로 표현하는 것이며 sh
, 변수에 작은따옴표 문자가 포함되어 있는 경우 \'
작은따옴표 바깥에 삽입하세요. 이것이 qq
매개변수 확장 플래그의 역할입니다 zsh
. 예를 들어 다음과 같습니다.
- 빈 문자열을 넣습니다.
''
a;b
입력하다'a;b'
a'b
입력하다'a'\''b'
$BUID_DIRECTORY
전달된 코드 내부의 값을 확장하면 해당 컨텍스트에서 특수 문자를 이스케이프 처리하지 않는 한 sed
코드 주입 취약점이 발생한다는 의미입니다 . sed
또한 -i
( sed
참조에서 복사한 일부 구현 perl
)은 표준이 아닙니다.
대신 사용하는 것은 perl
다음을 의미합니다.
-i
휴대용으로 사용하시면 됩니다- /를
$SRC
사용하여 이스케이프할 수 있으므로 정규식 연산자를 이스케이프할 필요가 없습니다 .\Q
\E
- 대체를 피할 필요도 없습니다.
답변3
sed 코드를 삽입하기 위해 변수를 사용하는 방법은 s///
명령의 LHS 또는 RHS에서 사용되는지 여부에 따라 먼저 쉘 검증 가능한 콘텐츠를 이스케이프하는 것입니다.
& \ and :
귀하의 시나리오에서는 빌드 변수가 rhs에 배치됩니다. 따라서 실제 sed 코드에서는 구분 기호로 사용하므로 문자를 이스케이프해야 합니다 s:::
. 또한 빌드 변수가 여러 줄이면 줄 바꿈도 이스케이프됩니다. 변수는 작은따옴표로 묶여 있으므로 '\''
빌드 변수에 작은따옴표가 있는 경우 모든 작은따옴표도 변경해야 합니다.
BUILD_DIRECTORY='/mnt/c/git/build/linux_arm7/build_arm7'
BUILD_DIRECTORY_rhs=$(printf '%s\n' "${BUILD_DIRECTORY}" |
sed \
-e 's/[\&:]/\\&/g' \
-e 's/'\''/&\\\\&&/g' \
-e '$!s/$/\\/')
sed -i -e 's:^exec \("$progdir/$program" ${1+"$@"}\)$:'"exec qemu-arm -L '${BUILD_DIRECTORY_rhs}/sysroot' \\1:" -- "${BUILD_DIRECTORY}/file"
이 출력은 다음과 같습니다.
exec qemu-arm -L '/mnt/c/git/build/linux_arm7/build_arm7/sysroot' "$progdir/$program" ${1+"$@"}