이전 명령의 마지막 매개변수는 무엇이었나요?

이전 명령의 마지막 매개변수는 무엇이었나요?

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

그럼 왜 안 되는지 궁금합니다. EDITOR="emacs -nw"하지만 EDITOR아래 예에서는요?

"emacs -nw"왜 마지막 매개변수의 일부가 아닌가 ?

보다 일반적으로 하나의 매개변수와 마지막 매개변수의 정의는 무엇입니까?

감사해요.

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

답변1

변수 할당이 인수로 허용되면( alias, declare, export, local및 사용) Bash는 다른 것보다 먼저 변수 할당을 처리합니다(또는 오히려 다른 것보다 readonly먼저 typeset인식합니다. 확장은 변수 값에 대한 할당에 적용됩니다). 단어 확장을 할 때 나머지 명령은 export EDITOR이므로 _로 설정합니다 EDITOR.

일반적으로 매개변수는 확장 후 남은 "단어"입니다(변수 할당 및 리디렉션 제외).

바라보다간단한 명령 확장자세한 내용은 Bash 매뉴얼을 참조하세요.

답변2

핵심요약: 의 경우 export FOO=barbash는 임시 환경 생성을 호출하고 해당 환경을 설정한 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는 할당을 수행한 다음 변수를 내보냅니다. 이는 확장 후에 마지막 매개변수가 평가된다는 문서의 주장과 일치하는 것 같습니다.

답변3

제목 질문에 답하려면 다음을 시도해 보세요 !$.

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

이것은 역사의 확장이다. Bash 맨페이지에서:

히스토리 확장은 쉘이 행을 단어로 나누기 전에 전체 행을 읽은 후 즉시 수행됩니다. 두 부분으로 나누어져 있습니다. 첫 번째는 교체 중에 사용할 기록 목록의 행을 결정하는 것입니다. 두 번째는 현재 행에 포함할 행의 일부를 선택하는 것입니다. 히스토리에서 선택한 라인이 이벤트이고, 라인에서 실행된 부분이 단어입니다.

...

이벤트 표시기

...

! 뒤에 공백, 개행, 캐리지 리턴, = 또는 ((내장 shopt를 사용하여 extglob 쉘 옵션이 활성화된 경우)가 없으면 기록 교체를 시작합니다.

...

!!이전 명령어를 참고하세요. 이는 "!-1"의 동의어입니다.

...

단어 표시기

...

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

...

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

관련 정보