كيف يمكن الأمر الأخير جدار الوقت تكون وضعت في باش موجه?

StackOverflow https://stackoverflow.com/questions/1862510

  •  16-09-2019
  •  | 
  •  

سؤال

هل هناك طريقة تضمين الأمر الأخير هو المنقضي جدار الوقت في باش موجه?أنا آمل في شيء من شأنها أن تبدو مثل هذا:

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

الخلفية

أنا في كثير من الأحيان تشغيل طويلة البيانات الطحن وظائف فإنه من المفيد أن نعرف كم من الوقت لقد اتخذت حتى أستطيع تقدير كم من الوقت سوف يستغرق للحصول على وظائف في المستقبل.جدا المهام العادية ، أذهب إلى الأمام وتسجيل هذه المعلومات بدقة باستخدام المناسبة تسجيل التقنيات.على أقل رسمية المهام, أنا فقط prepend الأمر time.

سيكون من الجميل أن تلقائيا time كل واحد الأوامر التفاعلية و توقيت المعلومات المطبوعة في عدد قليل من الشخصيات بدلا من 3 خطوط.

هل كانت مفيدة؟

المحلول

يمكنك الاستفادة من هذا هوك المقترض ZSH ل Bash: http://www.twistedmatrix.com/users/glyph/preexec.bash.txt.

توقيت القيام به مع هذا الخطاف (Mac OS X): استخدم Growl لمراقبة أوامر Shell طويلة الأمد

نصائح أخرى

هذا هو الحد الأدنى رمز مستقل لتحقيق ما تريد:

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)
  • الأحمر و الصليب علامة يعني خطأ (عودة المدونة >0)
  • (الأخضر أو الأحمر) :الأمر الأخير وقت التنفيذ بين قوسين
  • (الأخضر أو الأحمر) :التاريخ والوقت الحالي (t)
  • (الأخضر إن لم يكن الجذر الأحمر إذا كان الجذر) :تسجيل اسم المستخدم
  • (الأخضر) :اسم الملقم
  • (الأزرق) :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\\u$Green@\\h "
    else
        PS1+="$Green\\u@\\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'

نهج آخر ضئيل للغاية هو:

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

هذا يدل على عدد الثواني منذ بدء آخر أمر بسيط. لا يتم إعادة تعيين العداد إذا قمت ببساطة بالضغط على دخول دون إدخال أمر - والذي قد يكون مفيدا عندما تريد فقط معرفة المدة التي ارتكبت فيها المحطة منذ آخر شيء فعلت شيئا فيه. إنه يعمل بشكل جيد بالنسبة لي في قبعة حمراء وأوبونتو. لم تنجح لي تحت Cygwin، لكنني لست متأكدا مما إذا كان هذا خطأ أو مجرد قيود لمحاولة تشغيل Bash ضمن Windows.

أحد العيوب المحتملة لهذا النهج هو أن تستمر في إعادة تعيين الثواني، ولكن إذا كنت بحاجة حقا إلى الحفاظ على الثواني كعدد الثواني نظرا لاستدعاء Shell الأولي، فيمكنك إنشاء متغير خاص بك لمكافحة PS1 بدلا من استخدام الثواني مباشرة. عيب آخر محتمل هو أنه قد يتم عرض قيمة ثوان كبيرة مثل "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" في "11days، 13: 46: 39". تتغير SED في النهاية "1days" إلى "1 يوم"، وقم بإيقاف القيم الرائدة الفارغة مثل "0days، 00:". ضبط حسب الذوق.

إذا لم تقم بإعداد أي من الإجابات الأخرى قبل طرح عملك منذ فترة طويلة، فأنت تريد أن تعرف كم من الوقت استغرق المهمة، فيمكنك القيام بهذه البساطة

$ HISTTIMEFORMAT="%s " history 2

وسوف يرد مع شيء مثل

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

ويمكنك بعد ذلك طرح الطابع الزمني اثنين فقط (أي شخص يعرف كيفية التقاط إخراج أمر SHEL SHELTIN INVENT؟)

أخذت الجواب من فيل لوريكاري وتحسينها باستخدام 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]$ '

بالطبع يتطلب ذلك عملية بدء العملية، لذلك فهي أقل كفاءة، ولكن لا تزال سريعة بما يكفي لن تلاحظ.

