마지막 명령의 벽 시간을 Bash 프롬프트에 어떻게 넣을 수 있습니까?
Bash 프롬프트 에 마지막 명령의 경과 시간을 포함하는 방법이 있습니까? 나는 다음과 같은 것을 기대하고 있습니다.
[last: 0s][/my/dir]$ sleep 10
[last: 10s][/my/dir]$
배경
저는 데이터 처리량이 많은 긴 작업을 자주 실행하며 얼마나 오래 걸 렸는지 아는 것이 유용하므로 향후 작업에 걸리는 시간을 추정 할 수 있습니다. 매우 일반적인 작업의 경우 적절한 로깅 기술을 사용하여이 정보를 엄격하게 기록합니다. 덜 형식적인 작업의 경우 명령 앞에 time.
time모든 단일 대화 형 명령 을 자동으로 수행하고 3 줄이 아닌 몇 개의 문자로 타이밍 정보를 인쇄하는 것이 좋습니다.
이 zsh-borrowed 후크를 bash에 사용할 수 있습니다. http://www.twistedmatrix.com/users/glyph/preexec.bash.txt
이 후크로 완료되는 타이밍 (Mac OS X) : Growl을 사용하여 장기 실행 셸 명령 모니터링
이것은 원하는 것을 달성하기위한 최소한의 독립 실행 형 코드입니다.
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 디렉토리와 일반적인 $
~ / .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) # '
마지막 단순 명령이 시작된 이후의 시간 (초)을 표시합니다. 명령을 입력하지 않고 Enter 키만 누르면 카운터가 재설정되지 않습니다. 이는 마지막으로 터미널에서 작업을 수행 한 후 터미널이 얼마나 오래 작동했는지 확인하고자 할 때 유용 할 수 있습니다. Red Hat과 Ubuntu에서 잘 작동합니다. Cygwin에서는 작동하지 않았지만 그것이 버그인지 아니면 Windows에서 Bash를 실행하려는 제한인지 확실하지 않습니다.
이 접근 방식의 한 가지 가능한 단점은 SECONDS를 계속 재설정한다는 것입니다. 그러나 초기 셸 호출 이후 SECONDS를 초 단위로 유지해야하는 경우 SECONDS를 직접 사용하는 대신 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"를 "1day"로 변경하고 "0days, 00 :"과 같은 빈 선행 값을 제거합니다. 취향에 맞게 조정하십시오.
장기 작업을 시작하기 전에 다른 답변을 설정하지 않았고 작업이 얼마나 오래 걸 렸는지 알고 싶다면 간단한 작업을 수행 할 수 있습니다.
$ HISTTIMEFORMAT="%s " history 2
다음과 같이 응답합니다.
654 1278611022 gvn up
655 1278611714 HISTTIMEFORMAT="%s " history 2
그런 다음 두 개의 타임 스탬프를 시각적으로 뺄 수 있습니다 (쉘 내장 히스토리 명령의 출력을 캡처하는 방법을 아는 사람이 있습니까?).
Ville Laurikari의 답변을 받아 time1 초 미만의 정확도를 보여주는 명령을 사용하여 개선했습니다 .
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명령을 등록하지 않습니다, 시작 시간이 잘못된 것 (예 : 반복 또는 명령을 무시). - 여러 줄 명령은 .NET에서 날짜를 제대로 추출하지 못합니다
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준비된 스 니펫입니다. 그것은 자신의 목적으로 덮어 쓰는 undistract-me 를 사용하는 모든 사람들에게 특히 유용 trap DEBUG합니다.
PS1에 \ t를 넣으면 효과가 있습니까?
경과 시간을 알려주지는 않지만 필요할 때 시간을 뺄 수있을만큼 쉬워야합니다.
$ export PS1='[\t] [\w]\$ '
[14:22:30] [/bin]$ sleep 10
[14:22:42] [/bin]$
그가 이미 \ t를 사용하고 있다는 OP의 의견에 따라. bash 대신 tcsh를 사용할 수 있으면 시간 변수를 설정할 수 있습니다.
/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에서 비슷한 시설을 모른다
이것은 내 버전입니다
- 날짜를 사용하여 시간 형식 지정, 계산 일만
- 터미널 제목 설정
- 사용자 $ + root #에 대해 PS1에서 \ $ 사용
- 반환 코드 / 종료 코드 표시
- date -u를 사용하여 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밀리 초를 기본 단위로 가져 오는 데 사용 하며, 다음 코드 (0 미만)를 단순화합니다.
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_showPS1에 추가 하십시오.
'IT TIP' 카테고리의 다른 글
| Team Foundation Build 또는 TeamCity? (0) | 2020.12.07 |
|---|---|
| 간단한 삽입 문을 사용하여 바이너리 파일 데이터를 바이너리 SQL 필드에 삽입하려면 어떻게해야합니까? (0) | 2020.12.06 |
| 두 개의 java.util.Properties 객체를 병합하는 방법은 무엇입니까? (0) | 2020.12.06 |
| numpy의 "isnotnan"기능이 더 비단뱀 적일까요? (0) | 2020.12.06 |
| 상대적인 URL 대신 전체 이미지 URL을 사용하도록 TinyMCE 가져 오기 (0) | 2020.12.06 |
