"-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.