$ _ vs.! $. Argumen terakhir dari perintah sebelumnya dan pengalihan output

28

Pertanyaannya adalah tentang variabel khusus. Dokumentasi mengatakan:

!!:$

menunjuk argumen terakhir dari perintah sebelumnya . Ini dapat disingkat menjadi $!


( $_, garis bawah.) Pada startup shell, setel ke pathname absolut yang digunakan untuk memanggil shell atau skrip shell yang dieksekusi seperti yang diteruskan dalam lingkungan atau daftar argumen. Selanjutnya, perluas argumen terakhir ke perintah sebelumnya setelah ekspansi. Juga setel ke nama path lengkap yang digunakan untuk memanggil setiap perintah yang dieksekusi dan ditempatkan di lingkungan yang diekspor ke perintah itu.

Pasti ada beberapa perbedaan yang tidak bisa saya tangkap, karena:

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

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

Apa bedanya?

Mesin tenun
sumber
4
! $ adalah ekspansi sejarah, bukan variabel khusus, jadi saya akan berasumsi bahwa kode bash menangani mereka secara berbeda.
Jeff Schaller
2
Saya tidak memiliki jawaban pasti untuk pertanyaan ini, tetapi: ① The Bourne bahasa shell adalah salah satu, mungkin satu , bahasa pemrograman paling konsisten secara internal masih banyak digunakan saat ini. Mencoba menyimpulkan prinsip-prinsip umum akan membuat Anda tidak berhasil. Anda hanya perlu mengingat semua aturan khusus. Maaf. ② Catat kata-kata "setelah ekspansi", segera setelah frasa yang Anda sorot, dalam definisi $_. Itu krusial. Mungkin tidak menjelaskan perbedaan yang membingungkan Anda, tetapi itu menjelaskan banyak cara lain $_dan !$tidak sama.
zwol

Jawaban:

32

!$adalah penunjuk kata perluasan sejarah, kata ini meluas ke kata terakhir dari perintah sebelumnya dalam sejarah . TKI, kata terakhir dari entri sebelumnya dalam sejarah. Kata ini biasanya argumen terakhir untuk perintah, tetapi tidak dalam kasus pengalihan. Di:

echo "hello" > /tmp/a.txt

seluruh perintah 'echo "hello" > /tmp/a.txt'muncul dalam sejarah, dan /tmp/a.txtmerupakan kata terakhir dari perintah itu.

_adalah parameter shell, itu memperluas argumen terakhir dari perintah sebelumnya. Di sini, pengalihan bukan merupakan bagian dari argumen yang diteruskan ke perintah, jadi hanya helloargumen yang diteruskan ke echo. Itu sebabnya $_diperluas ke hello.

_bukan salah satu dari parameter khusus standar shell lagi. Ia bekerja di bash, zsh, mkshdan dashhanya ketika interaktif, ksh93hanya ketika dua perintah berada di garis terpisah:

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

$ echo 1
1
$ echo $_
1
cuonglm
sumber
1
Salah satu efek dari !$ekspansi vs $_parameter adalah yang echo $_selalu ditampilkan dalam riwayat sebagai echo $_, sementara echo !$menunjukkan nilai yang diperluas. Misalnya echo one twokemudian echo !$, kemudian menekan up show echo two.
Jacktose