ps
옵션이 무엇이든 또는 결과를 grep하더라도 ps
열이 무엇인지 알려주는 출력의 첫 번째 줄을 얻을 수 있도록 작은 래퍼를 작성하고 싶습니다 . 예를 들어 의 출력은 ps_wrapper -aux | grep thing
다음과 같습니다.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
name 33925 1.0 0.0 9972 5528 pts/0 Ss 19:34 0:00 /bin/thing
나는 그것이 효과가 있는지 확인하려고 노력했고 tee
다음과 같은 것을 시도했습니다.
function ps_wrapper {
tmpfile=$(mktemp)
ps $@ > $tmpfile
head -n 1 $tmpfile >> /dev/stdout
cat $tmpfile
}
그러나 나는 "수동으로" 작성하더라도 /dev/stdout
여전히 grep
.
ps
인쇄되는 열은 사용된 옵션에 따라 변경될 수 있으므로 실행 중인 실제 명령의 첫 번째 줄을 인쇄하고 싶습니다.
저는 zsh를 사용하고 있지만 더 적합한 것이 있다면 다른 것을 사용해도 괜찮습니다.
읽어 주셔서 감사합니다.
답변1
일반적으로 "파이프를 우회"하는 것은 불가능합니다. 즉, 파이프 없이 출력이 갈 수 있는 곳으로 출력을 보내는 것입니다. 그러나 파이프를 우회하고 터미널과 같이 선택한 다른 위치로 출력을 리디렉션할 수 있습니다. 특수 파일은 /dev/tty
항상 현재 터미널을 나타냅니다.
function ps_wrapper {
tmpfile=$(mktemp)
ps "$@" > $tmpfile
head -n 1 $tmpfile >/dev/tty
cat $tmpfile
rm $tmpfile
}
원래 위치를 "저장"하고 아래로 전달하면 파이프를 우회할 수도 있습니다.파일 설명자를 통해. 하지만 ps_wrapper
함수에서는 그렇게 할 수 없습니다 .
function ps_wrapper {
tmpfile=$(mktemp)
ps "$@" > $tmpfile
head -n 1 $tmpfile >&3
cat $tmpfile
rm $tmpfile
}
{ ps_wrapper … | grep …; } 3>&1
임시 파일 생성을 방지하는 방법에는 여러 가지가 있습니다. 몇 가지를 언급하겠습니다. 달리 명시하지 않는 한, 이 답변의 솔루션은 다음과 같은 경우 bash에서 작동합니다.변수 및 명령 대체 주위에 큰따옴표 추가.
함수 호출 방식을 변경하려는 경우 head
파이프 오른쪽에서 및 연속적으로 두 가지를 모두 호출할 수 있습니다. 첫 번째 줄을 읽고 인쇄하고 나머지는 후속 작업을 위해 남겨 둡니다.grep
head
ps … | { head -n 1; grep …; }
당신은 할 수프로세스 교체그리고 tee
또는zsh에 tee
유사한 기능 내장( multios
)출력을 복사하려면 하나의 스트림을 head -n 1
선택한 명령으로 보내고 다른 스트림을 선택한 명령으로 보냅니다. 그러나 각 스트림을 명령으로 파이프하면 둘 사이에 경합이 발생하고 head
속도가 충분히 빠르지 않으면 첫 번째 줄이 맨 위에 표시되지 않을 수 있습니다. 상당히 빠르기 때문에 자주 작동할 수 있지만 , 예를 들어 디스크 캐시에 head
있지만 그렇지 않은 경우에는 보장할 수 없습니다 .grep
head
ps | tee >(head -n 1 >/dev/tty) | grep …
ps >(head -n 1 >/dev/tty) | grep … # zsh only, only if multios is not disabled
awk를 사용하여 첫 번째 줄을 표시한 다음 나머지 줄을 전달할 수 있습니다.
function ps_wrapper {
ps "$@" | awk 'NR == 1 {print >"/dev/tty"} NR != 1 {print}'
}
설명하다:
- awk는 입력을 한 줄씩 처리합니다.
- 건강 상태{암호} 구현하다암호만족의 선에서건강 상태.
NR
줄 번호입니다.- awk의 리디렉션은 셸과 정확히 동일하게 작동하지는 않지만 충분히 유사합니다.
print
인수 없이 입력 행을 인쇄합니다.
또 다른 접근 방식은 필터 기능을 단일 명령으로 구축하는 것입니다. 인수에 표시되지 않는 ps
구분 기호 로 사용할 문자열을 선택하세요(예: ) |
.
function pipe_preserving_first_line {
local lhs
lhs=()
while [[ $1 != '|' ]]; do
lhs+=($1)
shift
done
shift
"${lhs[@]}" | {
head -n 1;
"$@"
}
}
pipe_preserving_first_line ps u \| grep foo
예를 들어 , 명령 이름으로 프로세스를 일치시키려면 ps
grep 대신 일치 함수를 사용할 수 있습니다 .-C
ps uww -C mycommand
grep을 사용하는 것 외에도 pgrep
일치 도구를 사용할 수도 있습니다.
ps -p $(pgrep -d, mycommand)