문제는 특수 변수에 관한 것입니다. 문서에는 다음과 같이 나와 있습니다.
!!:$
지정하다이전 명령의 마지막 매개변수. 이는 로 단축될 수 있습니다
!$
.
(
$_
, 밑줄.) 쉘이 시작되면 환경 또는 인수 목록에 전달된 쉘을 호출하는 데 사용되는 절대 경로 이름 또는 실행 중인 쉘 스크립트로 설정하십시오. 나중에 다음으로 확장됨이전 명령의 마지막 매개변수확장 후. 또한 실행된 각 명령을 호출하고 해당 명령으로 내보낸 환경에 배치하는 데 사용되는 전체 경로 이름으로 설정됩니다.
다음과 같은 이유로 제가 잡을 수 없는 차이점이 있을 것입니다.
$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt
$ echo "hello" > /tmp/a.txt
$ echo $_
hello
차이점은 무엇입니까?
답변1
!$
역사적 확장을 위한 단어 표시기입니다. 이전 명령의 마지막 단어로 확장됩니다.역사. 즉, 역사상 이전 항목의 마지막 단어입니다. 이 단어는 일반적으로 명령의 마지막 매개변수이지만 리디렉션의 경우에는 그렇지 않습니다. 존재하다:
echo "hello" > /tmp/a.txt
전체 명령은 'echo "hello" > /tmp/a.txt'
역사에 나타나며 /tmp/a.txt
명령의 마지막 단어입니다.
_
셸 매개변수이며 이전 명령의 마지막 매개변수로 확장됩니다. 여기서 리디렉션은 명령에 전달된 매개변수의 일부가 아니므로 으로 만 hello
전달 됩니다 echo
.$_
hello
_
더 이상 그들 중 하나가 아니야쉘 표준 특수 매개변수. 두 명령이 별도의 줄 bash
, zsh
, mksh
및에 있는 경우에만 대화형으로만 작동합니다.dash
ksh93
$ echo 1 && echo $_
1
/usr/bin/ksh
$ echo 1
1
$ echo $_
1
답변2
매개변수 대체를 직접 사용하는 것은 불가능하지는 않더라도 어렵습니다 !$
.
wget http://foo.com/my.tar
예를 들어 , 할 수 있지만 tar xf ${_##*/}
중간 !$
변수를 정의하지 않으면 불가능합니다.