Câu hỏi Kịch bản Bash để tính thời gian trôi qua


Tôi đang viết một kịch bản trong bash để tính thời gian trôi qua để thực hiện các lệnh của tôi, hãy xem xét:

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

Tôi đoán logic của tôi là chính xác tuy nhiên tôi kết thúc với các bản in sau:

"Phải mất vài giây để hoàn thành nhiệm vụ này ..."

Bất cứ điều gì sai với đánh giá chuỗi của tôi?

Tôi tin rằng các biến bash là untyped, tôi rất thích nếu có một "chuỗi để số nguyên" phương pháp trong bash tuy nhiên.


76
2018-06-04 00:41


gốc


@OmnipotentEntity: bạn có thể làm điều này như một câu trả lời không? - Michael Mao
Chắc chắn là Michael Mao. - OmnipotentEntity


Các câu trả lời:


Hoặc $(()) hoặc là $[] sẽ làm việc để tính toán kết quả của phép toán số học. Bạn đang sử dụng $() đơn giản là lấy chuỗi và đánh giá nó như một lệnh. Đó là một chút khác biệt tinh tế. Hi vọng điêu nay co ich.

Như tink đã chỉ ra trong các ý kiến ​​về câu trả lời này, $[] không được chấp nhận và $(()) nên được ưa chuộng.


58
2018-06-04 01:03



Bạn có thể muốn trao đổi hai thứ đó xung quanh, như trang bash 4.x cho biết rằng $ [] không được dùng nữa và sẽ bị xóa trong các phiên bản sau. - tink
Cảm ơn bạn, tôi đã không biết. - OmnipotentEntity


Tôi thấy nó rất sạch sẽ để sử dụng biến nội bộ "$ SECONDS"

SECONDS=0 ; sleep 10 ; echo $SECONDS


89
2017-07-27 21:51



tuyệt vời, nó có tác dụng phụ không? - g13013
Chỉ thành công =) - Lon Kaut
Cần thành công, sử dụng của bạn - Gromish
$SECONDS thực sự làm việc cho / bin / bash. Nó không hoạt động với / bin / dash, shell mặc định trong Debian và Ubuntu. - Cameron Taggart
Nhược điểm của giải pháp này là nó chỉ đo lường toàn bộ giây, tức là không thể sử dụng được nếu bạn cần độ chính xác phụ thứ hai. - Czechnology


Bạn đang cố gắng thực hiện số trong ENDTIME như một lệnh. Bạn cũng sẽ thấy một lỗi như 1370306857: command not found. Thay vào đó hãy sử dụng mở rộng số học:

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

Bạn cũng có thể lưu các lệnh trong một tập lệnh riêng biệt, commands.shvà sử dụng lệnh thời gian:

time commands.sh

43
2018-06-04 00:48





Bạn có thể sử dụng Bash's time từ khóa ở đây với chuỗi định dạng thích hợp

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

Đây là những gì tham khảo nói về TIMEFORMAT:

Giá trị của tham số này được sử dụng như một chuỗi định dạng xác định cách thông tin thời gian cho các đường ống được bắt đầu bằng time   từ dành riêng sẽ được hiển thị. Các '%'Nhân vật giới thiệu một   chuỗi thoát được mở rộng thành giá trị thời gian hoặc thông tin khác.   Trình tự thoát và ý nghĩa của chúng như sau; niềng răng   biểu thị các phần tùy chọn.

%%

    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. 

Tùy chọn p là một chữ số chỉ định độ chính xác, số chữ số thập phân sau dấu thập phân. Giá trị 0 không gây ra   dấu thập phân hoặc phần thập phân để xuất ra. Tối đa ba địa điểm sau   dấu thập phân có thể được xác định; giá trị của p lớn hơn 3 được thay đổi   đến 3. Nếu p không được chỉ định, giá trị 3 được sử dụng.

Tùy chọn l chỉ định định dạng dài hơn, bao gồm phút, của biểu mẫu MMmSS.FFs. Giá trị của p xác định có hay không   phân số được bao gồm.

Nếu biến này không được thiết lập, Bash hoạt động như thể nó có giá trị

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

Nếu giá trị là null, không có thông tin thời gian nào được hiển thị. Một dòng mới được thêm vào khi chuỗi định dạng được hiển thị.


21
2018-03-14 06:48





Hãy thử đoạn mã sau:

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

5
2018-03-14 05:26





thử sử dụng thời gian với tùy chọn giây trôi qua:

/usr/bin/time -f%e sleep 1 dưới bash.

hoặc là \time -f%e sleep 1 trong bash tương tác.

xem trang thời gian của người đàn ông:

Người dùng bash shell cần sử dụng đường dẫn rõ ràng để chạy          lệnh thời gian bên ngoài và không phải là phiên bản nội trang hệ vỏ. Trên hệ thống          nơi thời gian được cài đặt trong / usr / bin, ví dụ đầu tiên sẽ trở thành               / usr / bin / thời gian wc / etc / hosts

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

1
2018-06-04 01:59



/bin/time sẽ không hoạt động ở đây: OP đề cập đến khối. Vì vậy, chúng tôi thực sự cần từ khóa time đây. - gniourf_gniourf


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

-1
2017-11-08 00:00





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

-1
2017-11-09 02:27