$ _ vs! $. Ostatni argument poprzedniego polecenia i przekierowanie danych wyjściowych

28

Pytanie dotyczy zmiennych specjalnych. Dokumentacja mówi:

!!:$

wyznacza ostatni argument poprzedniego polecenia . Można to skrócić do! $.


( $_podkreślenie.) Przy uruchamianiu powłoki ustaw bezwzględną nazwę ścieżki używaną do wywoływania powłoki lub skryptu powłoki wykonywanej tak, jak przekazano w środowisku lub liście argumentów. Następnie rozwija się do ostatniego argumentu do poprzedniego polecenia po rozwinięciu. Ustawiono również na pełną ścieżkę używaną do wywoływania każdego wykonanego polecenia i umieszczanego w środowisku eksportowanym do tego polecenia.

Musi być jakaś różnica, której nie mogę złapać, ponieważ:

$ echo "hello" > /tmp/a.txt
$ echo "!$"
echo "/tmp/a.txt"
/tmp/a.txt

$ echo "hello" > /tmp/a.txt
$ echo $_
hello

Jaka jest różnica?

Warsztat tkacki
źródło
4
! $ jest rozszerzeniem historii, a nie specjalną zmienną, więc zakładam, że kod bash obsługuje je inaczej.
Jeff Schaller
2
Nie ma jednoznacznej odpowiedzi na to pytanie, ale: ① Językiem powłoki Bourne jest jednym z, być może , przynajmniej wewnętrznie spójny język programowania nadal powszechnie stosowane. Próba ustalenia ogólnych zasad nie doprowadzi cię nigdzie. Musisz tylko zapamiętać wszystkie specjalne zasady. Przepraszam. ② Zwróć uwagę na słowa „po rozwinięciu”, bezpośrednio po wyróżnionej frazie, w definicji . To bardzo ważne. Może nie wyjaśniać różnicy, która Cię intryguje, ale wyjaśnia wiele innych sposobów i nie są takie same. $_$_!$
zwolnienie

Odpowiedzi:

32

!$jest słowem oznaczającym ekspansję historii, rozwija się do ostatniego słowa poprzedniego polecenia w historii . IOW, ostatnie słowo poprzedniego wpisu w historii. To słowo jest zwykle ostatnim argumentem do polecenia, ale nie w przypadku przekierowania. W:

echo "hello" > /tmp/a.txt

całe polecenie 'echo "hello" > /tmp/a.txt'pojawiło się w historii i /tmp/a.txtjest ostatnim słowem tego polecenia.

_jest parametrem powłoki, rozwija się do ostatniego argumentu poprzedniego polecenia. Przekierowanie nie jest tutaj częścią argumentów przekazywanych do polecenia, więc helloprzekazywany jest tylko argument echo. Właśnie dlatego został $_rozszerzony do hello.

_nie jest już jednym ze standardowych parametrów specjalnych powłoki . To działa w bash, zsh, mkshi dashtylko wtedy, gdy interaktywne, ksh93tylko wtedy, gdy dwa polecenia są na oddzielnych liniach:

$ echo 1 && echo $_
1
/usr/bin/ksh

$ echo 1
1
$ echo $_
1
Cuonglm
źródło
1
Jednym z efektów !$interpretacji vs $_parametru jest to, że echo $_zawsze pokazuje się w historii jako echo $_, a echo !$pokazuje wartość, do której został rozwinięty. Np. echo one twoNastępnie echo !$naciśnięcie przycisku pokazuje echo two.
Jacktose