Bash
管道到多個 awk 命令
我正在嘗試將一個命令的輸出通過管道傳輸到兩個不同的
awk
命令。在這篇文章之後,我正在使用tee
和處理替換。但是,我看不到替代過程的輸出。nvidia-smi | tee >(awk '/ C / {print $6}') | awk '/ C / {print $3}' | xargs -r ps -o user
這應該顯示所有 gpu 程序的使用者和記憶體使用情況。
nvidia-smi
記憶體使用情況和 PID分別由提取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
我已嘗試按照此處
fflush()
的建議將或添加stdbuf -o0
到第一個 awk 命令。
使用 shell 腳本的更緊湊的解決方案:
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 執行三個額外的程序。
原始解決方案使用
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