PS1 프롬프트에 경과 시간이 표시됩니다.

PS1 프롬프트에 경과 시간이 표시됩니다.

현재 이것을 사용하여 bash 프롬프트에 현재 시간을 표시합니다.

PS1=\[\e[0;32m\]\t \W>\[\e[1;37m\]

20:42:23 ~>

마지막 프롬프트 이후 경과된 시간을 표시할 수 있습니까? 예를 들어:

00:00:00 ~> sleep 10
00:00:10 ~> sleep 20
00:00:20 ~>

이는 다음과 관련이 있습니다.백그라운드 스크립트를 통해 주기적으로 PS1을 변경할 수 있습니까?

답변1

한 가지 접근 방식은 bash의 PROMPT_COMMAND 함수를 사용하여 PS1을 수정하는 코드를 실행하는 것입니다. 아래 함수는 원래 제출한 것의 업데이트된 버전입니다. 이 함수는 두 개의 더 적은 환경 변수를 사용하고 기존 변수가 손상되지 않도록 "_PS1_" 접두사를 붙입니다.

prompt_command() {
  _PS1_now=$(date +%s)
  PS1=$( printf "\[\e[0;32m\]%02d:%02d:%02d \W>\[\e[1;37m\] " \
           $((  ( _PS1_now - _PS1_lastcmd ) / 3600))         \
           $(( (( _PS1_now - _PS1_lastcmd ) % 3600) / 60 )) \
           $((  ( _PS1_now - _PS1_lastcmd ) % 60))           \
       )
  _PS1_lastcmd=$_PS1_now
}
PROMPT_COMMAND='prompt_command'
_PS1_lastcmd=$(date +%s)

시작하려면 .bash_profile에 넣으세요.

프롬프트 매개변수와 일치하도록 매개변수를 빨리 입력해야 한다는 점에 유의하십시오 sleep. 시간은 실제로 명령을 입력하는 데 걸리는 시간을 포함하여 프롬프트 간의 차이입니다.

00:00:02 ~> sleep 5   ## here I typed really quickly
00:00:05 ~> sleep 3   ## here I took about 2 seconds to enter the command
00:00:10 ~> sleep 30 ## more slow typing
00:01:35 ~>

나중에 추가된 내용:

현재 삭제된 @Cyrus의 답변을 바탕으로 추가 변수로 환경을 복잡하게 만들지 않는 버전은 다음과 같습니다.

PROMPT_COMMAND='
    _prompt(){
        PROMPT_COMMAND="${PROMPT_COMMAND%-*}-$SECONDS))\""
        printf -v PS1 "\[\e[0;32m\]%02d:%02d:%02d \W>\[\e[1;37m\] " \
                      "$(($1/3600))" "$((($1%3600)/60))" "$(($1%60))"
    }; _prompt "$((SECONDS'"-$SECONDS))\""

추가 늦은 추가 사항:

Bash 버전 4.2부터 시작( echo $BASH_VERSION), date새로운 printf 형식 문자열을 사용하여 외부 호출을 방지할 $(date +%s)수 있습니다 $(printf '%(%s)T' -1).버전 4.3부터-1, "인수가 없음을 의미함"에 의존하기 위해 인수를 생략할 수 있습니다.지금" 행동.

답변2

PS1[3]=$SECONDS
PS1='${PS1[!(PS1[1]=!1&(PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600))
   ]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]/60%60),  ${PS1[3]})):${PS1[1
   ]#${PS1[3]%%*??}0}$((PS1[3]=(PS1[2]%60),     ${PS1[3]})):${PS1[1
   ]#${PS1[3]%%*??}0}$((PS1[3]=(SECONDS),       ${PS1[3]})):'$PS1

이는 서식을 계산적으로 처리하므로 몇 번 확장되지만 하위 쉘이나 파이프는 수행되지 않습니다.

단지 이를 $PS1배열로 취급하고 더 높은 인덱스를 사용하여 프롬프트 사이에 필요한 모든/필요한 상태를 저장/계산합니다. 다른 쉘 상태에는 영향을 주지 않습니다.

