it-swarm-ko.tech

강타를 울리는 법!

편집기로 파일을 여는 대신 내용을 파일에 echo '하여 스크립트를 만들려고했습니다.

echo -e "#!/bin/bash \n /usr/bin/command args"  > .scripts/command

출력 :

bash :!/bin/bash : 이벤트를 찾을 수 없습니다

이 이상한 행동을 bang 에 격리했습니다.

$ echo !
!  

$ echo "!"
bash: !: event not found

$ echo \#!
#!

$ echo \#!/bin/bash
bash: !/bin/bash: event not found
  • 뱅이 왜 이런 원인입니까?
  • 배쉬가 말하는이 "이벤트"는 무엇입니까?
  • 이 문제를 극복하고 "#!/bin/bash"를 화면이나 파일에 어떻게 인쇄합니까?
59
Stefan

작은 따옴표를 사용해보십시오.

echo -e '#!/bin/bash \n /usr/bin/command args'  > .scripts/command

echo '#!'

echo '#!/bin/bash'

Bash가!/bin/bash에 대한 히스토리를 검색하기 때문에 문제점이 발생했습니다. 작은 따옴표를 사용하면이 동작을 피할 수 있습니다.

62
Richm

Richm이 말했듯이 , bash는 history match 를 시도하고 있습니다. 그것을 피하는 또 다른 방법은 \ :

$ echo \#\!/bin/bash
#!/bin/bash

큰 따옴표 안에는 \는 제거되지 않습니다 :

$ echo "\!"
\!
18
Michael Mrozek

!는 히스토리 대체를 시작합니다 ( "이벤트"는 명령 히스토리의 행입니다). 예를 들어 !lsls를 포함하는 마지막 명령 줄로 확장되고 !?foofoo를 포함하는 마지막 명령 줄로 확장됩니다. 특정 단어를 추출 할 수도 있습니다 (예 : !!:1는 이전 명령의 첫 번째 단어를 나타냄). 자세한 내용은 설명서를 참조하십시오.

이 기능은 커맨드 라인 에디션이 기본이었던 시절에 이전 명령을 빠르게 리콜하기 위해 개발되었습니다. 최신 셸 (최소한 bash 및 zsh)과 복사하여 붙여 넣기를 사용하면 기록 확장이 이전처럼 유용하지는 않습니다. 여전히 도움이되지만 도움이되지 않아도 얻을 수 있습니다.

histchars 변수를 설정하여 히스토리 대체를 트리거하는 문자를 변경할 수 있습니다. 기록 대체를 거의 사용하지 않는 경우 예를 들어 histchars='¡^' 대신 ¡! 대신 히스토리 확장을 트리거합니다. set +o histexpand를 사용하여 기능을 모두 끌 수도 있습니다.

특정 명령 행에서 히스토리 확장을 사용하지 않으려면 space$histchars의 세 번째 문자로 사용할 수 있습니다.

histchars='!^ '

그런 다음 선행 공백으로 명령을 입력하면 히스토리 확장이 수행되지 않습니다.

bash-4.3$ echo "#!/bin/bash"
bash: !/bin/bash: event not found
bash-4.3$  echo "#!/bin/bash"
#!/bin/bash

그러나 $HISTCONTROLignorespace가 히스토리에 명령 행을 기록하지 않도록하는 방법으로 bash가 포함 된 경우 선행 공백도 사용됩니다.

두 기능을 모두 원치 않는 경우 $histchars의 세 번째 문자로 다른 문자를 선택해야합니다. 명령 해석 방식에 영향을 미치지 않는 것을 원합니다. 몇 가지 옵션 :

  • 백 슬래시 사용 (\) : \echo foo는 작동하지만 별명 또는 키워드를 사용하지 않으면 부작용이 있습니다.
  • 탭 : 첫 번째 위치에 삽입하려면을 (를) 눌러야합니다. Ctrl+VTab 그러나.
  • 두 개의 키를 입력하는 것이 마음에 들지 않으면 일반적으로 첫 번째 위치에 나타나지 않는 문자를 선택할 수 있습니다 (%, @, ?, 직접 선택) 빈 별칭을 만드십시오.

    histchars='!^%'
    alias %=
    

    그런 다음 해당 문자, 공백 및 명령을 입력하십시오.

    bash-4.3$ % echo !!
    !!
    

(히스토리 대체가 비활성화 된 명령은 기록 할 수 없습니다. 또한 주석에서 히스토리 확장이 수행되지 않도록 $histchars의 기본 3 번째 문자는 #입니다. 변경하고 프롬프트에서 설명을 입력하면! 시퀀스가 ​​확장 될 수 있다는 사실을 알고 있어야합니다.

4
Stéphane Chazelas

제안 된 솔루션은 다음 예와 같이 작동하지 않습니다.

$ bash -c "echo 'hello World!'"
-bash: !'": event not found
$

이 경우 뱅은 8 진수 ASCII 코드를 사용하여 인쇄 할 수 있습니다.

$ bash -c "echo -e 'hello World\0041'"
hello World!
$
2
Atti

아직 언급되지 않은 간단한 해결책은 변수를 사용하는 것입니다.

$ var='!'
$ echo -e "#${var}/bin/bash \n /usr/bin/command args"  > .scripts/command

bang! 인쇄는 not 문자열이 따옴표가 없거나 작은 따옴표로 묶거나 C- 문자열 안에있을 때 문제가됩니다

$ echo hi\!pal 'hi!pal' $'hi!pal'
hi!pal 'hi!pal' $'hi!pal'

Histexpand가 비활성화 된 경우에도 문제가되지 않습니다 (shopt -ou histexpand 또는 set +o histexpand 또는 단순히 set +H). 확장 문자를 변경하여 인쇄하기 쉽도록 할 수도 있습니다 bang!.

그러나 가장 간단한 휴대용 솔루션은 다음과 같습니다.

$ var='!'
$ echo "hi${var}pal"
hi!pal
0
Isaac