2011-02-13 6 views
4

나는 문자열 보안을 위해 내 스크립트를 떠받하는 동안이 발견 :이것은 GNU Bash의 버그입니까?

$ echo '!!' 
!! 
$ echo "$(echo '!!')" 
echo "$(echo 'echo '!!'')"  #<~ the console echoes the line with expanded history here 
echo !!       #<~ the result 

아무것도, 변수 확장하지해야 가장 안쪽의 단일 인용되는, 인용 나에게 보인다, 서브 쉘 또는 그렇지 않은 경우이 경우에는 !!을 마지막 행으로 확장합니다. 그렇게해서는 안되는 것처럼 보입니다.

나는 당신에게 물어 봅니다 : 이것은 Bash의 버그이며, 감탄 부호를 출력하는 따옴표 붙은 서브 쉘 확장을 사용할 수 있다면? 위의 예상대로 그렇다면 왜이 행동 않는 버그가 아닌 경우

:

편집 (리눅스 배쉬 4.1.007 사용)?

$ foo='some value' 
$ echo "$(echo 'neither $foo nor `this subshell` should expand here')" 
neither $foo nor `this subshell` should expand here 
+1

버그가 아닙니다. bash가 인수 확장을 수행하는 방법입니다. 누군가는 매뉴얼의 관련 부분을 참조하여 답할 것입니다. – Juliano

답변

2

동의합니다.

$ echo "$(echo '!!')" 
echo "$(echo 'echo $(echo '!!')')" 
echo $(echo !!) 

내가 history expansion documentation에 따라 차이를 설명하는 방법을 볼 수 없습니다

$ echo $(echo '!!') 
!! 

으로 동일한 작업을 수행해야합니다.

내역 확장 문서가 나머지 shell expansions documentation과 어떻게 완전하게 다른지도 이상하지 않습니다.

zsh은 둘 모두에 대해 !! 에코를 보내고 적어도 내 설치 프로그램을 사용하십시오.

+0

버그, 그것은'echo ''case를 처리하고 echo'$ (echo '!!') "를 잡으려고 시도합니다 – Mikel

+1

버그는 bash-3.0에서 소개되었습니다 .bash-2.05b는 작동합니다. 예상대로 – Mikel

1

(어쨌든 스크립트에서 기본적으로 꺼져) 그것은 버그 수 있지만, set +H은 비활성화됩니다. 여기

그 사람의 페이지에서 관련 부분은 다음과 같습니다 따옴표

묶는 문자가 $,`, \를 제외하고, 의 리터럴 값 따옴표 내의 모든 문자를 보존하고, 기록 확장을 사용하면! $와`문자는 이중 따옴표 안에 의 특별한 의미를 유지합니다. 백 슬래시는 $,`, "\, < 개행 > 중 하나의 문자가 뒤에 오는 경우에만 의 특별한 의미를 지닙니다. 이중 인용 부호는 백 슬래시 앞에따옴표 안에 인용 부호로 묶을 수 있습니다. 역사 확장 따옴표에 나타나는 백 슬래시를 사용하여 를 탈출한다!하지 않는 한 수행됩니다. 앞의 백 슬래시! 제거되지 않습니다.

역사 확장을 즉시 수행 완성 된 줄은 입니다. 셸에서 단어를 분리하기 전에 읽으십시오. ... 역사 확장은 에 의해 소개되며 역사 확장 문자의 등장입니다! 기본값. 백 슬래시 (\)와 작은 따옴표 만이 확장 문자 의 내역을 인용 할 수 있습니다.

+0

"큰 따옴표로 묶는 문자 ..."- 그게 전부입니다. 앞머리는 작은 따옴표 안에 있습니다. 변수가 거기에있는 변수라면 확장되지 않습니다. – amphetamachine

+0

@amphetamachine 큰 따옴표 (대개)는 큰 따옴표 사이에있을 때 (이 경우처럼) 특별한 의미를 상실합니다. '$()'는 작은 따옴표에 특별한 의미를 부여하지만 분명히 bash는 역사 확장 후에도 그렇게 많은 부분을 파싱하지 않는다. 어떤 의미에서 역사 치환은'$'''''''''''''''''''''''''물건의 인용 상태를 바꿀지도 모르는 것들을 포함 할 수 있기 때문에 아직 구문 분석해서는 안됩니다 ... –

+0

@Gordon : 원래 질문의 편집을 참조하십시오.) – amphetamachine

1

두 개의 강약을 변수에 넣으면 예상 한 결과 (더 많은 문자열 보안뿐 아니라)를 얻을 수 있습니다.

(
#set -xv 
twobangs='!!' 
echo "${twobangs}" 
echo "$(echo "${twobangs}")" 
echo "$(echo 'echo "${twobangs}"')" 
echo "$(echo "echo "${twobangs}"")" 
echo "$(echo "echo ""${twobangs}")" 
#set -xv 
) 

비슷한 주에서 쉘의 내장 문자열 연결을 사용하고 '!'와 같은 문자를 넣을 수 있습니다. 쉘에 의한 해석을 막기 위해 작은 따옴표로 묶으십시오.

(
set -H 
echo "Hello, world"'!' 
(sleep 10) & 
#trap "echo exit; kill -TERM $!" EXIT HUP INT QUIT TERM # troublemaker 
#trap "echo exit; kill -TERM $"'!' EXIT HUP INT QUIT TERM 
trap "echo exit; kill -TERM $"'!'"; echo killed" EXIT HUP INT QUIT TERM 
sleep 5 
)