나는 현재 이것을 사용하여 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을 변경하는 것이 가능을?
답변
이를 수행하는 한 가지 방법은 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
“No argument means now “동작 에 의존 하도록 매개 변수를 생략 할 수 있습니다 .
답변
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이지만 궁극적 인 값 $x
은 15입니다.
$PS1
배열 인덱스에 추가적인 수학 확장 / 평가가 있다는 점을 제외하고 는 방정식의 작동 방식이 대부분 입니다.
PS1='${PS1[!(PS1[1]=!1&(...))]#...}...'
나는 왜 내가 PS1[1]=!1
거기 에서 사용하기로 선택했는지 잘 모르겠습니다. 아마 그것은 어리석은 미학 인 것 같습니다. 그러나 이것은 $PS1[1]
매개 변수 대체를 위해 확장하는 동안 0을 할당합니다 . 0 및 기타에 대한 비트 AND의 값은 항상 0이지만 &&
가장 왼쪽의 1 차가 0 일 때 부울 이 수행 하는 것처럼 단락되지 않으므로 괄호 표현식은 여전히 매번 평가됩니다. 물론 첫 번째 줄임표는 초기 값 $PS1[2,3]
이 설정 되는 위치이기 때문에 중요 합니다.
어쨌든, $PS1[1]
프롬프트 드로우 사이에서 훼손 된 경우에도 0이 보장됩니다. 괄호 안에 …
PS1[3]=(PS1[2]=$SECONDS-${PS1[3]})/3600
…는 $PS1[2]
차이를 할당 $PS1[3]
하고 $SECONDS
, 그리고 $PS1[3]
, 그 값과 3600 모든 값이 여기 초기화의 지수가 할당된다. 그래서 :
${PS1[1]#${PS1[3]%%*??}0}
… 내장 $PS1[3]
확장 에 두 자리 이상이 있으면 내부 확장이 null이고, 우리 $PS1[1]
가 0 임을 알고 있기 때문에 $PS1[3]
아무것도 대체 할 수 없다면 $PS1[1]
다른 값으로 확장됩니다. 이러한 방식으로, $PS1[3]
할당의 각 반복에 대한 단일 숫자 값만 이 선행 0을 확장 할 것이고, $PS1[3]
그 후 바로 모듈로 60으로 확장되는 한편, 시간, 분, 초 각각에 대해 다음으로 연속적으로 작은 값을 동시에 할당 받는다.
프롬프트가 다음에 그려 질 때 한 번 더 비교 될 수 있도록 $PS1[3]
현재 값으로 덮어 쓸 때까지 마지막 반복까지 헹구고 반복하십시오 .$SECONDS
$SECONDS
답변
내가 지금까지 찾은 가장 좋은 해결책은 다음과 같습니다 : https://github.com/jichu4n/bash-command-timer
[ 1s011 | May 25 15:33:44 BST ]
실행 된 명령 후 오른쪽에 경과 시간이 인쇄 되어 PS1을 어지럽히 지 않습니다.
전체 문자열 및 시간 형식을 구성 할 수 있습니다. 색상과 정밀도도 구성 할 수 있습니다. 나는 그것이 미니멀리스트에게는 조금 많을 수도 있다는 것을 알고 있지만 꽤 시원합니다.