Menurut manual Bash , variabel lingkungan BASH_COMMANDberisi
Perintah saat ini sedang dieksekusi atau akan dieksekusi, kecuali shell mengeksekusi perintah sebagai hasil jebakan, dalam hal ini adalah perintah yang dieksekusi pada saat jebakan.
Mengambil kasus sudut perangkap itu, jika saya mengerti dengan benar ini berarti bahwa ketika saya menjalankan perintah, variabel BASH_COMMANDberisi perintah itu. Tidak sepenuhnya jelas apakah variabel itu tidak disetel setelah eksekusi perintah (yaitu, hanya tersedia ketika perintah sedang berjalan, tetapi tidak setelah), meskipun orang mungkin berpendapat bahwa karena itu adalah "perintah saat ini sedang dieksekusi atau akan dieksekusi" , itu bukan perintah yang baru saja dieksekusi.
Tapi mari kita periksa:
$ set | grep BASH_COMMAND=
$
Kosong. Saya akan berharap untuk melihat BASH_COMMAND='set | grep BASH_COMMAND='atau mungkin adil BASH_COMMAND='set', tetapi kosong mengejutkan saya.
Mari kita coba yang lain:
$ echo $BASH_COMMAND
echo $BASH_COMMAND
$
Itu masuk akal. Saya menjalankan perintah echo $BASH_COMMANDdan variabel tersebut BASH_COMMANDberisi string echo $BASH_COMMAND. Mengapa ini bekerja saat ini, tetapi tidak sebelumnya?
Mari kita lakukan setlagi:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Jadi, tunggu. Hal itu ditetapkan ketika saya dieksekusi bahwa echoperintah, dan itu tidak diset setelah itu. Tetapi ketika saya dieksekusi setlagi, BASH_COMMAND tidak diatur ke setperintah. Tidak peduli seberapa sering saya menjalankan setperintah di sini, hasilnya tetap sama. Jadi, apakah variabel ditetapkan ketika menjalankan echo, tetapi tidak ketika menjalankan set? Ayo lihat.
$ echo Hello AskUbuntu
Hello AskUbuntu
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Apa? Jadi variabel ditetapkan ketika saya dieksekusi echo $BASH_COMMAND, tetapi tidak ketika saya dieksekusi echo Hello AskUbuntu? Di mana bedanya sekarang? Apakah variabel hanya disetel ketika perintah saat ini sendiri benar-benar memaksa shell untuk mengevaluasi variabel? Mari kita coba sesuatu yang berbeda. Mungkin beberapa perintah eksternal kali ini, bukan bash builtin, untuk suatu perubahan.
$ /bin/echo $BASH_COMMAND
/bin/echo $BASH_COMMAND
$ set | grep BASH_COMMAND=
BASH_COMMAND='/bin/echo $BASH_COMMAND'
$
Hmm, ok ... lagi, variabelnya sudah diset. Jadi, apakah tebakan saya saat ini benar? Apakah variabel hanya ditetapkan ketika harus dievaluasi? Mengapa? Mengapa? Untuk alasan kinerja? Mari kita coba sekali lagi. Kami akan mencoba grep untuk $BASH_COMMANDdalam file, dan karena itu $BASH_COMMANDharus mengandung grepperintah, grepharus grep untuk grepperintah itu (yaitu, untuk dirinya sendiri). jadi mari kita buat file yang sesuai:
$ echo -e "1 foo\n2 grep\n3 bar\n4 grep \$BASH_COMMAND tmp" > tmp
$ grep $BASH_COMMAND tmp
grep: $BASH_COMMAND: No such file or directory
tmp:2 grep <-- here, the word "grep" is RED
tmp:4 grep $BASH_COMMAND tmp <-- here, the word "grep" is RED
tmp:2 grep <-- here, the word "grep" is RED
tmp:4 grep $BASH_COMMAND tmp <-- here, the word "grep" is RED
$ set | grep BASH_COMMAND=
BASH_COMMAND='grep --color=auto $BASH_COMMAND tmp'
$
Ok, menarik. Perintah grep $BASH_COMMAND tmpmenjadi diperluas ke grep grep $BASH_COMMAND tmp tmp(variabel akan diperluas hanya sekali, tentu saja), dan jadi saya mengerti grep, sekali dalam file $BASH_COMMANDyang tidak ada, dan dua kali dalam file tmp.
T1: Apakah asumsi saya saat ini benar bahwa:
BASH_COMMANDhanya diset ketika sebuah perintah mencoba untuk benar-benar mengevaluasinya; dan- itu tidak diset setelah pelaksanaan perintah, meskipun deskripsi dapat membawa kita untuk percaya begitu?
T2: Jika ya, mengapa? Performa? Jika tidak, bagaimana lagi perilaku dalam urutan perintah di atas dapat dijelaskan?
T3: Terakhir, apakah ada skenario di mana variabel ini sebenarnya bisa digunakan secara bermakna? Saya benar-benar mencoba menggunakannya di dalam $PROMPT_COMMANDuntuk menganalisis perintah yang sedang dieksekusi (dan melakukan beberapa hal tergantung pada itu), tetapi saya tidak bisa, karena begitu, dalam saya $PROMPT_COMMAND, saya menjalankan perintah untuk melihat variabel $BASH_COMMAND, variabel mendapat set ke perintah itu. Bahkan ketika saya melakukan yang MYVARIABLE=$BASH_COMMANDbenar di awal saya $PROMPT_COMMAND, kemudian MYVARIABLEberisi string MYVARIABLE=$BASH_COMMAND, karena tugas juga merupakan perintah. (Pertanyaan ini bukan tentang bagaimana saya bisa mendapatkan perintah saat ini dalam $PROMPT_COMMANDeksekusi. Ada cara lain, saya tahu.)
Ini agak mirip dengan prinsip ketidakpastian Heisenberg. Hanya dengan mengamati variabelnya, saya mengubahnya.
bashüber- gurus yang asli di sana.