2010-10-01 21 views
7

Tôi chạy tập lệnh của riêng tôi để đổ cơ sở dữ liệu vào tệp trên cơ sở hàng đêm.
Tôi muốn đếm thời gian (tính bằng giây) phải mất mỗi cơ sở dữ liệu, vì vậy tôi đã cố gắng viết một số chức năng để giúp tôi đạt được nó, nhưng tôi đang gặp vấn đề.Đơn giản hẹn giờ để đo giây hoạt động đã hoàn thành

Tôi không có chuyên gia về viết mã trong bash, vì vậy nếu tôi làm sai, chỉ cần nói như vậy và lý tưởng đề nghị thay thế, xin vui lòng.

Đây là kịch bản:

#!/bin/bash 

declare -i time_start 

function get_timestamp { 
     declare -i time_curr=`date -j -f "%a %b %d %T %Z %Y" "\`date\`" "+%s"` 
     echo "get_timestamp:" $time_curr 
     return $time_curr 
} 

function timer_start { 
     get_timestamp 
     time_start=$? 
     echo "timer_start:" $time_start 
} 

function timer_stop { 
     get_timestamp 
     declare -i time_curr=$? 
     echo "timer_stop:" $time_curr 
     declare -i time_diff=$time_curr-$time_start 

     return $time_diff 
} 

timer_start 
sleep 3 
timer_stop 
echo $? 

Mã này thực sự nên được khá tự giải thích. echo lệnh chỉ để gỡ lỗi.
tôi mong đợi đầu ra được một cái gì đó như thế này:

$ bash timer.sh 
get_timestamp: 1285945972 
timer_start: 1285945972 
get_timestamp: 1285945975 
timer_stop: 1285945975 
3 

Bây giờ đây không phải là trường hợp không may. Những gì tôi nhận được là:

$ bash timer.sh 
get_timestamp: 1285945972 
timer_start: 116 
get_timestamp: 1285945975 
timer_stop: 119 
3 

Như bạn có thể thấy, giá trị mà var địa phương time_curr được từ lệnh là một dấu thời gian hợp lệ, nhưng trở về giá trị này gây ra nó phải được thay đổi thành một số nguyên từ 0 đến 255.

Ai đó có thể giải thích cho tôi biết tại sao điều này xảy ra?

PS. Điều này rõ ràng chỉ là kịch bản kiểm tra hẹn giờ của tôi mà không có bất kỳ logic nào khác.


CẬP NHẬT Chỉ cần được hoàn toàn rõ ràng, tôi muốn điều này là một phần của một kịch bản bash rất giống với this one, nơi tôi muốn đo mỗi chu kỳ vòng lặp.

Trừ khi tất nhiên tôi có thể làm điều đó với time, sau đó vui lòng đề xuất giải pháp.

+2

Bạn không phải sử dụng 'ngày' cho việc này. Bash có một biến '$ SECONDS' được tự động cập nhật và hiển thị số giây kể từ khi kịch bản (hoặc shell) được bắt đầu. Nó thậm chí có thể cài đặt và sẽ vẫn tự động tăng. –

+0

Dennis, đây là giải pháp đơn giản nhất tôi có thể tìm thấy và nó chính xác là những gì tôi đang tìm kiếm. Nếu bạn đặt nó xuống như một aswer tôi sẽ vui vẻ chấp nhận nó. –

+0

http://unix.stackexchange.com/questions/53841/how-to-use-a-timer-in-bash –

Trả lời

3

$? được sử dụng để giữ trạng thái thoát của lệnh và chỉ có thể giữ giá trị từ 0 đến 255. Nếu bạn chuyển mã thoát ra ngoài phạm vi này (ví dụ: trong chương trình C gọi số exit(-1)), trình bao sẽ vẫn nhận được một giá trị trong phạm vi đó và đặt $? cho phù hợp.

Là một workaround, bạn chỉ có thể đặt một giá trị khác nhau trong chức năng bash của bạn:

function get_timestamp { 
     declare -i time_curr=`date -j -f "%a %b %d %T %Z %Y" "\`date\`" "+%s"` 
     echo "get_timestamp:" $time_curr 
     get_timestamp_return_value=$time_curr 
} 

function timer_start { 
     get_timestamp 
     #time_start=$? 
     time_start=$get_timestamp_return_value 
     echo "timer_start:" $time_start 
} 

... 
+1

Là một thay thế cho biến "toàn cầu", 'echo' có thể được sử dụng để" trả về "một giá trị. Cả hai kỹ thuật đều hữu ích và sự lựa chọn của bạn phụ thuộc vào nhu cầu của bạn. –

21

Bạn không cần phải làm tất cả điều này. Chỉ cần chạy time <yourscript> trong vỏ.

+0

Câu hỏi được cập nhật. –

+0

Đặt các lệnh nằm trong vòng lặp vào một tập lệnh khác, sau đó chạy: time other_script –

0

Tôi tin rằng bạn sẽ có thể sử dụng chức năng "thời gian" hiện tại.

Sau khi cập nhật cho câu hỏi: Đây là đoạn mã từ liên kết của bạn đang thực hiện vòng lặp for.

# dump each database in turn 
for db in $databases; do 
    echo $db 
    $MYSQLDUMP --force --opt --user=$USER --password=$PASSWORD 
    --databases $db > "$OUTPUTDIR/$db.bak" 
done 

Bạn có thể trích xuất các phần bên trong của vòng lặp thành một kịch bản mới (gọi nó là dump_one_db.sh) và làm được điều này bên trong vòng lặp:

# dump each database in turn 
    for db in $databases; do 
     time dump_one_db.sh $db 
    done 

Hãy chắc chắn để viết ra của thời gian chống lại tên db vào một số tệp.

+0

Câu hỏi được cập nhật. –

0

này đang xảy ra vì các mã trở lại cần phải được từ 0-255. Bạn không thể trả lại một số tùy ý. Nếu bạn tiếp tục từ chối sử dụng hàm dựng sẵn time và cuộn của riêng bạn, hãy thay đổi các chức năng của bạn để lặp lại dấu và sử dụng mở rộng quy trình ($()) để lấy giá trị.

Các vấn đề liên quan