2013-06-04 11 views
69

verstrichene ich ein Skript in bash zu schreiben, die Zeit für die Ausführung meiner Befehle verstrichene zu berechnen, betrachten:Linux - Bash-Skript zu berechnen Zeit

STARTTIME=$(date +%s) 
#command block that takes time to complete... 
#........ 
ENDTIME=$(date +%s) 
echo "It takes $($ENDTIME - $STARTTIME) seconds to complete this task..." 

Ich denke, meine Logik aber richtig ist ich am Ende mit der folgende Ausdruck:

„Es dauert Sekunden, um diese Aufgabe zu erfüllen ...“

alles falsch mit meiner String Auswertung ???

Ich glaube, dass Bash-Variablen untypisiert sind, würde ich lieben, wenn es eine "String to Integer" -Methode in bash gibt.

+0

@OmnipotentEntity: Sie können dies als eine Antwort zu machen? –

+0

Sicher Ding Michael Mao. – OmnipotentEntity

Antwort

52

Entweder $(()) oder $[] wird für die Berechnung des Ergebnisses einer arithmetischen arbeiten Betrieb. Sie verwenden $(), die einfach die Zeichenfolge nimmt und sie als Befehl auswertet. Es ist ein bisschen eine subtile Unterscheidung. Hoffe das hilft.

Wie in den Kommentaren zu dieser Antwort hingewiesen, $[] ist veraltet, und $(()) sollte bevorzugt werden.

+4

Vielleicht möchten Sie diese beiden umgehen, da bash 4.x man-page besagt, dass ** ** [] ** veraltet ist und in zukünftigen Versionen entfernt wird. – tink

+1

Danke, mir war nicht bewusst. – OmnipotentEntity

42

Sie versuchen, die Nummer in ENDTIME als Befehl auszuführen. Sie sollten auch einen Fehler wie 1370306857: command not found sehen. Verwenden Sie stattdessen die arithmetic expansion:

echo "It takes $(($ENDTIME - $STARTTIME)) seconds to complete this task..." 

Sie auch die Befehle in einem separaten Skript speichern könnte, commands.sh und Zeit Befehl:

time commands.sh 
1

Versuch mit der verstrichenen Sekunden Option Zeit:

/usr/bin/time -f%e sleep 1 unter bash.

oder \time -f%e sleep 1 in interaktiver Bash.

finden Sie in die Zeit Manpage:

Nutzer des Bash-Shell müssen einen expliziten Pfad verwenden, um den externen Zeitbefehl und nicht die Shell-builtin Variante ausgeführt werden.Auf System , wo die Zeit in/usr/bin installiert ist, wäre das erste Beispiel /usr/bin/Zeit WC/etc/hosts

und

FORMATTING THE OUTPUT 
... 
    %  A literal '%'. 
    e  Elapsed real (wall clock) time used by the process, in 
       seconds. 
+0

'/ bin/time' wird hier nicht funktionieren: OP erwähnt einen _block_. Also brauchen wir hier wirklich das Keyword 'time'. –

5

Versuchen Sie, den folgenden Code werden:

start=$(date +'%s') && sleep 5 && echo "It took $(($(date +'%s') - $start)) seconds" 
18

Sie können time Keywords Bash hier mit einem entsprechenden Format-String

TIMEFORMAT='It takes %R seconds to complete this task...' 
time { 
    #command block that takes time to complete... 
    #........ 
} 

Hier ist, was die reference says about TIMEFORMAT:

Der Wert dieses Parameters wird als Format-String verwendet angibt, wie die Zeitinformationen für das time reservierte Wort Präfix Pipelines angezeigt werden sollen. Das Zeichen '%' führt eine Escape-Sequenz ein, die zu einem Zeitwert oder anderen Informationen erweitert wird. Die Escape-Sequenzen und ihre Bedeutungen sind wie folgt; die Klammern bezeichnen optionale Teile.

%% 

    A literal ‘%’. 
