lsof: 한 줄에 사용자 정의 필드를 인쇄합니다.

lsof: 한 줄에 사용자 정의 필드를 인쇄합니다.

-F옵션을 사용하여 lsof인쇄할 필드를 지정할 수 있습니다.

lsof -w -F pcfn

그러나 출력은 각 필드마다 하나씩 여러 줄로 분할됩니다.

p23022
csleep
fcwd
n/home/testuser
frtd
n/
ftxt
n/usr/bin/sleep
fmem
n/usr/lib/locale/locale-archive
fmem
n/usr/lib/x86_64-linux-gnu/libc-2.28.so
fmem
n/usr/lib/x86_64-linux-gnu/ld-2.28.so
f0
n/dev/pts/20
f1
n/dev/pts/20
f2
n/dev/pts/20

한 줄에 사용자 정의 필드를 인쇄하는 방법은 무엇입니까?

답변1

출력은 lsof -F사후 처리가 가능합니다.

AFAICT, 백슬래시 및 제어 문자(TAB 및 개행 문자 포함)는 적어도 일부 기호 (여기서는 각각 백슬래시, TAB 및 개행 문자를 의미 ) 개행)² lsof가 있는 필드 중 하나에서 발견될 때 렌더링되므로 다음이 가능해야 합니다. 열려 있는 각 파일에 대해 다음과 같이 탭으로 구분된 값과 여전히 사후 처리할 수 있는 값을 사용하여 이 출력 형식을 지정합니다.\x\\\t\n

LC_ALL=C lsof -w -F pcfn | LC_ALL=C awk -v OFS='\t' '
  {t = substr($0, 1, 1); f[t] = substr($0, 2)}
  t == "n" {print f["p"], f["c"], f["f"], f["n"]}'

샘플에서 다음을 제공합니다.

23022   sleep   cwd /home/testuser
23022   sleep   rtd /
23022   sleep   txt /usr/bin/sleep
23022   sleep   mem /usr/lib/locale/locale-archive
23022   sleep   mem /usr/lib/x86_64-linux-gnu/libc-2.28.so
23022   sleep   mem /usr/lib/x86_64-linux-gnu/ld-2.28.so
23022   sleep   0   /dev/pts/20
23022   sleep   1   /dev/pts/20
23022   sleep   2   /dev/pts/20

후에 lsof -w -F pcfn -a -d3 -p "$!":

perl -e '$0 = "a\nb\t"; sleep 999' 3> $'x\ny z\tw' &

이는 다음을 제공합니다:

7951    a\nb\t  3   /home/stephane/x\ny z\tw

이 출력에서 ​​실제 파일 n이름을 얻으려면 여전히 시퀀스를 디코딩해야 합니다 \x.

알아채다lsof명령을 사용하면 각 프로세스의 각 스레드에 대한 기록을 얻을 수 있습니다., 그러나 필드 목록에 스레드 ID를 포함하지 않았으므로 프로세스의 어느 스레드가 파일을 열었는지 알 수 없습니다. 동일한 프로세스의 스레드가 다른 열린 파일을 거의 갖지 않으므로 문제가 아닐 수도 있지만 여전히 의미는 다음과 같습니다. 당신은 거기에 있을 것입니다. 파이프로 제거할 수 있는 중복 항목이 있습니다 LC_ALL=C sort -u. lsof 4.90 이상을 사용할 수도 있습니다 -Ki.

다음을 포함할 수도 있습니다.유형도메인은 해석 방법을 알고 있습니다.이름대지. 열려 있는 파일이 삭제될 때 lsof추가하는 것에 주의하세요  (deleted). 그리고 제가 아는 한 이름이 끝나는 파일에서 이를 명확하게 구분할 수 있는 확실한 방법은 없습니다. (deleted)


lsof¹ 이것이 반드시 개행 문자가 포함된 파일 이름을 안전하게 처리할 수 있다는 의미는 아닙니다 . 예를 들어 Linux에서는 여전히 /proc/net/unixnetlink 대신 이전 API를 사용하여 Unix/추상 도메인 소켓에 대한 정보를 검색하며, 소켓 파일 경로에 개행 문자가 포함되어 있으면 API가 완전히 중단됩니다. 가짜 파일 경로를 사용하여 소켓에 바인딩하면 lsof프로세스에 다른 소켓이 아닌 특정 소켓이 열려 있다고 쉽게 믿을 수 있습니다.

² 비제어 문자를 유지하지만 α일부 로케일(예: BIG5의 0xa3 0x5c)에서 일부 문자의 인코딩에는 백슬래시 인코딩이기도 한 0x5c 바이트가 포함되어 있습니다. 따라서 여기서는 \xHH후처리 중에 예상치 못한 상황을 피하기 위해 0x7f 이상의 모든 바이트가 렌더링되도록 로케일을 C로 강제 설정합니다 .

답변2

