Perintah sejarah di dalam skrip bash


20

History adalah perintah shell-built in yang saya tidak bisa menggunakannya dalam skrip BASH. Jadi, apakah ada cara untuk mencapai ini menggunakan skrip BASH?
Ini skrip saya untuk Anda:

#!/bin/bash
history |  tail -100 > /tmp/history.log
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

Jawaban:


32

Bash menonaktifkan riwayat di shell yang tidak aktif secara default, tetapi Anda bisa menyalakannya.

#!/bin/bash
HISTFILE=~/.bash_history
set -o history
history | tail 

Tetapi jika Anda mencoba memonitor aktivitas di server itu, histori shell tidak berguna (itu sepele untuk menjalankan perintah yang tidak muncul dalam histori). Lihat Bagaimana saya bisa mencatat semua proses peluncuran di Linux .

Jika Anda men-debug skrip maka shell history bukan cara terbaik untuk mendapatkan informasi yang bermanfaat. Alat yang jauh lebih baik adalah fasilitas penelusuran jejak: letakkan di set -xdekat bagian atas skrip. Jejak ditulis ke kesalahan standar.


Ini menolak untuk bekerja dalam sebuah skrip:histtest.sh: 5: set: Illegal option -o history
Ken Sharp

4
@ KenSharp Itu karena Anda mencoba untuk menggunakannya dalam skrip sh (dan Anda shberlari menilai dengan kata-kata yang tepat dari pesan kesalahan). Untuk mengakses riwayat bash, Anda perlu menggunakan bash (skrip dimulai dengan #!/bin/bashatau #!/usr/bin/env bash).
Gilles 'SANGAT berhenti menjadi jahat'

1
@ KenSharp Ya itu. Anda jelas menjalankannya di bawah tanda hubung, mengingat pesan kesalahan. Bash tidak memiliki pesan kesalahan Illegal option(katanya set: history: invalid option name).
Gilles 'SANGAT berhenti menjadi jahat'

masalah dengan ini adalah bahwa ia menambahkan semua perintah yang mengikuti set -o history sejarah yang kemudian akan diisi dengan entri seperti if [... vars=$(...dll.
nath

1
@nath Itulah pertanyaan yang diajukan. Ini hampir tidak ada gunanya, seperti yang saya tunjukkan. Kegiatan pemantauan adalah masalah sulit yang tidak bisa dipecahkan oleh riwayat shell. Jika Anda men-debug skrip maka set -xitu jauh lebih berguna.
Gilles 'SO- stop being evil'

6

Saya tidak yakin apakah itu benar-benar menggunakan kemampuan histori saat menjalankan non-interaktif, jika tidak setiap skrip shell yang Anda jalankan akan mengacaukan histori perintah Anda.

Mengapa tidak langsung ke sumbernya ${HOME}/.bash_history, ganti history | tail -100dengan tail -100 ${HOME}/.bash_history. (Jika Anda menggunakan cap waktu, Anda mungkin harus melakukan sesuatu di sepanjang baris grep -v ^# ${HOME}/.bash_history | tail -100).


Memang, dengan cap waktu, Anda seharusnya benar-benar greq -v '^#[0-9]\+$'(kadang-kadang saya "mengeksekusi" komentar di shell saya ...)
PlasmaBinturong

Dan sebenarnya, dalam kasus saya, saya perlu menggunakan nomor baris riwayat yang benar , tetapi ada perbedaan antara output historydan output grepmetode ...
PlasmaBinturong

Ok, memperbaiki itu untuk menyinkronkan daftar sejarah dengan file sejarah seperti ini: history -a; history -c; history -r. (tambahkan, hapus, baca)
PlasmaBinturong

2

Jika Anda ingin menggunakan output dari historyperintah dari sesi shell aktif dalam skrip, Anda dapat menggunakan alias untuk menjalankan perintah terlebih dahulu. Kemudian, dengan alias yang sama, Anda dapat memanggil sisa skrip. Dengan konfigurasi seperti itu, Anda pada dasarnya dapat mencapai hasil yang sama dengan memiliki historyperintah dalam skrip yang sebenarnya.

Misalnya, Anda dapat membuat alias seperti ini, dengan asumsi nama skrip adalah script.sh:

alias hy_tmp='history | tail -100 > /tmp/history.log ; bash /patch/to/script.sh'

Dan ubah skrip menjadi ini:

#!/bin/bash
cd /tmp
uuencode history.log history.txt  | mail -s "History log of server" hello@hel.com

Saya menemukan pertanyaan ini saat menulis proses untuk menggabungkan, mengurutkan dan menyinkronkan ~/bash_historyfile di dua komputer sehingga akan mudah untuk mencari perintah yang saya gunakan di masa lalu.

Jauh lebih mudah untuk memperbarui file kumulatif riwayat saya tanpa harus masuk ke shell baru untuk ~/bash_historymemperbarui. Untuk memonitor server, ini jelas tidak akan berfungsi, seperti yang disebutkan dalam jawaban lain.

Penggunaan saya khususnya adalah:

alias hbye='history | cut -c 8- > /home/chris/.bash_history_c; bash /hby.sh

Script hby.shkemudian menarik semua entri unik dari semua ~/.bash_history*file.



1

Buat skrip bernama script.shseperti di bawah ini. Itu menciptakan skrip bernama X dan menempatkan Y Jumlah baris sejarah Anda ke dalamnya.

#!/bin/bash
SCRIPT_NAME=$1
NUMBER_OF_LINES_BACK=$2

# Enable History in a non interactive shell
HISTFILE=~/.bash_history
set -o history

# echo shabang line and x number of lines of history to new script
echo \#\!\/bin\/bash > $SCRIPT_NAME.sh; history | tail -n $NUMBER_OF_LINES_BACK >> $SCRIPT_NAME.sh;
chmod u+x $SCRIPT_NAME.sh;

# Open the newly created script with vim
vim $SCRIPT_NAME.sh;
~

Kemudian jika Anda ingin membuat skrip untuk menyelesaikan tugas bernama "tugas" yang telah Anda kerjakan selama 14 baris terakhir jalankan

script.sh task 14

Lalu bersihkan riwayat Anda untuk membuat skrip yang bagus!


histtest.sh: 5: set: Illegal option -o history
Ken Sharp

1

Perintah histori dinonaktifkan secara default pada skrip bash itu sebabnya bahkan perintah histori tidak akan berfungsi dalam file .sh. untuk pengalihannya, silakan redirect file bash_history di dalam file .sh.

atau mekanisme histori dapat diaktifkan juga dengan menyebutkan file histori dan mengubah parameter run-time seperti yang disebutkan di bawah ini

#!/bin/bash
HISTFILE=~/.bash_history
set -o history 

catatan: disebutkan di atas dua baris di bagian atas file skrip. sekarang perintah sejarah akan bekerja dalam sejarah.


0

Setiap pengguna memiliki file histori sendiri yang merupakan hasil dari perintah history. Alih-alih menggunakan perintah histori dalam skrip shell Anda, Anda dapat menggunakan file histori untuk pengguna. Akan ada .bash_historyfile di direktori home pengguna, yang akan menjadi file histori untuk pengguna.


-1

Jawaban singkat :

gunakan history -puntuk melakukan ekspansi riwayat secara eksplisit.

Contoh berikut.

Satu kasus penggunaan yang sering terjadi pada saya adalah:

  • perintah sebelumnya dapatkan daftar nama file, dan cetak ke stdout,
  • Saya perlu mengedit file tersebut dengan vim.

Sejak bash saya set -o histexpand, biasanya yang saya lakukan adalah mengetik

vim $(!!)

untuk mengedit file-file yang terdaftar dengan perintah sebelumnya.

Sayangnya terkadang kesalahan terjadi, jadi saya aktifkan verifikasi oleh shopt -s histverify.

Sekarang saya dapat memverifikasi ekspansi, dengan biaya satu Returnkunci tambahan .

Hari ini saya ingin membungkus detail-detail itu menjadi fungsi bash karena saya sering menggunakannya,

function vk() {
    set -o history && set -o histexpand;
    vim -i ~/.viminfok $($(history -p !!));
}

Di sini saya menggunakan dua bersarang command substitution, yang dalam untuk memperluas !!ke perintah sebelumnya, yang luar untuk menjalankannya dan mendapatkan output.

Sekarang saya dapat mencapai efek yang sama, hanya dengan tiga kunci, dan salah satunya adalah Return!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.