لقد وجدت أن 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.

سيكون نهج آخر ل Bash 4.x وما فوق هو استخدام coproc مع PS0 و PS1 مثل أدناه:

cmd_timer()
{
    echo $(( SECONDS - $(head -n1 <&"${CMD_TIMER[0]}") ))
}

coproc CMD_TIMER ( while read; do echo $SECONDS; done )
echo '' >&"${CMD_TIMER[1]}" # For value to be ready on first PS1 expansion
export PS0="\$(echo '' >&${CMD_TIMER[1]})"
export PS1="[ \$(cmd_timer) ] \$"

هذا ال .bashrc مقتطف جاهز. إنه مفيد بشكل خاص للجميع الذي يستخدم unstract-me. الذي الكتابة trap DEBUG لأغراضها الخاصة.

سوف يضع A t في عمل 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 >

يمكنك تغيير تنسيق الطباعة لتكون أقل قبيحة (SE صفحة TCSH MAN).

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

أنا لا أعرف منشأة مماثلة في باش

هذا هو بلدي الإصدار

  • استخدام التاريخ لتنسيق الوقت، فقط الأيام Calc
  • تعيين عنوان المحطة الطرفية
  • استخدم $ في PS1 للمستخدم $ + الجذر #
  • إظهار رمز الإرجاع / رمز الخروج
  • استخدام التاريخ - دو لتعطيل DST
  • استخدام أسماء مخفية مثل _foo
_x_dt_min=1 # minimum running time to show delta T
function _x_before {
    _x_t1=${_x_t1:-$(date -u '+%s.%N')} # float seconds
}
function _x_after {
    _x_rc=$? # return code
    _x_dt=$(echo $(date -u '+%s.%N') $_x_t1 | awk '{printf "%f", $1 - $2}')
    unset _x_t1
    #_x_dt=$(echo $_x_dt | awk '{printf "%f", $1 + 86400 * 1001}') # test
    # only show dT for long-running commands
    # ${f%.*} = int(floor(f))
    (( ${_x_dt%.*} >= $_x_dt_min )) && {
        _x_dt_d=$((${_x_dt%.*} / 86400))
        _x_dt_s='' # init delta T string
        (( $_x_dt_d > 0 )) && \
            _x_dt_s="${_x_dt_s}${_x_dt_d} days + "
        # format time
        # %4N = four digits of nsec
        _x_dt_s="${_x_dt_s}$(date -u -d0+${_x_dt}sec '+%T.%4N')"
        PS1='rc = ${_x_rc}\ndT = ${_x_dt_s}\n\$ '
    } || {
        PS1='rc = ${_x_rc}\n\$ '
    }
    # set terminal title to terminal number
    printf "\033]0;%s\007" $(tty | sed 's|^/dev/\(pts/\)\?||')
}
trap '_x_before' DEBUG
PROMPT_COMMAND='_x_after'
PS1='\$ '

الناتج العينة:

$ sleep 0.5
rc = 0
$ sleep 1
rc = 0
dT = 00:00:01.0040
$ sleep 1001d
rc = 0
dT = 1001 days + 00:00:00.0713
$ false
rc = 1
$ 

ها هي بلدي تأخذ توماس

الاستخدامات date +%s%3N للحصول على milliseconds كوحدة أساسية، يتم تبسيط التعليمات البرمجية التالية (أقل الأصفار)

function t_now {
    date +%s%3N
}

function t_start {
    t_start=${t_start:-$(t_now)}
}

function t_stop {
    local d_ms=$(($(t_now) - $t_start))
    local d_s=$((d_ms / 1000))
    local ms=$((d_ms % 1000))
    local s=$((d_s % 60))
    local m=$(((d_s / 60) % 60))
    local h=$((d_s / 3600))
    if ((h > 0)); then t_show=${h}h${m}m
    elif ((m > 0)); then t_show=${m}m${s}s
    elif ((s >= 10)); then t_show=${s}.$((ms / 100))s
    elif ((s > 0)); then t_show=${s}.$((ms / 10))s
    else t_show=${ms}ms
    fi
    unset t_start
}
set_prompt () {
t_stop
}

trap 't_start' DEBUG
PROMPT_COMMAND='set_prompt' 

ثم أضف $t_show إلى PS1 الخاص بك

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top