한 명령의 출력을 두 개의 다른 명령으로 파이프하려고 합니다 awk
. 다음과 같은이 게시물tee
교체해서 사용하고 있습니다 . 그러나 교체 프로세스의 출력을 볼 수 없습니다.
nvidia-smi | tee >(awk '/ C / {print $6}') | awk '/ C / {print $3}' | xargs -r ps -o user
여기에는 모든 GPU 프로세스에 대한 사용자 및 메모리 사용량이 표시됩니다. 메모리 사용량과 PID는 및 각각에 의해 추출되고 nvidia-smi
후자는 에 파이프됩니다. 그러나 출력에는 사용자만 포함됩니다.awk '/ C / {print $6}'
awk '/ C / {print $3}'
ps -o user
내가 원하는 건
<memory-of-process1> <name-of-user-running-process1>
<memory-of-process2> <name-of-user-running-process2>
<memory-of-process3> <name-of-user-running-process3>
etc
내가 얻는 것은
<name-of-user-running-process1>
<name-of-user-running-process2>
<name-of-user-running-process3>
etc
제안된 대로 첫 번째 awk 명령에 fflush()
또는 추가를 시도했습니다.stdbuf -o0
여기.
답변1
쉘 스크립트를 사용하는 보다 컴팩트한 솔루션:
nvidia-smi | grep ' C ' | while read _ _ pid _ _ mem; do
user="$( ps -o user "${pid}" | tail -n +2 )"
printf '%8s %6d %s\n' "${mem}" "${pid}" "${user}"
done
이는 pid당 3개의 추가 프로세스를 실행한다는 점에 유의하세요.
원래 솔루션은 다음을 사용합니다 awk
.
#! /bin/bash
function nvidia-smi { cat <<'[][]'
A C 937 D E 1.7MB
A C 1232 D E 0.25MB
A E 6112 D E 13MB
A C 2008 D E 437KB
A C 2024 D E 314157
[][]
}
AWK='
/ C / { Pid[NR] = $3; xPid[$3] = NR; Mem[NR] = $6; }
END {
for (j in Pid) pp = pp "," Pid[j];
cmd = "ps 2>&1 -o pid,user -p " substr (pp, 2);
while (cmd | getline)
if ($1 in xPid) User[xPid[$1]] = $2;
close (cmd);
fmt = "%8s %6d %s\n";
for (j = 1; j <= NR; ++j)
if (j in Mem)
printf (fmt, Mem[j], Pid[j], User[j]);
}
'
nvidia-smi | awk "${AWK}"
nvidia-smi 함수는 일부 테스트 데이터를 제공할 뿐입니다. 이를 폐기하세요. AWK 변수(작은따옴표 사이의 여러 줄 상수의 12번째 줄)와 그 아래의 짧은 파이프가 필요합니다.
시험. 사용 중인 메모리의 PID를 포함했습니다.
paul $ ./nVid
1.7MB 937 syslog
0.25MB 1232 root
437KB 2008 postfix
314157 2024 paul