Pahami arti `$ _`

12

Bisakah Anda menjelaskan kalimat-kalimat berikut dari manual Bash tentang $_, terutama bagian yang dicetak tebal, mungkin dengan beberapa contoh?

  1. Pada startup shell, setel ke pathname absolut yang digunakan untuk memanggil shell atau skrip shell yang dieksekusi sebagaimana diteruskan dalam lingkungan atau daftar argumen .

  2. Selanjutnya , perluas argumen terakhir ke perintah sebelumnya, setelah ekspansi.

  3. Juga diatur ke pathname lengkap yang digunakan untuk memanggil setiap perintah yang dieksekusi dan ditempatkan di lingkungan yang diekspor ke perintah itu .

  4. Saat memeriksa email , parameter ini menyimpan nama file email.

Tim
sumber
4
-1 pertanyaan tidak jelas & tidak diteliti secara menyeluruh. Apa yang sudah kamu coba? Di mana harapan Anda tidak selaras dengan teks? Apakah Anda tidak benar-benar memahami kata 'sesudahnya'? Jika pengguna baru mengajukan pertanyaan yang sama, saya akan memiliki pertanyaan yang sama dari mereka (terlepas dari keingintahuan bawaan saya yang sama tentang bagaimana persisnya segala sesuatu bekerja).
Jeff Schaller

Jawaban:

20

Saya setuju itu tidak terlalu jelas.

1. Pada startup shell,

  • jika _variabel berada di lingkungan yang bashmenerima , maka bashbiarkan tidak tersentuh.

    Secara khusus, jika bashshell itu dipanggil oleh bash shell lain (meskipun zsh, yashdan beberapa kshimplementasi juga melakukannya), maka bashshell itu akan mengatur _variabel lingkungan ke jalur perintah yang dieksekusi (itulah poin ke-3 dalam pertanyaan Anda). Misalnya, jika bashdipanggil untuk menafsirkan skrip sebagai akibat dari bashpenafsiran shell lain :

    bash-script some args

    Itu bashakan diteruskan _=/path/to/bash-scripdi lingkungan yang diberikan bash-script, dan itulah nilai awal dari $_ bashvariabel akan berada di bashshell yang menafsirkan skrip itu.

    $ env -i _=whatever bash -c 'echo "$_"'
    whatever
    
  • Sekarang, jika aplikasi yang menjalankan tidak melewati _variabel lingkungan , bashshell yang dipanggil akan diinisialisasi $_ke yang argv[0]diterimanya sendiri yang bisa menjadi bash, atau /path/to/bashatau /path/to/some-scriptatau apa pun (dalam contoh di atas, itu akan menjadi /bin/bashjika she-bang dari skrip adalah #! /bin/bash atau /path/to/bash-script tergantung pada sistem ).

    Sehingga teks itu menyesatkan karena menggambarkan perilaku penelepon yang bashtidak memiliki kendali atas. Aplikasi yang dipanggil bashmungkin tidak disetel $_sama sekali (dalam praktiknya, hanya beberapa shell dan beberapa aplikasi interaktif yang jarang dilakukan, execlp()tidak misalnya), atau dapat menggunakannya untuk sesuatu yang sama sekali berbeda (misalnya ksh93mengaturnya *pid*/path/to/command).

    $ env bash -c 'echo "$_"'
    /usr/bin/env   (env did not set it to /bin/bash, so the value we
                   get is the one passed to env by my interactive shell)
    $ ksh93 -c 'bash -c "echo \$_"'
    *20042*/bin/bash
    

2. Selanjutnya

The Selanjutnya tidak sangat jelas baik. Dalam praktiknya, itu segera bashmengartikan perintah sederhana di lingkungan shell saat ini.

  • Dalam kasus shell interaktif , itu akan menjadi perintah sederhana pertama yang ditafsirkan dari /etc/bash.bashrcmisalnya.

    Sebagai contoh, pada prompt shell interaktif:

     $ echo "$_"
     ]      (the last arg of the last command from my ~/.bashrc)
     $ f() { echo test; }
     $ echo "$_"
     ]      (the command-line before had no simple command, so we get
             the last argument of that previous echo commandline)
     $ (: test)
     $ echo "$_"
     ]      (simple command, but in a sub-shell environment)
     $ : test
     $ echo "$_"
     test
    
  • Untuk shell non-interaktif , itu akan menjadi perintah pertama di $BASH_ENVatau dari kode yang diumpankan ke shell itu jika $BASH_ENVtidak disetel.

