Saya mencoba membuat skrip bash yang akan menyimpan histori terminal ke file bernama hist.txt. Penggunaan history > hist.txt
tampaknya tidak berfungsi di skrip bash, tetapi berfungsi dengan baik saat dieksekusi di baris perintah.
Bimbingan apa pun sangat dihargai.
Judy terima kasih
~/.bash_history
.Jawaban:
Jawaban singkat
Jalankan skrip dengan
source
atau.
:atau
Yang terakhir ini sedikit lebih kompatibel di berbagai shell.
Jawaban panjang
Pertanyaan ini menyoroti poin penting, yaitu skrip shell dijalankan dalam konteksnya sendiri. Untuk melihat apa artinya ini, pertimbangkan skrip shell berikut:
Jika Anda menjalankan ini, Anda akan mendapatkan hasil seperti ini:
Tetapi Anda akan melihat bahwa setelah Anda menjalankan skrip, Anda masih berada di direktori apa pun Anda berada sebelum menjalankannya: bagian
cd /
dalam skrip tidak benar-benar memengaruhi sesi Anda - itu hanya memengaruhi konteks tempat skrip dijalankan, yang dibuat untuk menjalankan skrip, dan dihancurkan begitu kembali.The
source
perintah akan 'membaca dan menjalankan perintah dari argumen nama file di shell saat ini konteks', sehingga setiap perintah seperticd
di dalamnya akan mempengaruhi sesi Anda saat ini. Jika Anda menjalankan skrip di atas dengan mengirimkannya kepadasource
Anda, Anda akan menemukan bahwa Anda berakhir di dalam direktori root setelah dijalankan.Dalam kasus ini, masalahnya adalah bahwa
history
perintah tersebut memberi Anda sejarah untuk konteks shell saat ini; konteks shell yang dijalankan skrip Anda tanpa menggunakansource
tidak memiliki riwayat, sehingga skrip tidak menulis apa pun ke file output. Jika Anda menggunakannyasource
akan mengeksekusi dalam konteks yang benar, dan akan berfungsi seperti yang diharapkan.NB:
source
adalah built-in shell, bukan program per se - di Bash,source
identik dengan.
, tetapi dalam beberapa shell hanya.
akan bekerja - Saya telah menggunakansource
jawaban ini karena lebih mudah dibaca daripada.
, tetapi untuk kompatibilitas maksimum,.
harus digunakan.sumber
Pertama-tama, perhatikan bahwa riwayat Anda sudah ada dalam file. Jika Anda menjalankan bash, biasanya namanya
~/.bash_history
. Lebih khusus, itu adalah apa pun yang Anda atur variabelnyaHISTFILE
. Jika Anda ingin menyalinnya ke file lain, jalankan sajacat "$HISTFILE" > hist.txt
Sekarang, mengapa
history
perintah tidak bekerja dalam skrip bash shell, itu karena skrip dijalankan dalam cangkang anak non-interaktif dari sesi shell Anda saat ini. Kerang anak tidak mewarisi semua lingkungan induk (jadi tidak semua variabel yang ditetapkan), hanya variabel yang telah diekspor. Untuk menggambarkan, skrip di bawah ini akan menggemakan nilai variabel$var
:Sekarang, atur
$var
sesuatu dan jalankan skrip:Selanjutnya, ekspor variabel terlebih dahulu:
Seperti yang Anda lihat, ketika variabel telah diekspor, itu tersedia untuk shell anak.
Seperti yang saya sebutkan sebelumnya, riwayat disimpan dalam file yang ditunjukkan oleh variabel
$HISTFILENAME
. Karena itu tidak diekspor secara default, itu tidak disetel saat menjalankan skrip:Seperti yang Anda lihat dalam contoh di atas, variabel
HISTFILE
diatur dalam sesi shell normal saya, tetapi kosong saat menjalankan skrip.Jadi, untuk mendapatkan riwayatnya, Anda memiliki beberapa opsi:
Nilai standarnya
HISTFILE
adalah$HOME/.bash_history
. Jika Anda belum mengubahnya, Anda bisa menjalankan perintah ini di skrip Anda:Anda bisa meneruskan
$HISTFILE
variabel ke skrip Anda dancat
itu:Simpan di atas sebagai
foo.sh
dan jalankan seperti ini:Pastikan variabel diekspor. Tambahkan baris ini ke file Anda
~/.bash_profile
(jika ada) atau~/.profile
(jika~/.bash_profile
tidak ada):Kemudian, keluar dan masuk kembali dan Anda harus dapat lari
history > hist.txt
dari skrip seperti yang diharapkan. Ini karenaexport VAR
berarti "sediakan $ VAR untuk kulit anak". Dalam istilah praktis, ini berarti bahwa nilaiHISTFILE
akan diwarisi oleh shell non-interaktif yang Anda gunakan untuk menjalankan skrip Anda.Sekarang, sementara
HISTFILE
akan diatur, itu belum dibaca oleh shell menjalankan skrip. Jadi, untuk membuatnya bekerja, Anda harus membacanyahistory -r
terlebih dahulu. Seluruh skrip akan terlihat seperti ini:Atau, cukup ekspor secara manual sebelum menjalankan skrip:
Tapi Anda masih harus melakukannya
history -r
di skrip.Anda dapat
source
melakukannya seperti yang disarankan oleh jawaban @ p0llard .sumber