%[p][l]R 

    The elapsed time in seconds. 
%[p][l]U 

    The number of CPU seconds spent in user mode. 
%[p][l]S 

    The number of CPU seconds spent in system mode. 
%P 

    The CPU percentage, computed as (%U + %S)/%R. 

Die optionalen p ist eine Ziffer, die Genauigkeit, die Anzahl der Nachkommastellen nach einem Dezimalpunkt angibt. Ein Wert von 0 bewirkt, dass kein Dezimalpunkt oder Bruch ausgegeben wird. Höchstens drei Stellen nach dem Dezimalpunkt dürfen angegeben werden; Werte von p größer als 3 werden zu 3 geändert. Wenn p nicht angegeben ist, wird der Wert 3 verwendet.

Das optionale l gibt ein längeres Format (einschließlich Minuten) des Formulars MMmSS.FFs an. Der Wert p bestimmt, ob der Bruch enthalten ist oder nicht.

Wenn diese Variable nicht gesetzt ist, wirkt Bash, als ob es den Wert hatte

$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS' 

Wenn der Wert Null ist, wird keine Zeitinformationen angezeigt. Ein abschließender Zeilenumbruch wird hinzugefügt, wenn die Formatzeichenfolge angezeigt wird.

74

Ich finde es sehr sauber, die interne Variable "SECONDS $" verwenden

SECONDS=0 ; sleep 10 ; echo $SECONDS

+2

wunderbar, dest es Nebenwirkungen haben? – g13013

+3

Nur Erfolg =) –

+0

Brauchen Sie Erfolg, verwenden Sie Ihre – Gromish

