더 나은 표현 방법이 없기 때문에 모든 명령에 타이밍 별칭을 강제로 추가할 수 있습니까 bash
?
예를 들어, 특정 사용자가 있고 명령이 실행될 때마다 항상 date
before 및 after 또는 으로 수행됩니다 time
.
가능합니까? 가능하다면 어떻게 달성할 수 있나요?
답변1
명령줄이 시작될 때와 프롬프트가 표시될 때 기록할 수 있습니다. Bash는 이미 기록에서 각 명령줄의 시작 날짜를 추적하고 있으며 다음 프롬프트가 표시되는 시기를 확인할 수 있습니다.
print_command_wall_clock_time () {
echo Wall clock time: \
$(($(date +%s) - $(HISTTIMEFORMAT="%s ";
set -o noglob;
set $(history 1); echo $2)))
}
PROMPT_COMMAND=print_command_wall_clock_time$'\n'"$PROMPT_COMMAND"
이는 두 번째 해결 방법과 벽시계 시간만 제공합니다. 더 나은 해상도를 원한다면 나노초 형식을 date
지원하는 외부 명령 %N
과 명령을 실행하기 전에 호출되는 트랩을 사용하여 DEBUG
시간을 측정해야 합니다.date
call_date_before_command () {
date_before=$(date +%s.%N)
}
print_wall_clock_time () {
echo "Wall clock time: $(date +"%s.%N - $date_before" | bc)"
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_wall_clock_time
트랩을 사용하더라도 DEBUG
각 명령에 대한 프로세서 시간을 자동으로 표시하거나 프롬프트보다 더 식별할 수 있는 방법은 없다고 생각합니다.
다른 셸을 사용하려는 경우 zsh에서 각 명령에 대한 시간 보고서를 얻는 방법은 다음과 같습니다(다른 작업에서는 작동하지 않음).
REPORTTIME=0
이 값은 임의의 정수 값으로 설정할 수 REPORTTIME
있으며 프로세서 시간을 이 초 이상 사용하는 명령만 타이밍 정보를 표시합니다.
Zsh는 변수가 호출되는 csh에서 이 기능을 상속받습니다 time
.
답변2
여기에서 선택할 수 있는 옵션은 쉘에 따라 다릅니다. 대화형 쉘 명령 이전에 실행되는 zsh
편리한 후크 기능이 있습니다 . preexec()
이 이름으로 함수를 생성하면 몇 가지 작업을 수행할 수 있습니다. precmd()
다음 팁이 그려지기 전에 실행되고 다음 팁 이후에 실행되는 함수를 호출하여 후속 조치를 취할 수도 있습니다.당신의명령이 완료되었습니다.
이 함수 쌍을 생성하면 프롬프트에서 명령을 실행하기 전후에 원하는 명령을 실행할 수 있습니다. 이를 사용하여 셸 사용량을 기록하고, 잠금을 생성하고, 환경을 테스트하거나, 예제에서와 같이 명령 실행에 소비된 시간이나 리소스를 계산할 수 있습니다.
이 예에서는 명령을 실행하기 전에 기준 타임스탬프를 생성한 preexec()
다음 명령을 실행하는 데 걸리는 시간을 계산 precmd()
하고 프롬프트 전에 출력하거나 기록합니다. 예:
preexec() {
CMDSTART=$(date +%s%N)
}
precmd() {
CMDRUNTIME=$(($(date +%s%N)-$CMDSTART))
echo "Last command ran for $CMDRUNTIME nanoseconds."
}
노트:이 특정 예에는 더 간단한 내장 함수가 있습니다. ZSH에서 런타임 보고를 열기만 하면 이 작업이 자동으로 수행됩니다.
$ export REPORTTIME=0
$ ls -d
./
ls -BF --color=auto -d 0.00s user 0.00s system 0% cpu 0.002 total
보다 실용적인 구현에서는 preexec()
이를 사용하여 쉘이 내부적으로 실행 중인지 확인하고 tmux
, screen
그렇다면 현재 실행 중인 명령 업스트림에 대한 정보를 탭 이름에 표시하도록 보냅니다.
불행하게도 이 작은 메커니즘은 bash에는 존재하지 않습니다. 이것은 남자의 것입니다복사해 보세요. 또한보십시오자일스의 대답이와 같은 멋진 작은 해킹을 위해.
답변3
가장 쉬운 방법은 아마도 그것을 설정하는 것입니다 PROMPT_COMMAND
. 보다배쉬 변수:
PROMPT_COMMAND 설정되면 이 값은
각 기본 프롬프트( )가 인쇄되기$PS1
전에 실행될 명령 으로 해석됩니다.
예를 들어 기존 프롬프트 명령을 덮어쓰지 않으려면 다음을 수행할 수 있습니다.
PROMPT_COMMAND="date ; ${PROMPT_COMMAND}"
답변4
~처럼wjandrea가 지적했습니다.,자일스의 대답작동하지 않습니다.
- 부분적으로는 미용상의 이유로 wjandrea가 이 문제를 해결했습니다.
- 그 이유 중 하나는 DEBUG 트랩 명령이 PROMPT_COMMAND 명령 바로 전에 실행되므로 런타임을 측정하려는 사용자 입력 명령의 시작 시간을 잃게 되기 때문입니다.
다행히 DEBUG 트랩 명령은언제 이런 일이 발생하는지 알 수 있음 그리고 예방할 수 있습니다. 따라서 Gilles의 답변을 바탕으로 (DNA 단편과 결합)여기 내 대답과 매우 유사합니다.), 우리는 구성할 수 있습니다
call_date_before_command () {
if [ "$BASH_COMMAND" != "print_wall_clock_time" ]
then
command_flag=1
date_before=$(date +%s.%N)
fi
}
print_wall_clock_time () {
if [ "$command_flag" ]
then
echo "Wall clock time: $(date +"%s.%N - $date_before" | bc)"
fi
command_flag=
}
trap call_date_before_command DEBUG
PROMPT_COMMAND=print_wall_clock_time
실행하기 전에 where가 호출되면 call_date_before_command
아무 작업도 수행하지 않으며 사용자가 실제로 명령을 실행할 때만 정보를 보고합니다(Enter 키를 누르는 것이 아님).print_wall_clock_time
print_wall_clock_time
실수로 둘 중 하나를 대화식으로 재정의할 가능성을 줄이기 위해 call_date_before_command
, , 및 의 이름을 바꿀 수 있습니다 .command_flag
print_wall_clock_time
Twas_brillig_and_the_slithy_toves
Did_gyre_and_gimble_in_the_wabe
All_mimsy_were_the_borogoves