ISO 날짜 형식으로 PS 출력?


9

lstart프로세스 를 (프로세스 시작) 별로 정렬하고 싶습니다 .

ps -eo lstart,pid,cmd 

YYYY-MM-DD HH : MM : SS와 같은 ISO 형식으로 lstart를 출력하는 방법이 있습니까?

그러나 정렬만으로는 해결되지 않습니다. ISO 날짜 형식을 원합니다.


왜 그렇게 lstart잘못된 형식이 있습니까? RFC 2822와 비슷하지만 연말이 다가옵니다.
vaughan

답변:


10

lstartISO 형식 으로 출력하는 방법이 YYYY-MM-DD HH:MM:SS있습니까?

awk+ date협력 :

ps -eo lstart,pid,cmd --sort=start_time | awk '{ 
       cmd="date -d\""$1 FS $2 FS $3 FS $4 FS $5"\" +\047%Y-%m-%d %H:%M:%S\047"; 
       cmd | getline d; close(cmd); $1=$2=$3=$4=$5=""; printf "%s\n",d$0 }'

ps etimes 키워드를 사용한 대체 방법 (프로세스가 시작된 후 경과 된 시간 (초)) :

ps -eo etimes,pid,cmd --sort=etimes | awk '{ 
       cmd="date -d -"$1"seconds +\047%Y-%m-%d %H:%M:%S\047"; 
       cmd | getline d; close(cmd); $1=""; printf "%s\n",d$0 }' 
  • date -d -"$1"seconds-현재 타임 스탬프와 elapsed시간 의 차이 는 프로세스 의 타임 스탬프 값을 제공합니다.

2
더 쉬운 방법이 없습니까?
guettli

3
etimes대신 ps 형식을 사용 lstart하면 경과 시간을 초 단위로 얻을 수 date -d -999seconds있습니다.
meuh

@meuh, 네, 조금 짧은 것, 내가 업데이 트했습니다
RomanPerekhrest

@guettli, 쉽게 호출 할 수는 없지만 조금 더 짧은 길을 얻었습니다
RomanPerekhrest

4

다음과 같이 정렬 할 수 있습니다.

ps -eo lstart,pid,cmd --sort=start_time

감사합니다. 질문을 확장했습니다. ISO 날짜 형식도 원합니다.
guettli

2

참고 lstart표준 유닉스 중 하나가 아닌 ps열입니다.

모든 시스템에 시스템이 하나있는 것은 아니며 구현마다 그리고 잠재적으로 로케일마다 출력이 다릅니다.

예를 들어 FreeBSD 또는 psfrom procps-ng(일반적으로 내장되지 않은 Linux 기반 시스템에 있음) 및 C로켈에서 다음을 얻을 수 있습니다.

Wed Nov  1 12:36:15 2017

macOS에서 :

Wed  1 Nov 12:36:15 2017

또한 GMT 오프셋을 제공하지 않기 때문에 DST를 구현하는 시간대 (동일한 날짜가 두 번 나타나는 연도에 한 시간이 있음)에서 출력이 모호하며 항상 시간순으로 정렬되는 것은 아닙니다.

여기에서 시간을 UTC로 강제하고 perlDate::Manip모듈을 사용 하여 다른 자연 형식을 이해하는 방식으로 날짜를 구문 분석 할 수 있습니다.

(export TZ=UTC0 LC_ALL=C
  ps -A -o lstart= -o pid= -o args= |
    perl -MDate::Manip -lpe '
      s/^(\s*\S+){5}/UnixDate(ParseDate($&), "%Y-%m-%dT%T+00:00")/e' |
    sort
)

또는 다음과 ksh93같은 날짜 형식도 인식합니다.

(export TZ=UTC0 LC_ALL=C
  unset -v IFS
  ps -A -o lstart= -o pid= -o args= |
    while read -r a b c d e rest; do
      printf '%(%FT%T+00:00)T %s\n' "$a $b $c $d $e" "$rest"
    done
)

(각 라인에서 후행 공백을 제거합니다)

또는 zshGNU 와 함께 date:

(export LC_ALL=C TZ=UTC0
  (){
    paste -d '\0' <(cut -c1-24 < $1 | date -f- --iso-8601=s) \
                  <(cut -c25-  < $1) | sort
  } =(ps -A -o lstart= -o pid= -o args=)
)

또는 Linux에서만 bash(또는 zsh) GNU 만 사용하십시오 date.

(export LC_ALL=C TZ=UTC0
  {
    paste -d '\0' <(cut -c1-24 | date -f- --iso-8601=s) \
                  <(cut -c25- < /dev/stdin) | sort
  } <<< "$(ps -A -o lstart= -o pid= -o args=)"
)

또한 프로세스 시작 시간이 프로세스가 명령을 실행 한 마지막 시간과 반드시 ​​같을 필요는 없다는 점에 유의하십시오. 프로세스는 일반적으로 수명 기간 동안 둘 이상의 명령을 실행할 수 있으므로 (일반적으로 명령을 실행하지 않는 명령은 아님) . 다시 말해, 명령 ( args필드, 표준 등가 cmd)이 시작된 시간과 반드시 ​​일치하지는 않습니다 .

$ sh -c 'sleep 4; exec sleep 123' & sleep 234 & sleep 5
[1] 9380
[2] 9381(export TZ=UTC0 LC_ALL=C; ps -o lstart,pid,args | perl -MDate::Manip -lpe 's/^(\s*\S+){5}/UnixDate(ParseDate($&), "%Y-%m-%dT%T+00:00")/e')

2017-10-30T17:21:06+00:00  3071 zsh
2017-11-01T15:47:48+00:00  9380 sleep 123
2017-11-01T15:47:48+00:00  9381 sleep 234

4 초 후에 시작된 것처럼 어떻게 sleep 123동시에 시작되었는지 확인 하십시오 sleep 234. 9388 프로세스가 실행 되기 전에 sh(그리고 4 초 동안 대기 중 sleep 4) 대화 형 쉘이 포크로 코드를 sleep 123실행 zsh했기 때문에 다른 시점에서 해당 프로세스에 대해 프로세스를 실행했기 때문입니다. 볼 ps출력 : zshshsleep).


1
답변 주셔서 감사합니다. 이제 전보다 더 많은 질문이 있습니다. 나는 쉽고 간단한 해결책이 있다고 생각했다.
guettli

1

다음은 성능이 더 높은 구현입니다 (한 줄에 새 프로세스를 실행할 필요가 없음).

ps -eo etimes,pid,args --sort=etimes | awk 'BEGIN{now=systime()} {$1=strftime("%Y-%m-%d %H:%M:%S", now-$1); print $0}'

열 순서도 쉽게 변경할 수 있습니다. 예를 들어 pid첫 번째 및 시작 시간을 두 번째 열로 :

ps -eo pid,etimes,args --sort=etimes | awk 'BEGIN{now=systime()} {$2=strftime("%Y-%m-%d %H:%M:%S", now-$2); print $0}'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.