Bh betiğinin içindeki geçmiş komutu


20

Tarih bir BASH betiği içinde kullanamadım bir kabuk yerleşik komut. Peki, BASH betiğini kullanarak bunu elde etmenin bir yolu var mı?
İşte senaryomu senin için gidiyoruz:

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

Yanıtlar:


32

Bash, varsayılan olarak etkileşimli olmayan kabuklardaki geçmişi devre dışı bırakır, ancak açabilirsiniz.

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

Ancak bu sunucudaki etkinliği izlemeye çalışıyorsanız, kabuk geçmişi işe yaramaz (geçmişte görünmeyen komutları çalıştırmak önemsizdir). Linux'ta tüm işlem başlatmalarını nasıl kaydedebilirim konusuna bakın .

Bir komut dosyasında hata ayıklama yapıyorsanız, kabuk geçmişi yararlı bilgiler almanın en iyi yolu değildir. Çok daha iyi bir araç, hata ayıklama izleme özelliğidir: set -xbetiğin en üstüne koyun . Izleme standart hataya yazılır.


Bu bir senaryoda çalışmayı reddediyor:histtest.sh: 5: set: Illegal option -o history
Ken Sharp

4
@KenSharp Bir sh komut dosyasında kullanmaya çalıştınız (ve shhata mesajının tam ifadesi ile kısa çizginiz var). Bash geçmişine erişmek için bash ( #!/bin/bashveya ile başlayan komut dosyası) kullanmanız gerekir #!/usr/bin/env bash.
Gilles 'SO- kötü olmayı bırak'

1
@KenSharp Evet öyle. Hata mesajı göz önüne alındığında, bunu çizgi altında çalıştırdınız. Bash hata mesajına sahip değildir Illegal option(söyler set: history: invalid option name).
Gilles 'SO- kötü olmayı bırak'

Bu sorun aşağıdaki tüm komutlar ekler olmasıdır set -o history sonra böyle girdilerin sürekli doldurulmuş olacak tarihine if [... vars=$(...vs.
Nath

1
@nath Sorunun sorduğu şey buydu. Belirttiğim gibi, hemen hemen anlamsız. Etkinliği izlemek kabuk geçmişinin çözemeyeceği zor bir sorundur. Bir komut dosyasında hata ayıklama yapıyorsanız set -xçok daha kullanışlı olur.
Gilles 'SO- kötü olmayı bırak'

6

Etkileşimli olmayan bir şekilde çalışırken gerçekten tarih özelliğini kullanıp kullanmadığından emin değilim, aksi takdirde çalıştırdığınız her kabuk komut dosyası komut geçmişinizi karmaşık hale getirir.

Kaynağına doğrudan gitmek değil neden ${HOME}/.bash_historyyerine history | tail -100sahip tail -100 ${HOME}/.bash_history. (Zaman damgalarını kullanırsanız, muhtemelen satırlarında bir şeyler yapmanız gerekir grep -v ^# ${HOME}/.bash_history | tail -100).


Gerçekten de, zaman damgaları ile, aslında greq -v '^#[0-9]\+$'(bazen benim kabuğu "yorum" yürütmek gerekir ...)
PlasmaBinturong

Ve aslında, benim durumumda, doğru geçmiş satır numarasını kullanmam gerekiyor , ancak yöntemin historyçıktısı ve çıktısı arasında bir fark var grep...
PlasmaBinturong

Tamam, düzeltme böyle geçmiş dosyası ile geçmiş listesini senkronize etmek oldu: history -a; history -c; history -r. (ekle, temizle, oku)
PlazmaBinturong

2

historyKomut dosyasının çıktısını bir komut dosyasında etkin bir kabuk oturumundan kullanmak istiyorsanız, önce komutu çalıştırmak için bir diğer ad kullanabilirsiniz. Ardından, aynı takma adda, komut dosyasının geri kalanını çağırabilirsiniz. Böyle bir yapılandırma ile, historygerçek komut dosyasında komutun bulunmasıyla aynı sonucu elde edebilirsiniz .

Örneğin, komut dosyasının adının script.sh olduğunu varsayarak böyle bir takma ad oluşturabilirsiniz:

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

Ve betiği şu şekilde değiştirin:

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

Bu soruyu ~/bash_history, iki bilgisayarda dosyaları birleştirmek, sıralamak ve senkronize etmek için bir işlem yazarken buldum, böylece geçmişte kullandığım komutları aramak kolay olacak.

Kümülatif geçmiş dosyamı güncellemek için yeni bir kabukta oturum açmak zorunda kalmadan güncellemek çok daha az zor ~/bash_history. Bir sunucuyu izlemek için, diğer cevaplarda belirtildiği gibi, bu kesinlikle çalışmaz.

Özellikle benim kullanımım:

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

Komut dosyası hby.shdaha sonra tüm ~/.bash_history*dosyalardan tüm benzersiz girişleri alır .



1

script.shAşağıdaki gibi bir komut dosyası oluşturun . X adında bir komut dosyası oluşturur ve Y Geçmişinizin satır sayısını içine koyar.

#!/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;
~

Sonra son 14 satır çalıştırmak için üzerinde çalıştığınız "görev" adlı bir görevi gerçekleştirmek için bir komut dosyası oluşturmak istiyorsanız

script.sh task 14

Sonra güzel bir senaryo yapmak için geçmişinizi temizleyin!


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

1

Geçmiş komutu bash betiğinde varsayılan olarak devre dışıdır, bu nedenle geçmiş komutu bile .sh dosyasında çalışmaz. yeniden yönlendirmesi için bash_history dosyasını .sh dosyasının içine yönlendirin.

veya geçmiş mekanizması, geçmiş dosyasından bahsedilerek ve aşağıda belirtildiği gibi çalışma zamanı parametrelerini değiştirerek de etkinleştirilebilir

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

not: yukarıda kod dosyasının üstünde iki satırdan bahsedilmiştir. şimdi tarih komutu tarihte çalışacaktır.


0

Her kullanıcının geçmiş komutunun sonucu olan kendi geçmiş dosyası vardır. Kabuk betiğinizde geçmiş komutunu kullanmak yerine kullanıcı için geçmiş dosyasını kullanabilirsiniz. .bash_historyKullanıcının giriş dizininde, kullanıcının geçmiş dosyası olacak bir dosya olacaktır.


-1

Kısa cevap :

history -pgeçmiş genişlemesi gerçekleştirmek için kullanın .

Bir örnek aşağıdadır.

Bir kullanım örneği benim için çok şey oluyor:

  • önceki komut dosya adlarının bir listesini alır ve stdout'a yazdırır,
  • Bu dosyayı vim ile düzenlemem gerekiyor.

Benim bashım olduğu için set -o histexpand, genellikle yaptığım şey yazmak

vim $(!!)

önceki komut tarafından listelenen dosyaları düzenlemek için.

Ne yazık ki bazen hata olur, bu yüzden doğrulamayı etkinleştiririm shopt -s histverify.

Artık bir ekstra Returnanahtarın maliyetiyle genişletmeyi doğrulayabilirim .

Bugün bu ayrıntıları bash fonksiyonuna sarmak istiyorum, çünkü onları çok kullanıyorum,

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

Burada iki iç içe command substitution, bir iç !!komut önceki komut genişletmek için, dış bir yürütmek ve çıktı almak için kullanın.

Şimdi aynı etkiyi sadece üç anahtarla elde edebilirim ve bunlardan biri Return!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.