00:00:46:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:00:[mikeserv@desktop tmp]$
00:00:01:[mikeserv@desktop tmp]$
00:00:43:[mikeserv@desktop tmp]$ sleep 10
00:00:33:[mikeserv@desktop tmp]$ sleep 10
00:00:15:[mikeserv@desktop tmp]$
00:00:15:[mikeserv@desktop tmp]$
00:00:02:[mikeserv@desktop tmp]$
00:02:27:[mikeserv@desktop tmp]$

조금 쪼개어 볼 수도 있겠네요...

먼저 현재 값을 저장합니다 $SECONDS.

PS1[3]=$SECONDS

다음으로, 항상 올바른 값을 설정하는 동시에 자체 참조를 만드는 $PS1[0]방식으로 자체 재귀를 정의합니다 . $PS1[1-3]이 부분을 얻으려면 쉘 수학 표현식이 평가되는 순서를 고려해야 합니다. 가장 중요한 것은 쉘 수학이 항상 쉘 수학의 마지막 작업이라는 것입니다. 먼저, 쉘은 값을 확장합니다. 이 방법으로 할당을 사용한 후 수학 표현식에서 쉘 변수의 이전 값을 참조할 수 있습니다 $.

먼저 간단한 예를 들어보겠습니다.

x=10; echo "$(((x+=5)+$x+x))" "$x"

40 15

쉘은 먼저 참조된 위치 값을 달러 기호로 대체하여 $x명령문을 평가 하므로 $표현식은 다음과 같습니다.

(x+=5)+10+x

...쉘은 값에 5를 더한 다음 참조 변수에 실제 할당된 값만 유지하면서 $x전체 표현식을 로 확장합니다 . x+10+x따라서 수학적 표현의 확장된 값은 40이지만 최종 값은 $x15입니다.

이는 $PS1주로 방정식이 작동하는 방식이지만 배열 인덱싱에 활용되는 추가 수학적 확장/평가가 필요합니다.

PS1='${PS1[!(PS1[1]=!1&(...))]#...}...'

내가 왜 거기를 사용하기로 선택했는지 잘 모르겠습니다 PS1[1]=!1. 아마도 어리석은 미학일 것 같습니다. 그러나 $PS1[1]매개변수 대체를 위해 확장할 때 0이 할당됩니다. 0의 비트 AND 값과 다른 값은 항상 0이 되지만, &&가장 왼쪽의 기본 값이 0이면 부울 값처럼 단락되지 않으므로 대괄호 표현식은 매번 평가됩니다. 물론 첫 번째 줄임표가 $PS1[2,3]초기 값이 설정되는 위치이기 때문에 이것이 중요합니다.

그럼에도 불구하고 $PS1[1]프롬프트 추첨 사이에 조작되더라도 여기서는 0이 보장됩니다. 괄호 안에는...

PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600

$PS1[2]... 합계의 차이가 할당 되고 해당 값과 3600의 몫이 할당됩니다. 모든 값은 여기에서 초기화됩니다. 그래서:$PS1[3]$SECONDS$PS1[3]