Awk는 제가 가장 좋아하는 망치입니다.

  • 값이 항상 제공되지는 않으므로 필드와 일치하는 이름의 변수를 사용하고 "-"로 초기화합니다.
  • "n"이 마지막인지 여부에 따라 다릅니다. 우리가 그때까지 모든 필드를 보았다고 가정하면 이를 확인하면 인쇄물이 트리거됩니다. 물론 인쇄 순서는 무엇이든 될 수 있습니다.
lsof -w -F pcfn|awk '
BEGIN {
        p=c=f=n="-"
}
# extract field & value for every line
{field=substr($0,1,1); value=substr($0,2)}
# assign value to matching variable name
/^p/{p=value}
/^c/{c=value}
/^f/{f=value}
/^n/{n=value
        print p,c,f,n
        p=c=f=n="-"
}
'

결과는 다음과 같습니다.

1 systemd cwd /
- - rtd /
- - txt /usr/lib/systemd/systemd
- - mem /lib64/libm-2.26.so
and so on...

답변3

p원하는 것이 f각 PID( field ) 또는 각 필드 설명자( field )의 출력 뿐인 경우하나철사. 설명서에 나와 있는 내용을 시도해 볼 수 있습니다.

예를 들어, -F pcfn'' will select the process ID (`p'), command name (`c'), file descriptor (`f') and file name (`n') fields with an NL field terminator character;-F pcfn0''은 NUL(000) 필드 종결자가 있는 동일한 출력을 선택합니다.

lsof -w -F pcfn0

pf각 또는 그룹에 대해 한 줄(NUL 포함)을 인쇄 합니다 . Less를 사용하여 출력을 볼 수 있습니다. 매뉴얼에 다음과 같이 명시되어 있으므로 모든 필드가 표시된다는 의미는 아닙니다.

Lsof는 각 프로세스 또는 파일 세트에 대한 모든 필드를 생성하지 않고 사용 가능한 필드만 생성합니다.

그러나 분명히 -F 옵션은 데이터를 다음으로 전송하는 데 사용됩니다.기타 프로그램. 설명서에 따르면:

lsof는 표시용 형식이 아닌 다른 프로그램에서 구문 분석할 수 있는 출력을 생성합니다. 자세한 내용은 -F, 옵션 설명 및 다른 프로그램의 출력 섹션을 참조하세요.

따라서 선택의 여지가 없으며 lsof의 출력은 다른 프로그램에서 처리되어야 합니다. 과거에 ac 프로그램이나 awk 스크립트를 사용한 적이 있습니다. lsof 출력을 올바르게 처리하는 방법에 대한 awk 예는 스크립트 디렉토리에 제공됩니다.

 /usr/share/doc/lsof/examples/list_fields.awk

https://github.com/Distrotech/lsof/blob/master/scripts/list_fields.awk아니면 예를 들어.

또한 lsof 배포판 lsof_fields.h에는 lsof.

이것이 당신이 해야 할 일인 것 같습니다. 이는 각 필드(행)의 첫 번째 문자(제공된 필드의 식별자)를 구문 분석하고 이를 모두 인쇄할 수 있는 단일 테이블로 연결하는 것을 의미합니다.

이 답변lsof의 출력을 구문 분석하는 방법을 보여주었습니다.

답변4

awk좋습니다. 하지만 덜 알려진 대체 명령을 제공하고 싶습니다.pr. 이 명령의 텍스트 분할 기능을 다음과 결합했습니다.column이 명령은 아름답고 사용자 정의 가능한 형식으로 출력을 표시합니다.

lsof -w -F pcfn / | pr --column 4 --across | column

4이것의 또 다른 이점은 관심 있는 필드 수에 숫자를 일치시키기만 하면 관심 있는 출력에 따라 쉽게 변경할 수 있다는 것입니다.

다음은 출력의 예입니다.

p1682             cPM2 v5.2.0: God  fcwd              n/
frtd              n/                ftxt              n/home/aaron/.nvm
fmem              n/usr/lib/x86_64- fmem              n/usr/lib/x86_64-
fmem              n/usr/lib/x86_64- fmem              n/usr/lib/x86_64-
fmem              n/usr/lib/x86_64- fmem              n/usr/lib/x86_64-

pr필요한 경우 사용자 정의 구분 기호를 지정하여 아래와 같은 출력을 제공할 수도 있으며, 원하는 대로 사용자 정의할 수 있습니다. 예:

lsof -w -F pcfn / | head -20 | pr -ts' ' --column 4 -a

산출:

p1682 cPM2 v5.2.0: God fcwd n/
frtd n/ ftxt n/home/aaron/.nvm/versions/node/v16.14.2/bin/node
fmem n/usr/lib/x86_64-linux-gnu/libnss_dns-2.31.so fmem n/usr/lib/x86_64-linux-gnu/libresolv-2.31.so
fmem n/usr/lib/x86_64-linux-gnu/libc-2.31.so fmem n/usr/lib/x86_64-linux-gnu/libpthread-2.31.so
fmem n/usr/lib/x86_64-linux-gnu/libgcc_s.so.1 fmem n/usr/lib/x86_64-linux-gnu/libm-2.31.so

관련 정보