-1
start=$(date +%Y%m%d%H%M%S); 
for x in {1..5}; 
do echo $x; 
sleep 1; done; 
end=$(date +%Y%m%d%H%M%S); 
elapsed=$(($end-$start)); 
ftime=$(for((i=1;i<=$((${#end}-${#elapsed}));i++)); 
     do echo -n "-"; 
     done; 
     echo ${elapsed}); 
echo -e "Start : ${start}\nStop : ${end}\nElapsed: ${ftime}" 

Start : 20171108005304 
Stop : 20171108005310 
Elapsed: -------------6 
0
#!/bin/bash 

    time_elapsed(){ 
    appstop=$1; appstart=$2 

    ss_strt=${appstart:12:2} ;ss_stop=${appstop:12:2} 
    mm_strt=${appstart:10:2} ;mm_stop=${appstop:10:2} 
    hh_strt=${appstart:8:2} ; hh_stop=${appstop:8:2} 
    dd_strt=${appstart:6:2} ; dd_stop=${appstop:6:2} 
    mh_strt=${appstart:4:2} ; mh_stop=${appstop:4:2} 
    yy_strt=${appstart:0:4} ; yy_stop=${appstop:0:4} 

    if [ "${ss_stop}" -lt "${ss_strt}" ]; then ss_stop=$((ss_stop+60)); mm_stop=$((mm_stop-1)); fi 
    if [ "${mm_stop}" -lt "0" ]; then mm_stop=$((mm_stop+60)); hh_stop=$((hh_stop-1)); fi 
    if [ "${mm_stop}" -lt "${mm_strt}" ]; then mm_stop=$((mm_stop+60)); hh_stop=$((hh_stop-1)); fi 
    if [ "${hh_stop}" -lt "0" ]; then hh_stop=$((hh_stop+24)); dd_stop=$((dd_stop-1)); fi 
    if [ "${hh_stop}" -lt "${hh_strt}" ]; then hh_stop=$((hh_stop+24)); dd_stop=$((dd_stop-1)); fi 

    if [ "${dd_stop}" -lt "0" ]; then dd_stop=$((dd_stop+$(mh_days $mh_stop $yy_stop))); mh_stop=$((mh_stop-1)); fi 
    if [ "${dd_stop}" -lt "${dd_strt}" ]; then dd_stop=$((dd_stop+$(mh_days $mh_stop $yy_stop))); mh_stop=$((mh_stop-1)); fi 

    if [ "${mh_stop}" -lt "0" ]; then mh_stop=$((mh_stop+12)); yy_stop=$((yy_stop-1)); fi 
    if [ "${mh_stop}" -lt "${mh_strt}" ]; then mh_stop=$((mh_stop+12)); yy_stop=$((yy_stop-1)); fi 

    ss_espd=$((10#${ss_stop}-10#${ss_strt})); if [ "${#ss_espd}" -le "1" ]; then ss_espd=$(for((i=1;i<=$((${#ss_stop}-${#ss_espd}));i++)); do echo -n "0"; done; echo ${ss_espd}); fi 
    mm_espd=$((10#${mm_stop}-10#${mm_strt})); if [ "${#mm_espd}" -le "1" ]; then mm_espd=$(for((i=1;i<=$((${#mm_stop}-${#mm_espd}));i++)); do echo -n "0"; done; echo ${mm_espd}); fi 
    hh_espd=$((10#${hh_stop}-10#${hh_strt})); if [ "${#hh_espd}" -le "1" ]; then hh_espd=$(for((i=1;i<=$((${#hh_stop}-${#hh_espd}));i++)); do echo -n "0"; done; echo ${hh_espd}); fi 
    dd_espd=$((10#${dd_stop}-10#${dd_strt})); if [ "${#dd_espd}" -le "1" ]; then dd_espd=$(for((i=1;i<=$((${#dd_stop}-${#dd_espd}));i++)); do echo -n "0"; done; echo ${dd_espd}); fi 
    mh_espd=$((10#${mh_stop}-10#${mh_strt})); if [ "${#mh_espd}" -le "1" ]; then mh_espd=$(for((i=1;i<=$((${#mh_stop}-${#mh_espd}));i++)); do echo -n "0"; done; echo ${mh_espd}); fi 
    yy_espd=$((10#${yy_stop}-10#${yy_strt})); if [ "${#yy_espd}" -le "1" ]; then yy_espd=$(for((i=1;i<=$((${#yy_stop}-${#yy_espd}));i++)); do echo -n "0"; done; echo ${yy_espd}); fi 

    echo -e "${yy_espd}-${mh_espd}-${dd_espd} ${hh_espd}:${mm_espd}:${ss_espd}" 
    #return $(echo -e "${yy_espd}-${mh_espd}-${dd_espd} ${hh_espd}:${mm_espd}:${ss_espd}") 
    } 

    mh_days(){ 
    mh_stop=$1; yy_stop=$2; #also checks if it's leap year or not 

    case $mh_stop in 
    [1,3,5,7,8,10,12]) mh_stop=31 
    ;; 
    2) ((!(yy_stop % 4) && (yy_stop % 100 || !(yy_stop % 400)))) && mh_stop=29 || mh_stop=28 
    ;; 
    [4,6,9,11]) mh_stop=30 
    ;; 
    esac 

    return ${mh_stop} 
    } 

    appstart=$(date +%Y%m%d%H%M%S); read -p "Wait some time, then press nay-key..." key; appstop=$(date +%Y%m%d%H%M%S); elapsed=$(time_elapsed $appstop $appstart); echo -e "Start...: ${appstart:0:4}-${appstart:4:2}-${appstart:6:2} ${appstart:8:2}:${appstart:10:2}:${appstart:12:2}\nStop....: ${appstop:0:4}-${appstop:4:2}-${appstop:6:2} ${appstop:8:2}:${appstop:10:2}:${appstop:12:2}\n$(printf '%0.1s' "="{1..30})\nElapsed.: ${elapsed}" 

    exit 0 


-------------------------------------------- return 
Wait some time, then press nay-key... 
Start...: 2017-11-09 03:22:17 
Stop....: 2017-11-09 03:22:18 
============================== 
Elapsed.: 0000-00-00 00:00:01 
Verwandte Themen