Her komuta 'eklenen' takma ad zorlama


11

Her komuta zorla bir zamanlama takma adı eklemek (bunu ifade etmenin daha iyi bir yolu olmadığı için) mümkün müdür bash?

Örneğin, bir komut çalıştırıldığında, her zaman dateönce ve sonra ya da ile sarılmış belirli bir kullanıcıya sahip olmak isterim time.

Bu mümkün mü ve eğer mümkünse nasıl?


Daha önce baktım ve tam olarak bunu yapmanın bir yolunu bulamadım. Caleb'in dediği gibi kullanabilirsiniz preexec, ancak onu preexec(örneğin preexec() { time $1; }) içinde çalıştırmak istemezsiniz , çünkü kabuk preexecgeri döndükten sonra hala çalıştırır . Yani yapabileceğimiz en iyi şey benzer bir şey.
Mikel

@Mikel preexec()Komutu getirerek, onu işlevin içinden kendiniz çalıştırarak ve ardından kabuğun komutu yürütmek için devam etmemesi için bir tür hata döndürerek, işlevi yürütmekte olan her şeyi sarmak için işlevi kullanabileceğinizi düşünüyorum .
Caleb

Yanıtlar:


10

Bir komut satırının başlatıldığı zamanı ve bir istemin görüntülendiği zamanı kaydedebilirsiniz. Bash, geçmişindeki her komut satırının başlangıç ​​tarihini zaten izler ve bir sonraki istemi görüntülediğiniz zamanı not edebilirsiniz.

print_command_wall_clock_time () {
  echo Wall clock time: \
    $(($(date +%s) - $(HISTTIMEFORMAT="%s ";
                       set -o noglob;
                       set $(history 1); echo $2)))
}
PROMPT_COMMAND=print_command_wall_clock_time$'\n'"$PROMPT_COMMAND"

Bu size yalnızca ikinci çözünürlük ve sadece duvar saati süresini verir. Daha iyi çözünürlük istiyorsanız, nanosaniye biçimini datedestekleyen bir harici komut kullanmanız ve komutu zamana çalıştırmadan önce aramak %Niçin DEBUGtuzak kullanmanız dategerekir.

call_date_before_command () {
  date_before=$(date +%s.%N)
}
print_wall_clock_time () {
  echo Wall clock time: \
    $((date +"$date_before - %s.%N" | bc))
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_command_wall_clock_time

Tuzakla bile, DEBUGher komut için işlemci sürelerini otomatik olarak göstermenin veya istem isteminden daha ayrımcı olmanın bir yolu olduğunu düşünmüyorum.


Farklı bir kabuk kullanmak istiyorsanız, zsh'daki her komut için nasıl zaman raporu alacağınız aşağıda açıklanmıştır (bu, diğer görevler için genelleştirilmez):

REPORTTIME=0

REPORTTIMEHerhangi bir tamsayı değerine ayarlayabilirsiniz , zamanlama bilgisi yalnızca işlemci süresinin bu saniyeden daha fazlasını kullanan komutlar için görüntülenir.

Zsh bu özelliği değişkenin çağrıldığı csh'den almıştır time.


3

Buradaki seçenekleriniz kabuğunuza bağlı olacaktır. Gelen zshdiye bir uygun kanca fonksiyonu preexec()herhangi interaktif kabuk komutları önce sağ çalıştırılır. Bu adda bir işlev oluşturarak işlerin yürütülmesine neden olabilirsiniz. Ayrıca adında bir işlevle takip edebilirsiniz precmd()hemen sonra olacak bir sonraki istemi çizilir önce sadece çalışır, sizin komuta bittikten.

Bu işlev çiftini oluşturarak, komut isteminde verilen komutlardan önce ve sonra çalıştırılmasını istediğiniz rasgele komutlara sahip olabilirsiniz. Kabuk kullanımını günlüğe kaydetmek, kilitler oluşturmak, ortamı test etmek veya örneğinizde olduğu gibi bir komut çalışırken harcanan zamanı veya kaynakları hesaplamak için bunu kullanabilirsiniz.

Bu örnekte, bir komutu çalıştırmadan önce kendimize bir kıyaslama zaman damgası oluşturacağız, preexec()ardından komutu kullanarak yürütmek için harcanan zamanı hesaplayacağız ve komut precmd()isteminden önce çıktısını vereceğiz veya oturumdan çıkaracağız . Misal:

preexec() {
   CMDSTART=$(date +%s%N)
}
precmd() {
   CMDRUNTIME=$(($(date +%s%N)-$CMDSTART))
   echo "Last command ran for $CMDRUNTIME nanoseconds."
}

Not: Bu özel örnek için, daha da kolay bir yerleşik işlev vardır. Yapmanız gereken tek şey ZSH'de çalışma zamanı raporlamasını açmaktır ve bunu otomatik olarak yapar.

$ export REPORTTIME=0
$ ls -d
./
ls -BF --color=auto -d  0.00s user 0.00s system 0% cpu 0.002 total

Daha pratik uygulamasında preexec(), ben kabuk içinde çalışıyorsa görmek kullanabilir tmuxveya screensekme adının görüntülenmesini anda çalışan komut memba hakkında bilgi göndermek için, eğer öyleyse, ve.

Ne yazık ki bash'da bu küçük mekanizma mevcut değil. İşte bir erkeğin onu çoğaltma girişimi . Ayrıca benzer zarif küçük kesmek için Gilles'in cevabına bakınız .




Bu bash mevcut olsaydı!
warren

Bkz Gilles 'ler ve diğerleri bağlantıları, biraz ekstra bir işe yaramaz ile bash uygulanabilir olduğunu. Tekrar, neden sadece zsh kullanmıyorsun? Geçiş yapmak için bundan daha iyi nedenleri olan bir sallanan kabuk!
Caleb

2
Eğer zsh kullanıyorsanız bunu yapmanın daha iyi bir yolu var. Ayarlandığında REPORTTIME ortam değişkeni, $ REPORTTIME saniyeden uzun süren herhangi bir komut için yürütme süresi bilgisini (komutu 'önünde' zamanla çalıştırmış gibi) verir. Sadece 0 olarak ayarlayın ve önyükleme için kullanıcı / sys dökümü ile size her komutun zamanını söylemelidir.
Joseph Garvin

1

En kolay yol muhtemelen ayarlanacaktır PROMPT_COMMAND. Bkz. Bash Değişkenleri :

PROMPT_COMMAND
Ayarlanmışsa, değer her birincil istemin ( $PS1) yazdırılmasından önce yürütülecek bir komut olarak yorumlanır .

Örneğin, varolan herhangi bir komut isteminin üzerine yazılmasını önlemek için şunları yapabilirsiniz:

PROMPT_COMMAND="date ; ${PROMPT_COMMAND}"

bunu bilmiyordum - iyi bir başlangıç ​​gibi görünüyor, @cjm
warren

1
Bu bir başlangıç, ancak bir komutun ne zaman çalıştırıldığını bilme sorununu ele almıyor. Komutun kendisi bir komutun yazılmasından ve çalıştırılmasından dakikalar, saatler veya günler önce çizilebilir.
Caleb

0

csh/ tcshbu özellik için en iyi desteğe sahiptir (ve her zaman sahip olmuştur).

  The `time` shell variable can be set to execute the time builtin  command
  after the completion of any process that takes more than a given number
  of CPU seconds.

Başka bir deyişle, set time=1işlemci süresini 1 saniyeden fazla alan herhangi bir komutla tüketilen zamanı (sistem, kullanıcı, geçen) yazdıracaktır. Düz set time, tüm komutların zamanının yazdırılmasını sağlar.

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.