2009-12-07 32 views
53

有沒有辦法在Bash提示符中嵌入最後一條命令的過期掛壁時間?我希望的東西,應該是這樣的:如何將最後命令的掛牆時間放入Bash提示符中?

[last: 0s][/my/dir]$ sleep 10 
[last: 10s][/my/dir]$ 

背景

我經常跑長數據運算工作,是非常有用的知道,他們已經採取了多久,這樣我就可以估算出長期以來它將用於未來的工作。對於非常規的任務,我會繼續使用適當的記錄技術嚴格記錄這些信息。對於不太正式的任務,我只需在time之前加上命令。

這將是很好的自動time每一個交互式命令,並有計時信息打印在幾個字符而不是3行。

+2

這是Unix/Linux Stackexchange的一個很好的問題。 – Flimm 2013-07-03 09:48:09

+0

但是我從來沒有在那裏發現它,也沒有能夠給回答者獎勵賞金。 :( – 2013-08-08 18:26:40

+1

@Flimm已經在那裏重新調試過了:[強制爲每個命令添加'別名'](http://unix.stackexchange.com/questions/12059/forcing-an-added-alias-to-every-command )無論如何[這個問題太舊,無法遷移](http://meta.stackexchange.com/questions/151890/disable-migration-for-questions-older-than-60-days)。 – Gilles 2013-11-19 20:36:18

回答

10

您可以利用此zsh的借用吊鉤慶典:http://www.twistedmatrix.com/users/glyph/preexec.bash.txt

時序與此掛鉤鍵(Mac OS X)來完成:Use Growl to monitor long-running shell commands

+1

下面是以類似方式使用Bash調試掛鉤的另一個視圖:http://www.davidpashley.com/articles/xterm-titles-with-bash.html來自成員David Pashley的成員:http://serverfault.com/users/7342/david-pashley – 2009-12-07 21:19:15

+0

掛鉤正是我所期待的(咆哮鏈接是一個很好的快速使用示例)。謝謝! – 2009-12-07 21:31:00

0

將在PS1中爲你工作嗎?

它沒有給出經過的時間,但它應該很容易在必要時減去時間。

$ export PS1='[\t] [\w]\$ ' 
[14:22:30] [/bin]$ sleep 10 
[14:22:42] [/bin]$ 

繼OP的評論,他已經在使用\ t。 如果你可以使用tcsh而不是bash,你可以設置時間變量。

/bin 1 > set time = 0 
/bin 2 > sleep 10 
0.015u 0.046s 0:10.09 0.4%  0+0k 0+0io 2570pf+0w 
/bin 3 > 

您可以將打印格式更改爲不太難看(請參見tcsh手冊頁)。

/bin 4 > set time = (0 "last: %E") 
/bin 5 > sleep 10 
last: 0:10.09 
/bin 6 > 

我不知道在bash類似的設施的

+2

目前,我實際上使用\ t,而且通常是足夠的,不幸的是,當我以非交互方式運行長命令時,從上一個命令完成時開始,我交互地開始一個新命令,如果在運行前按一個新的命令的作品,但我並不總是記得這樣做,所以我想自動捕獲流逝的時間。 – 2009-12-07 20:28:23

80

這是最小的單機代碼來實現你想要什麼:

function timer_start { 
    timer=${timer:-$SECONDS} 
} 

function timer_stop { 
    timer_show=$(($SECONDS - $timer)) 
    unset timer 
} 

trap 'timer_start' DEBUG 
PROMPT_COMMAND=timer_stop 

PS1='[last: ${timer_show}s][\w]$ ' 
+0

+1 - 已經爲您確定的問題添加了一個建議。 – 2009-12-07 21:27:20

+0

感謝Martin。我更新了我的答案利用DEBUG陷阱提供一個大大改進的解決方案。 – 2009-12-08 10:58:30

+4

+1你剛剛徹底改變了我的生活。 – 2012-07-28 07:54:13

10

另一種很小的做法是:

trap 'SECONDS=0' DEBUG 
export PS1='your_normal_prompt_here ($SECONDS) # ' 

這顯示的秒數自上次簡單的命令開始。如果您只是在不輸入命令的情況下直接按下Enter鍵,計數器就不會被重置 - 當您只想查看自上次做任何事情以來終端已啓動多久時,該計數器可能非常方便。它在Red Hat和Ubuntu中可以正常工作。它在Cygwin下並不適合我,但我不確定這是一個錯誤還是隻是在Windows下運行Bash的限制。

這種方法的一個可能的缺點是您保持重置SECONDS,但如果您確實需要保留SECONDS作爲自初始shell調用以來的秒數,則可以爲PS1計數器創建自己的變量,而不是直接使用SECONDS 。另一個可能的缺點是,大量秒值,如「999999」可能會得到更好的顯示爲天+時間+分+秒,但它很容易添加一個簡單的過濾器,例如:

seconds2days() { # convert integer seconds to Ddays,HH:MM:SS 
    printf "%ddays,%02d:%02d:%02d" $(((($1/60)/60)/24)) \ 
    $(((($1/60)/60)%24)) $((($1/60)%60)) $(($1%60)) | 
    sed 's/^1days/1day/;s/^0days,\(00:\)*//;s/^0//' ; } 
trap 'SECONDS=0' DEBUG 
PS1='other_prompt_stuff_here ($(seconds2days $SECONDS)) # ' 

這意味着「999999 「變成」11日,13:46:39「。在結束時的sed改變「1天」到「1天」,並且剪掉如空領先值「0天,00:」。適應口味。

+0

非常好。我選擇了這一個。謝謝。 – FractalSpace 2012-11-23 18:54:00

+0

我喜歡這個答案的外觀,但不幸的是它似乎不適用於我,至少不會在Ubuntu 12.04上發佈4.2.25(1)版本。一旦你設置SECONDS爲0,它總是爲0. – pioto 2013-05-02 16:30:03

+0

我遇到的問題是,有一個'PROMPT_COMMAND'在每個命令後被觸發,併發送'DEBUG'信號,這會重置定時器 - 所以每次提示時,計時器都在0秒前啓動。 – PJSCopeland 2016-04-12 22:50:18

6

如果您還沒有設置任何你踢之前,把你的長期運行的工作,你只是想知道這份工作了多長時間,你可以做簡單的

$ HISTTIMEFORMAT="%s " history 2 

和其他的答案它會與一些回覆喜歡

654 1278611022 gvn up 
    655 1278611714 HISTTIMEFORMAT="%s " history 2 

,你可以就可以直觀地減去兩個時間戳(有人知道如何捕捉shell內置history命令的輸出?)

+1

你是什麼意思,「如何捕捉輸出」?你可以直接使用它,使用命令替換,'剪切','grep','awk','perl','sed' ... [Technologic](http://www.youtube.com /手錶?ν= UoPplpBPQxQ)。 – 2014-06-28 14:40:07

4

我從威樂Laurikari答案,並使用time命令顯示亞秒級的精度提高了它:

function timer_now { 
    date +%s%N 
} 

function timer_start { 
    timer_start=${timer_start:-$(timer_now)} 
} 

function timer_stop { 
    local delta_us=$((($(timer_now) - $timer_start)/1000)) 
    local us=$((delta_us % 1000)) 
    local ms=$(((delta_us/1000) % 1000)) 
    local s=$(((delta_us/1000000) % 60)) 
    local m=$(((delta_us/60000000) % 60)) 
    local h=$((delta_us/3600000000)) 
    # Goal: always show around 3 digits of accuracy 
    if ((h > 0)); then timer_show=${h}h${m}m 
    elif ((m > 0)); then timer_show=${m}m${s}s 
    elif ((s >= 10)); then timer_show=${s}.$((ms/100))s 
    elif ((s > 0)); then timer_show=${s}.$(printf %03d $ms)s 
    elif ((ms >= 100)); then timer_show=${ms}ms 
    elif ((ms > 0)); then timer_show=${ms}.$((us/100))ms 
    else timer_show=${us}us 
    fi 
    unset timer_start 
} 

trap 'timer_start' DEBUG 
PROMPT_COMMAND=timer_stop 

PS1='[last: ${timer_show}][\w]$ ' 

當然,這需要一個過程來啓動,所以它的效率較低,但仍然不夠快,你不會注意到。

14

使用您的回覆和其他一些線索,我寫了這個提示,我想與您分享。我參加了至極的截圖可以看到:

  • 白:最後返回代碼
  • 綠色刻度線意味着成功(返回碼0)
  • 紅色十字標誌意味着錯誤(返回代碼是> 0)
  • (綠或紅):當前日期時間(\噸)
  • (綠色如果不是根,紅如果根)::登錄用戶名在括號
  • (綠或紅)最後命令的執行時間
  • (綠色):服務器名稱
  • (藍色):在PWD目錄和平常$

Custom prompt

這裏是把你的〜/ .bashrc文件中的代碼:

function timer_now { 
    date +%s%N 
} 

function timer_start { 
    timer_start=${timer_start:-$(timer_now)} 
} 

function timer_stop { 
    local delta_us=$((($(timer_now) - $timer_start)/1000)) 
    local us=$((delta_us % 1000)) 
    local ms=$(((delta_us/1000) % 1000)) 
    local s=$(((delta_us/1000000) % 60)) 
    local m=$(((delta_us/60000000) % 60)) 
    local h=$((delta_us/3600000000)) 
    # Goal: always show around 3 digits of accuracy 
    if ((h > 0)); then timer_show=${h}h${m}m 
    elif ((m > 0)); then timer_show=${m}m${s}s 
    elif ((s >= 10)); then timer_show=${s}.$((ms/100))s 
    elif ((s > 0)); then timer_show=${s}.$(printf %03d $ms)s 
    elif ((ms >= 100)); then timer_show=${ms}ms 
    elif ((ms > 0)); then timer_show=${ms}.$((us/100))ms 
    else timer_show=${us}us 
    fi 
    unset timer_start 
} 


set_prompt() { 
    Last_Command=$? # Must come first! 
    Blue='\[\e[01;34m\]' 
    White='\[\e[01;37m\]' 
    Red='\[\e[01;31m\]' 
    Green='\[\e[01;32m\]' 
    Reset='\[\e[00m\]' 
    FancyX='\342\234\227' 
    Checkmark='\342\234\223' 


    # Add a bright white exit status for the last command 
    PS1="$White\$? " 
    # If it was successful, print a green check mark. Otherwise, print 
    # a red X. 
    if [[ $Last_Command == 0 ]]; then 
     PS1+="$Green$Checkmark " 
    else 
     PS1+="$Red$FancyX " 
    fi 

    # Add the ellapsed time and current date 
    timer_stop 
    PS1+="($timer_show) \t " 

    # If root, just print the host in red. Otherwise, print the current user 
    # and host in green. 
    if [[ $EUID == 0 ]]; then 
     PS1+="$Red\\[email protected]\\h " 
    else 
     PS1+="$Green\\[email protected]\\h " 
    fi 
    # Print the working directory and prompt marker in blue, and reset 
    # the text color to the default. 
    PS1+="$Blue\\w \\\$$Reset " 
} 

trap 'timer_start' DEBUG 
PROMPT_COMMAND='set_prompt' 
+0

MACOSX有一個調整:刪除日期命令後的%N – 2016-02-29 09:45:05

+2

Wowwweee!這就像有史以來最好的事情! – 2016-10-16 23:38:36

+2

@NicolasThery對我來說,我不得不''brew install coreutils'並用'/ usr/local/opt/coreutils/libexec/gnubin/date +%s%N'替換'date +%s%N'在macOS Sierra上。 – fredrik 2017-01-29 19:03:39

3

我發現trap ... DEBUG正在運行的每$PROMPT_COMMAND被稱爲時間,復位定時器,因此總是返回0。

然而,我發現,history記錄時間,我挖掘到這些讓我的答案是:

HISTTIMEFORMAT='%s ' 
PROMPT_COMMAND=" 
    START=\$(history 1 | cut -f5 -d' '); 
    NOW=\$(date +%s); 
    ELAPSED=\$[NOW-START]; 
    $PROMPT_COMMAND" 
PS1="\$ELAPSED $PS1" 

它並不完美,但:

  • 如果history不登記命令(例如重複或忽略的命令),開始時間將是錯誤的。
  • 多行命令無法從history中正確提取日期。
相關問題