다음은 두 개의 서로 다른 대칭 암호를 순서대로 사용하여 파일을 대칭적으로 암호화/해독하는 스크립트입니다.
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Arguments: enc|dec filename"
exit
fi
E="gpg -o - --symmetric --cipher-algo"
D="gpg -o - --decrypt"
ERR="2>/dev/null"
if [ "$1" = "enc" ]; then
$E AES $2 | $E TWOFISH -
elif [ "$1" = "dec" ]; then
$D $2 ${ERR} | $D - ${ERR}
else
echo "Arguments: enc|dec filename"
exit
fi
실행하면 ./doublecrypt dec /tmp/test.encrypted
오류가 발생합니다.
usage: gpg [options] --decrypt [filename]
usage: gpg [options] --decrypt [filename]
내가 줄을 바꾸면
$D $2 ${ERR} | $D - ${ERR}
에게
echo "$D $2 ${ERR} | $D - ${ERR}"
인쇄합니다
gpg -o - --decrypt /tmp/xenc 2>/dev/null | gpg -o - --decrypt - 2>/dev/null
이것을 bash에 복사하여 붙여넣으면 올바르게 실행됩니다.
echo
그렇다면 원래 형식에서와 같이 를 제거하고 bash 스크립트가 직접 평가하도록 하면 작동하지 않는 이유는 무엇입니까 ?
저는 Ubuntu Saucy를 실행 중이고 bash는 제 쉘입니다.
답변1
짧은 대답: 참조BashFAQ #50: 변수에 명령을 넣으려고 하는데 복잡한 경우가 항상 실패합니다!.
긴 대답: 쉘이 명령줄의 다양한 요소를 구문 분석하는 순서로 인해 문제가 발생하고 있습니다. 특히 ${ERR}
프로세스 중간쯤에 따옴표, 이스케이프 및 리디렉션과 같은 작업을 이미 처리한 후 변수 참조(예: )를 확장합니다 . 귀하의 경우 중요한 리디렉션 부분입니다. 쉘이 ${ERR}
로 확장될 때 2>/dev/null
이미 리디렉션을 찾았지만 아무것도 찾지 못했기 때문에 2>/dev/null
명령에 대한 인수로 처리한 다음 gpg
이를 말도 안 되는 것으로 거부합니다.
기본적으로 명령(또는 명령 요소)을 변수에 저장하는 것은 잘못된 방법입니다. 변수는 실행 가능한 코드가 아닌 데이터용입니다. 이 경우 대신 함수를 사용하는 것이 훨씬 더 나을 것입니다.
e() {
gpg -o - --symmetric --cipher-algo "$@"
}
d() {
gpg -o - --decrypt "$@" 2>/dev/null
}
if [ "$1" = "enc" ]; then
e AES "$2" | e TWOFISH -
elif [ "$1" = "dec" ]; then
d "$2" | d -
else
echo "Arguments: enc|dec filename"
exit
fi
$2
또한 해당 값이 쉘 구문 분석 프로세스의 후반부에 적용되는 것을 방지하기 위해 큰따옴표로 묶었습니다 .
답변2
다음으로 변경해 보세요 $D $2 ${ERR} | $D - ${ERR}
.
$( $D $2 ${ERR} | $D - ${ERR} )
또한 프로그램의 전체 경로를 사용하십시오 gpg
. 예:
/usr/local/bin/gpg