이전 명령의 마지막 인수는 무엇입니까? 명령의 마지막 인수라고합니다. 나는 그것이없는 이유를 궁금해 그래서

$_ 이전 명령의 마지막 인수라고합니다.

나는 그것이없는 이유를 궁금해 그래서 EDITOR="emacs -nw"하지만 EDITOR다음 예에?

"emacs -nw"마지막 논쟁의 일부 가 아닌 이유는 무엇 입니까?

더 일반적으로, 인수의 정의와 마지막 인수는 무엇입니까?

감사.

$ export EDITOR="emacs -nw"
$ echo $_
EDITOR



답변

배쉬 (과 그들이 인수로 사용할 때, 변수 할당을 처리 alias, declare, export, local, readonly,과 typeset) 다른 어떤 전에 (- 확장 변수에 할당 된 값에 적용 또는 오히려, 그것은 아무것도하기 전에 식별). 이 단어 확장에 도달하면, 나머지 명령이있다 export EDITOR, 그래서 _으로 설정됩니다 EDITOR.

일반적으로 인수는 확장 후 남은 “단어”입니다 (변수 할당 및 방향 재 지정은 포함되지 않음).

자세한 내용 은 Bash 매뉴얼의 간단한 명령 확장 을 참조하십시오.


답변

TL; DR :의 경우 export FOO=bar, bash는 임시 환경 작성을 호출하고 FOO=bar해당 환경을 설정 한 다음 최종 명령을 생성합니다 export FOO. 이때 FOO마지막 인수로 간주됩니다.


아, 많이 욕설 $_:

($ _, 밑줄) 쉘 시작시 환경 또는 인수 목록에 전달 된대로 실행중인 쉘 또는 쉘 스크립트를 호출하는 데 사용되는 절대 경로 이름으로 설정하십시오. 결과적으로 확장 후 이전 명령의 마지막 인수로 확장됩니다. 또한 실행되어 해당 명령으로 내 보낸 환경에 배치 된 각 명령을 호출하는 데 사용되는 전체 경로 이름으로 설정하십시오. 메일을 확인할 때이 매개 변수는 메일 파일의 이름을 보유합니다.

몇 가지 변형을 살펴 보겠습니다.

$ man; echo $_
What manual page do you want?
man
$ man foo; echo $_
No manual entry for foo
foo
$ echo; echo $_

echo
$ echo bar foo; echo $_
bar foo
foo
$ foo=x eval 'echo $foo'; echo $_
x
echo $foo
$ bar() { man $1; }; echo $_
foo
$ for (( i=0; $i<0; i=i+1 )); do echo $i; done; echo $_
foo
$ bar; echo $_
What manual page do you want?
man
$ bar foo; echo $_
No manual entry for foo
foo
$ MANPATH=/tmp; echo $_

$ export MANPATH=/tmp; echo $_
MANPATH

여기에 세 가지 패턴이 있습니다.

  • 파일 시스템, 함수 및 내장에서 호출 된 명령은 일반적으로 예상 한대로 작동합니다. $_인수가 없으면 명령 이름 자체로 설정되고, 그렇지 않으면 마지막으로 제시된 인수가 설정됩니다.
  • 함수 정의, 루프 및 기타 논리적 구성 후에 $_는 수정되지 않습니다.
  • 그 밖의 모든 것 : $_예상치 못한 것으로 설정되었습니다. 기묘한.

이상한 점에 대한 통찰력을 제공하기 위해 코드를 계측했습니다.

$ ./bash --noprofile --norc -c 'man foo'
lastword=[man]
lastarg=[foo]
$ ./bash --noprofile --norc -c 'export FOO=bar'
lastword=[export]
lastarg=[FOO=bar]
bind_variable, name=[FOO], value=[bar]
before bind_lastarg, lastarg=[FOO]
bind_lastarg, arg=[FOO]
bind_variable, name=[_], value=[FOO]
$ ./bash --noprofile --norc -c 'declare FOO=bar'
lastword=[declare]
lastarg=[FOO=bar]
bind_variable, name=[FOO], value=[(null)]
before bind_lastarg, lastarg=[FOO=bar]
bind_lastarg, arg=[FOO=bar]
bind_variable, name=[_], value=[FOO=bar]

파서lastarg=모든 경우에 예상되는 마지막 인수 ( )를 볼 수 있지만 그 이후에 발생하는 일은 bash가 어떻게 생각 해야하는지에 달려 있습니다. execute_cmd.c, execute_simple_command ()를 참조하십시오 .

의 경우 export FOO=barbash는 할당을 한 다음 변수를 내 보냅니다. 이것은 확장 후 마지막 인수가 계산 된 문서의 주장과 일치하는 것 같습니다.


답변

제목 질문에 대답하려면 다음을 시도하십시오 !$.

$ export EDITOR="emacs -nw"
$ echo !$
EDITOR=emacs -nw

이것은 역사 확장입니다. bash 맨 페이지에서 :

기록 확장은 완전한 행을 읽은 직후에 쉘이 단어로 나누기 전에 수행됩니다. 두 부분으로 이루어집니다. 첫 번째는 히스토리 목록에서 대체 중에 사용할 행을 결정하는 것입니다. 두 번째는 현재 라인에 포함 할 라인의 일부를 선택하는 것입니다. 히스토리에서 선택한 라인은 이벤트이며 해당 라인의 일부는 단어입니다.

이벤트 지정자

! 공백, 개행, 캐리지 리턴, = 또는 뒤에 오는 경우를 제외하고 히스토리 대체를 시작하십시오 (extglob 쉘 옵션이 shopt 내장을 사용하여 활성화 된 경우).

!! 이전 명령을 참조하십시오. 이것은`! -1 ‘의 동의어입니다.

단어 지정자

$ 마지막 단어. 이것은 일반적으로 마지막 인수이지만 줄에 단어가 하나만 있으면 0 번째 단어로 확장됩니다.

이벤트 지정없이 단어 지정자가 제공되면 이전 명령이 이벤트로 사용됩니다.


답변