$_
이전 명령의 마지막 매개변수라고 합니다.
그럼 왜 안 되는지 궁금합니다. 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=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=bar
bash는 할당을 수행한 다음 변수를 내보냅니다. 이는 확장 후에 마지막 매개변수가 평가된다는 문서의 주장과 일치하는 것 같습니다.
답변3
제목 질문에 답하려면 다음을 시도해 보세요 !$
.
$ export EDITOR="emacs -nw"
$ echo !$
EDITOR=emacs -nw
이것은 역사의 확장이다. Bash 맨페이지에서:
히스토리 확장은 쉘이 행을 단어로 나누기 전에 전체 행을 읽은 후 즉시 수행됩니다. 두 부분으로 나누어져 있습니다. 첫 번째는 교체 중에 사용할 기록 목록의 행을 결정하는 것입니다. 두 번째는 현재 행에 포함할 행의 일부를 선택하는 것입니다. 히스토리에서 선택한 라인이 이벤트이고, 라인에서 실행된 부분이 단어입니다.
...
이벤트 표시기
...
! 뒤에 공백, 개행, 캐리지 리턴, = 또는 ((내장 shopt를 사용하여 extglob 쉘 옵션이 활성화된 경우)가 없으면 기록 교체를 시작합니다.
...
!!이전 명령어를 참고하세요. 이는 "!-1"의 동의어입니다.
...
단어 표시기
...
$ 마지막 문장. 이는 일반적으로 마지막 인수이지만 줄에 단어가 하나만 있는 경우 0번째 단어로 확장됩니다.
...
이벤트를 지정하지 않고 단어 지정자가 제공되면 이전 명령이 이벤트로 사용됩니다.