${PS1[1]#${PS1[3]%%*??}0}

...두 자리 이상이면 내부적으로 null로 확장되고, 0이라는 것을 $PS1[3]알고 있으므로 if 를 null로 대체할 수 있으므로 else도 해당 값으로 확장할 수 있습니다. 이러한 방식으로 할당 반복당 단일 숫자 값만 선행 0으로 확장되고 자체적으로 모듈로 60으로 즉시 확장되는 동시에 각 시간, 분, 초에 다음 연속 작은 값이 할당됩니다.$PS1[1]$PS1[3]$PS1[1]$PS1[3]$PS1[3]

$PS1[3]다음에 팁을 그릴 때 $SECONDS다시 비교할 수 있도록 마지막 반복을 현재 값으로 덮어쓸 때까지 헹구고 반복합니다 .$SECONDS

답변3

지금까지 내가 찾은 최고의 솔루션은 다음과 같습니다.https://github.com/jichu4n/bash-command-timer

명령을 실행한 후 오른쪽에 경과 시간이 인쇄 되므로 [ 1s011 | May 25 15:33:44 BST ]PS1이 복잡해지지 않습니다.

전체 문자열과 시간 형식을 구성할 수 있습니다. 색상과 정밀도도 구성 가능합니다. 일부 미니멀리스트에게는 이것이 다소 과할 수도 있다는 것을 알고 있지만 꽤 멋집니다.

답변4

Bash 이후 매우 가능함4.4PS0, 환경 변수를 소개합니다 .

export PS0='$(date +%s%03N > ~/.execStart.$$)'

printElapsedCommandTime () {
    local execStart execEnd execDur elaStr
    if [ -e ~/.execStart.$$ ]; then
        read execStart < ~/.execStart.$$ 2>/dev/null
        rm -f ~/.execStart.$$
        if [ -n "$execStart" ]; then
            execEnd=`date +%s%03N`
            execDur=$((execEnd-execStart))
            printf -v elaStr "Ela %u.%03u" $((execDur / 1000)) $((execDur % 1000))
            printf "%*s\e[32;7m%s\e[0m\n" $((COLUMNS-${#elaStr})) "" "$elaStr"
        fi
    fi
}
export PROMPT_COMMAND='printElapsedCommandTime'

PS0( 디스플레이뒤쪽에Bash는 명령을 읽었지만앞으로Bash가 실행을 시작했습니다.) 출력을 임시 파일에 저장합니다 date +%s%03N. 이는 에포크 초와 나노초의 처음 3자리입니다. 전체적인 효과는 에포크 마이크로초를 저장하는 것입니다.

PROMPT_COMMAND(평가 하다뒤쪽에Bash가 명령 실행을 완료했지만앞으로Bash는 기본 프롬프트를 표시했습니다 PS1. 다시 Epoch 마이크로초를 찾아 임시 파일에 저장된 측정값을 뺍니다.

경과 시간은 오른쪽의 별도 줄에 표시됩니다. 낮은 수준은 printf조금 더 까다롭습니다.

  • 형식 지정자 %*s소비매개변수, 정수 및 문자열. 전자는 후자를 인쇄할 때 사용할 열 수를 나타냅니다. 우리가 제공하는 두 개의 매개변수는 N = $((COLUMNS-${#elaStr}))이고 빈 문자열은 ""N 공백을 인쇄하는 것입니다.
  • \e[32;7m7녹색(" " 32) 배경의 역상 비디오(" ") 텍스트를 요청합니다.
  • %s우리 문자열을 소비하는 것입니다 $elaStr.
  • \e[0m글꼴 색상을 일반 색상으로 재설정합니다.

불다5.0EPOCHREALTIME두 번 호출하는 것을 방지하는 환경 변수가 도입되었습니다 date(1). EPOCHREALTIME는 마이크로초 단위의 소수 초입니다. .제거하면 와 동일한 출력이 되므로 date +%s%03N개선된 솔루션을 얻으려면 두 가지 작은 변경만 하면 됩니다.

export PS0='echo ${EPOCHREALTIME/./} > ~/.execStart.$$)'   ### change here...

printElapsedCommandTime () {
    local execStart execEnd execDur elaStr
    if [ -e ~/.execStart.$$ ]; then
        read execStart < ~/.execStart.$$ 2>/dev/null
        rm -f ~/.execStart.$$
        if [ -n "$execStart" ]; then
            execEnd=`${EPOCHREALTIME/./}                   ### ...and here
            execDur=$((execEnd-execStart))
            printf -v elaStr "Ela %u.%03u" $((execDur / 1000)) $((execDur % 1000))
            printf "%*s\e[32;7m%s\e[0m\n" $((COLUMNS-${#elaStr})) "" "$elaStr"
        fi
    fi
}
export PROMPT_COMMAND='printElapsedCommandTime'

관련 정보