3. Saat Bash menjalankan perintah

Poin ketiga adalah sesuatu yang berbeda dan diisyaratkan dalam diskusi di atas.

bash, seperti beberapa shell lain akan melewatkan _variabel lingkungan ke perintah yang dijalankannya yang berisi jalur yang bashdigunakan sebagai argumen pertama ke execve()panggilan sistem.

$ env | grep '^_'
_=/usr/bin/env

4. Saat memeriksa surat

Poin keempat dijelaskan secara lebih rinci dalam deskripsi MAILPATHvariabel:

'MAILPATH'

Daftar nama file yang dipisahkan oleh titik dua dimana shell secara berkala memeriksa email baru .

Setiap entri daftar dapat menentukan pesan yang dicetak ketika surat baru masuk dalam file surat dengan memisahkan nama file dari pesan dengan '?'. Ketika digunakan dalam teks pesan, '$ _' meluas ke nama file email saat ini.

Contoh:

$ MAILCHECK=1 MAILPATH='/tmp/a?New mail in <$_>' bash
bash$ echo test >> /tmp/a
New mail in </tmp/a>
Stéphane Chazelas
sumber
4

Coba contoh sederhana ini:

echo "$_"
echo "test"
echo "$_"

Jalankan dengan memberikan path absolut ( /home/$USERNAME/test.sh); keluaran:

/home/$USERNAME/test.sh
test
test

Pertama $_berisi jalur yang Anda gunakan untuk menjalankan skrip dan yang kedua berisi argumen pertama ke tengah echo. Untuk item ketiga dalam daftar, jika Anda memulai terminal baru dan mengetik gema, $_ ia akan menampilkan variabel yang berisi PATHyang biasanya digunakan untuk mencari dan memanggil perintah (di mesin Ubuntu saya) di shell normal atau path absolut ke .bashrsfile Anda di shell login.

Untuk item empat dari halaman bash man:

Saat digunakan dalam teks pesan, $_perluas nama file saat ini.

coffeMug
sumber
Terima kasih. (1) dapatkah Anda menjelaskan kasus ketiga dengan contoh? (2) Ketika saya membuka tab terminal gnome baru, output dari echo $_adalah EDITOR, dan mengapa itu? Kasus apa yang diikuti? (3) Dapatkah Anda memberikan contoh tentang cara memeriksa email, dan menggunakan $_dalam hal ini?
Tim
Buka .bashrcdan komentari setiap baris di sana. Simpan hanya satu baris yang berisi perintah suka echo "test"atau serupa. Simpan dan tutup. Kemudian jalankan bashdan segera echo $_. Gema terakhir ini harus mencetak tes dalam output.
coffeMug
Untuk bagian surat saya belum pernah menggunakan surat Unix dan tidak memiliki surat kerja yang diinstal pada sistem saya sekarang jadi tidak bisa memberi Anda contoh. Tetapi harus jelas jika Anda mengikuti deskripsi MAILPATHdi linuxcommand.org/lc3_man_pages/bash1.html
coffeMug
1
FYI, versi bash manual canonical dan terkini adalah: gnu.org/software/bash/manual/bashref.html . Versi 4.3 sementara halaman perintah linux 4.1.
Jeff Schaller
1

Untuk kasus 2, contoh bernilai ribuan kata:

mkdir my_long_dir
cd $_

Lakukan apa yang Anda duga / harapkan. Memberi saya placeholder sederhana ketika saya berada di baris perintah untuk menyelamatkan saya karena harus mengulang sendiri.

dsz
sumber