Menurut manual Bash , variabel lingkungan BASH_COMMAND
berisi
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_COMMAND
berisi 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_COMMAND
dan variabel tersebut BASH_COMMAND
berisi string echo $BASH_COMMAND
. Mengapa ini bekerja saat ini, tetapi tidak sebelumnya?
Mari kita lakukan set
lagi:
$ set | grep BASH_COMMAND=
BASH_COMMAND='echo $BASH_COMMAND'
$
Jadi, tunggu. Hal itu ditetapkan ketika saya dieksekusi bahwa echo
perintah, dan itu tidak diset setelah itu. Tetapi ketika saya dieksekusi set
lagi, BASH_COMMAND
tidak diatur ke set
perintah. Tidak peduli seberapa sering saya menjalankan set
perintah 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_COMMAND
dalam file, dan karena itu $BASH_COMMAND
harus mengandung grep
perintah, grep
harus grep untuk grep
perintah 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 tmp
menjadi diperluas ke grep grep $BASH_COMMAND tmp tmp
(variabel akan diperluas hanya sekali, tentu saja), dan jadi saya mengerti grep
, sekali dalam file $BASH_COMMAND
yang tidak ada, dan dua kali dalam file tmp
.
T1: Apakah asumsi saya saat ini benar bahwa:
BASH_COMMAND
hanya 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_COMMAND
untuk 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_COMMAND
benar di awal saya $PROMPT_COMMAND
, kemudian MYVARIABLE
berisi string MYVARIABLE=$BASH_COMMAND
, karena tugas juga merupakan perintah. (Pertanyaan ini bukan tentang bagaimana saya bisa mendapatkan perintah saat ini dalam $PROMPT_COMMAND
eksekusi. 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.