iproute2 ss 출력에서 ​​청취 TCP 포트 추출

iproute2 ss 출력에서 ​​청취 TCP 포트 추출

프로세스(예: apache2)가 수신 대기 중인 포트를 찾고 이(tcp) 포트 번호만 file1.txt 파일에 인쇄하고 싶습니다.

  • 내가 시도한 명령은 다음과 같습니다.

    $ ss -atpln | grep 'apache2' | awk -F':' '{print $2}' > file1.txt
    
  • 이것은 내 출력입니다(file1.txt로):

    80     *
    

내 출력이 "*"가 아닌 포트 번호(80)인지 어떻게 확인할 수 있나요?


OP에 제공된 중요한 정보를 추가하기 위해 Ed Morton이 편집함코멘트:

내 시스템에서 다음 순서를 기록해 두십시오.

$ ss -atpln | grep apache2

출력은 다음과 같습니다

LISTEN 0 511 *:80 *:* users:(("apache2",pid=55338,fd=4),("apache2",pid=55337,fd=4),("apache2",pid=856,fd=4))

답변1

# ss -atpln | awk -F ':|[[:blank:]]+' '/apache2/ {print $5}'
443
443
443
80
80
80

콜론이나 하나 이상의 "공백" 문자(예: 공백 또는 탭)를 필드 구분 기호로 사용합니다. 이는 인쇄하려는 필드(포트 번호)가 이제 필드 5임을 의미합니다.

grep이미 사용하고 있다면 사용할 필요가 없습니다 awk. awk는 grep의 도움 없이 패턴 일치를 완벽하게 수행할 수 있습니다.

sort -u고유한 포트 번호만 인쇄하려면 출력을 파이프로 연결해야 합니다 .

그런데 예제 출력에 각각 443과 80이라는 세 줄이 있는 이유가 궁금하다면 내 시스템에서 apache2는 포트 80과 443에서 세 개의 다른 IP 주소(세 개의 다른 가상 호스트에 대해)를 수신하도록 구성되어 있습니다. *:80그리고 *:443.

답변2

perl정보를 추출하기 위해 보다 명시적인 입력 일치를 사용 하고 수행합니다.

ss -Otpln |
  perl -slne '
    print $1 if m{
      ^ LISTEN \s+ # State
        \d+ \s+    # Recv-Q
        \d+ \s+    # Send-Q
        (?: 0\.0\.0\.0 | \[::\] | \*) : (\d+) \s+ # source address on INADDR_ANY
                                                  # or INADDR6_ANY only
        \S+ \s+    # dest address
        users: .* \(" \Q$name\E ",pid # match on process name
      }x && ! $already_seen{$1}++' -- -name=apache2

귀하의 출력 형식이 내 출력 형식과 다릅니다(나는 0.0.0.0와일드카드 IPv4 주소를 받고 [::]당신은 IPv6 주소를 받고 있음 *). 이는 ss출력 형식이 그다지 안정적이지 않을 수 있음을 의미합니다. 대신 일괄 처리를 위한 패턴을 갖고 프로세스 이름별로 일치시키는 것을 ss사용할 수 있습니다 .lsof

lsof -Fn -wnMPa -c apache2 -i tcp -s tcp:listen |
  sed -n 's/^n\*://p' |
  sort -nu

또한 Linux가 아닌 시스템에도 이식 가능합니다.

관련 정보