프로세스(예: 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가 아닌 시스템에도 이식 가능합니다.