"-bash :!": 이벤트를 찾을 수 없습니다 "


114

bash 쉘에서 다음을 실행하십시오. echo "Reboot your instance!"

내 설치에서 :

root@domU-12-31-39-04-11-83:/usr/local/bin# bash --version
GNU bash, version 4.1.5(1)-release (i686-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
root@domU-12-31-39-04-11-83:/usr/local/bin# uname -a
Linux domU-12-31-39-04-11-83 2.6.35-22-virtual #35-Ubuntu SMP Sat Oct 16 23:57:40 UTC 2010 i686 GNU/Linux
root@domU-12-31-39-04-11-83:/usr/local/bin# echo "Reboot your instance!"
-bash: !": event not found

"bash 이벤트"가 무엇인지 설명해 주시겠습니까? 나는 전에이 개념을 들어 본 적이 없다. 또한 어떻게 "!"를 출력해야합니까? 문장의 끝에?

답변:


53

을 사용하여 기록 대체를 끌 수 있습니다 set +H.


2
구문의 이유를 알고 있습니까? 정말 반 직관적 인 것 같습니다. +H무언가를 가능하게하고 무언가 -H를 불가능 하게하려고 타이핑한다고 생각할 것입니다.
Gavin Ward

7
@ PunkyGuy : 나는 그 역사 (말장난 의도)를 모르지만 Unix 옵션은 일반적으로 하이픈 (또는 마이너스)으로 시작하며 +그 반대입니다.
Dennis Williamson

105

!bash는 특수 문자이며 이전 명령을 참조하는 데 사용됩니다. 예를 들어

!rm

"rm"문자열로 시작한 마지막 명령을 기억하고 실행합니다.

!rm:p

"rm"문자열로 시작된 마지막 명령을 호출하지만 실행하지는 않습니다. bash는 느낌표 echo "reboot your instance!"를 " 여기에서 느낌표 바로 다음에 문자로 시작한 마지막 명령으로 대체 "로 느낌표를 해석하고 있으며, 역사에서 단일 항목으로 시작된 이벤트 (명령)를 찾을 수 없다는 것을 알게됩니다. 큰 따옴표.

시험

echo reboot your instance\!

느낌표를 bash에서 보호 (탈출)합니다.


예, 그러나 echo -e "일부 텍스트 $ ENV_VAL 더 많은 텍스트 \ n 지금 재부팅하십시오!"를 사용하려면 발생해야합니다. ?
Maxim Veksler

1
두 개의 반향 문을 작성하십시오. 당신은 무료로 줄 바꿈을 얻습니다.
MadHatter

1
간단한 해결책은 작은 따옴표와 큰 따옴표를 한 번에 사용하는 것입니다 : echo -e "Text \ nReeboot" '!'
mmey

4
짜증나 느낌표를 벗어나지 않으면 bash가 적합합니다. 내가하면 이스케이프 백 슬래시 최종 문자열에 포함되어 있습니다. 왜 이러니, 배쉬 !! ( pastebin.com/g4PYv56A )
Hubro

2
@Hubro의 공정성, 그것이 모두 bash의 잘못인지 확실하지 않습니다. 루비를 사용하여 bash에 물건을 공급함으로써 다소 복잡한 문제가 있으며, 탈출 문자의 제거 또는 강화에서 루비가 어떤 부분을 담당하고 있는지는 분명하지 않습니다.
MadHatter

25

원래 문제를 해결하려면 큰 따옴표 대신 작은 따옴표를 사용하십시오. 후자는 bash가 결과를 명령에 전달하기 전에 특정 문자를 확장하려고 시도합니다 (이 경우 에코). 작은 따옴표를 사용하면 bash는 전체 문자열을 변경하지 않고 전달합니다.

!명령 행 히스토리를 참조하기 위해 명령에 사용됩니다. 전체 세트는 http://tldp.org/LDP/abs/html/abs-guide.html#HISTCOMMANDS 를 참조하십시오 . 위의 예제에서 bash는 !"echo가 찾기 전에 이벤트에 대한 참조로 확장하려고 시도 하므로 오류가 발생합니다.

스크립트에서 모든 기록 명령은 대화식 쉘에서만 의미가 있으므로 비활성화됩니다.

내가 정기적으로 사용하는 유일한 방법은 !$입니다. 이전 명령의 마지막 인수로 확장됩니다. 장소에서 유용한 속기입니다.


4
!!마지막으로 입력 한 명령을 모두 채우는 것이 매우 유용합니다. 특히, sudo !!또는pfexec !!
jgoldschrafe

2
또한 sudo와 pfexec는 훌륭한 유틸리티이지만, 그렇게 열성적 일 필요는 없습니다.
LeartS

$_bash보다 많은 쉘에서 작동하며와는 달리 적절한 변수 !$입니다. (그리고 @LeartS : 당신의 농담이 부족한 이모티콘을 좋아했습니다.;))
ΤΖΩΤΖΙΟΥ

7

그냥 사이에 공백을 넣으십시오! "보다 효과가 있습니다.

건배.


2
솔루션이 작동하는 이유에 대한 설명을 추가해 주시겠습니까?
200_ 성공

2
이것은 배쉬 만 취급하기 때문에 작동합니다! 공백이 아닌 문자가 바로 뒤에 오는 경우 특수 문자로 사용됩니다. 그러나 출력에 여분의 공백을 추가하여 항상 바람직하지 않을 수도 있습니다.
mmey

2

예, ! bash는 특수 문자이며 이전 명령을 참조하는 데 사용됩니다.

상황을 처리 할 수있는 몇 가지 방법

다음은 문자열을 그대로 출력합니다.

echo 'Reboot your instance!'

다음은 명령을 실행하고 문자열을 연결합니다

echo 'escaping #'" adding `which python` to the string"
echo '#!'`which python`

1

으로 bash 4.3보인다는 더 이상 작은 따옴표 또는를 사용할 필요가 없습니다 set +H:

$ bash --version
GNU bash, version 4.3.46(1)-release (x86_64-unknown-linux-gnu)
[...]
$ echo "Reboot your instance!"
Reboot your instance!

아마도 버그입니다. 여기서 4.4.12가 있고 다시 set +H인용 해야합니다 . 또는 set +H어딘가에 (와 같은 /etc/profile) 있습니다.
Bodo Thiesen

문장 끝에서! -char를 사용하지 않으면 bash의 이벤트 감지가 여전히 제대로 작동하는지 확인합니다. 버전 4.3.30 ........ $는 에코입니다 배쉬 : foo는 : 이벤트를 찾을 수 없습니다 "당신의 문장을 다시 확인 foo는!"!의
JohnnyD92

0

heredoc을 사용할 수도 있습니다 .

cat <<EOF
Reboot your instance!
EOF

이 경우에는 하나의 라이너가 아니기 때문에 긴 명령 (bash 스크립트 작성과 같은) 때문에 훌륭합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.