2012-04-28 4 views
6

Perl'in Time :: HiRes modülünü geçen süreyi hesaplamak için çağıran bir komut dosyası var. geri keneler aracılığıyla Perl tercümanaKabuk betiği değişkeninde saklanan Perl kodunu nasıl uygularım?

use Time::HiRes qw(time); print time 

ve sonuçları geri döndük: Temelde komut aşağıdaki tek astar geçirerek zaman alır.

#/bin/sh 

START_TIME=`perl -e 'use Time::HiRes qw(time); print time'` 
END_TIME=`perl -e 'use Time::HiRes qw(time); print time'` 
ELAPSED_TIME=$(echo "($END_TIME - $START_TIME)" | bc) 
echo $ELAPSED_TIME 

Ben daha modüler bir şekilde yeniden yazmak çalıştım ama bash kabuğunun alıntı kurallarına stumped.

#/bin/sh 
CALCULATE='bc' 
NOW="perl -e 'use Time::HiRes qw(time); print time'" 
START_TIME=`$NOW` 
[Some long running task ...] 
ELAPSED_TIME=$(echo "($NOW - $START_TIME)" | $CALCULATE) 
echo $ELAPSED_TIME 

Bash şey düzgün alıntı olmadığını şikayet ediyor. Neden bash sadece komutu $ NOW olarak genişletir ve idam edilecek olan arka kene için iletir?

Bir kabuk betiği değişkenine perl kodunu gömmek için çeşitli yollar denedim, ancak dosyasını doğru şekilde göremiyorum.

Herkes, kabuk betikindeki perl kodunun nasıl doğru bir şekilde yazılacağını bilir? Bir fonksiyonu kullanarak

+0

@ Mat'da bas saatini kullanabilirsiniz. Kişilerin daha kolay yanıt vermesini sağlamak için çok daha büyük bir komut dosyasından bir alıntı yaptım. Kestim ve yanlış yapıştırdım. İşaret ettiğin için teşekkürler. Sabit. Ama sorun yine de alıntıdır. – GeneQ

+1

FYI, perl one-liner'ınızı 'perl -MTime :: HiRes = time -e' print time 'olarak yazabilirsiniz –

cevap

7

Bunu yapmanın en basit yolu, sanırım:

#! /bin/bash 

now() { 
    perl -e 'use Time::HiRes qw(time); print time'; 
} 

calc=bc 
time1=$(now) 
time2=$(now) 
elapsed=$(echo $time2 - $time1 | $calc) 
echo $elapsed $time1 $time2 

Esasen hiçbir gereklidir tırnaklama.

+0

Bu kadar! Aptal ben. Bir kutuda takılmaktan bahsedin. Bazen Bash'in tam bir programlama dili olduğunu unutuyorum. Teşekkürler. – GeneQ

3

Sorununuz, $NOW'un yalnızca içinde bazı perl kodlarına sahip bir dize olmasıdır. Sen ters tırnakların ya $() ile çalıştırabiliyor bash söylemek gerekir: Ayrıca

ELAPSED_TIME=$(echo "($($NOW) - $START_TIME)" | $CALCULATE) 

, bash doğal aritmetik yapabilirsiniz:

ELAPSED_TIME=$(($($NOW) - $START_TIME)) 

bc çağırmak gerek yok.

Son olarak, perl'i başlatmak ve durdurmak büyük olasılıkla çok zaman alacaktır, bu da sonuçlarınıza gürültü katacaktır. Perl'i sadece bir kez çalıştırmayı ve perl'in uzun süren görevi yerine getirmesini tavsiye ederim. Daha sonra hem Perl kendi içinde bütün hesaplama yapardım:

#!/usr/bin/perl 

use Time::HiRes qw(time); 

my $start = time; 
system(@ARGV); 
my $end = time; 

print "Elapsed: ", ($end - $start), "\n" 

Ya da sadece bash time (veya /usr/bin/time) sadece doğrudan tüm zamanlama yapmak yerleşik kullanabilirsiniz.

+0

Perl yorumlayıcı yükleme süresi hakkında iyi bir nokta var. Ama bu benim sürdürdüğüm eski bir kod, bu yüzden çok fazla değiştirmek istemiyorum. Perl'e geçmek onu tasvir ediyor, refakatsiz değil ve bu biraz fazla iş. Her gün saf Perl'e yazmayı tercih ederim. – GeneQ

+4

"bc çağırmaya gerek yok" - bash (ve 'expr ') ondalık sayılarla aritmetiği kullanmaz. – Mat

+0

@Mat, ah, evet, zsh, beni biraz attı – bdonlan

1

$NOW, tırnak işaretlerinin dışındaysa, boşlukta bölünür.

$ perl -E'say [email protected]; say for @ARGV' $NOW 
7 
perl 
-e 
'use 
Time::HiRes 
qw(time); 
print 
time' 

Buna önlemek için çift tırnak tarafından değişkeni çevreleyebilir:

$ perl -E'say [email protected]; say for @ARGV' "$NOW" 
1 
perl -e 'use Time::HiRes qw(time); print time' 

Ama bir kabuk komutu olarak bu dize yürütmek istiyoruz. Bunun için eval kullanın.

$ eval "$NOW" 
1335602750.57325 

Son olarak, atamak için, biz komutu ters tırnak (veya eşdeğer $(...)) kullanın.
$ START_TIME=$(eval "$NOW") 
$ echo $START_TIME 
1335602898.78472 

önceden yayınlanan fonksiyon

açıkçası temizleyici, ama sen alıntı yardım istediğini söyledi. Bu arada

,

perl -e 'use Time::HiRes qw(time); print time' 

perl -MTime::HiRes=time -e'print time' 

ve hatta kısaltılabilir (arka yeni satır mükemmel iyi olduğu için) Aşağıdaki:

perl -MTime::HiRes=time -E'say time' 

Ya da gerçekten gol istediyseniz f:

aşağıda
perl -MTime::HiRes=time -Esay+time 
+1

Renk için sonunda biraz ekledi. – ikegami

0

senin yazısının değiştirilmiş versiyonu, temelde bazı uygulamalar (standart hata) stderr'e doğru thiere standart çıktıyı olduğunu anlamamız gerekir böylece görmüyorum zaman onların çıkış bir değişkene koymak sen sadece

#/bin/sh 
CALCULATE='bc' 
echo 'starting' 
NOW=$(perl -e 'use Time::HiRes qw(time); print time' 2>&1) 
sleep 3 
echo 'ending' 
END_TIME=$(perl -e 'use Time::HiRes qw(time); print time' 2>&1) 
ELAPSED_TIME=$(echo "($NOW - $START_TIME)") 
echo $ELAPSED_TIME 
0

Ben kullanım çözünürlüklü zaman fayda perl nispeten ağır dış süreçtir ve ayrı iki kez başlatıldı gerçeği tarafından etkisiz düşünüyorum stdout'u (standart outputp) yönlendirebilirsiniz gerekir. Değer için bu çok ondalık basamağa ihtiyacınız yoksa.