В целях создания тестового примера рассмотрим ситуацию, когда несколько процессов ssh-agent
запущены и имеют открытые сокеты. То есть Пользователь запускает ssh-agent
несколько раз и теряет информацию о сокете / PID, указанную при запуске агента:
$ find /tmp -path "*ssh*agent*" 2>/dev/null
/tmp/ssh-0XemJ4YlRtVI/agent.14405
/tmp/ssh-W1Tl4i8HiftZ/agent.21283
/tmp/ssh-w4fyViMab8wr/agent.10966
Позже пользователь хочет программно определить владельца PID конкретного сокета ssh-agent (т.е. /tmp/ssh-W1Tl4i8HiftZ/agent.21283):
$ stat /tmp/ssh-W1Tl4i8HiftZ/agent.21283
File: '/tmp/ssh-W1Tl4i8HiftZ/agent.21283'
Size: 0 Blocks: 0 IO Block: 4096 socket
Device: 805h/2053d Inode: 113 Links: 1
Access: (0600/srw-------) Uid: ( 4000/ myname) Gid: ( 4500/ mygrp)
Access: 2018-03-07 21:23:08.373138728 -0600
Modify: 2018-03-07 20:49:43.638291884 -0600
Change: 2018-03-07 20:49:43.638291884 -0600
Birth: -
В этом случае, потому что ssh-agent
назвал свой сокет как наблюдатель, человек может догадаться, что сокет принадлежит PID 21284, потому что имя сокета содержит числовой компонент, который является единичным от PID, идентифицируемого ps
:
$ ps -ef | grep ssh-agent
myname 10967 1 0 16:54 ? 00:00:00 ssh-agent
myname 14406 1 0 20:35 ? 00:00:00 ssh-agent
myname 21284 1 0 20:49 ? 00:00:00 ssh-agent
Весьма неразумно делать какие-либо предположения о том, что идентификаторы PID будут настолько надежными, что всегда будут отключаться только одним, но также можно предположить, что не все создатели сокетов будут так красиво называть сокеты.
@ Ответ Сайфера указывает на простое решение проблемы идентификации PID владельца сокета, но оно неполное, поскольку lsof
на самом деле может идентифицировать этот PID только с повышенными разрешениями. Без повышенных разрешений никаких результатов не ожидается:
$ lsof /tmp/ssh-W1Tl4i8HiftZ/agent.21283
$
При повышенных разрешениях идентифицируется PID:
$ sudo lsof /tmp/ssh-W1Tl4i8HiftZ/agent.21283
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ssh-agent 21284 myname 3u unix 0xffff971aba04cc00 0t0 1785049 /tmp/ssh-W1Tl4i8HiftZ/agent.21283 type=STREAM
В этом случае запрос выполнял владелец PID (myname) и сокета, поэтому казалось, что повышенные разрешения не нужны. Кроме того, задача, выполняющая запрос, не должна была повышать разрешения, поэтому я искал другой ответ.
Это привело меня к ответу @ whoplisp, в котором предлагалось netstat -tulpen
в качестве решения проблемы ОП. Хотя это могло быть эффективным для OP, командная строка слишком ограничена, чтобы служить командой общего назначения, и в этом случае была совершенно неэффективна (даже с повышенными разрешениями).
$ sudo netstat -tulpen | grep -E -- '(agent.21283|ssh-agent)'
$
netstat
, однако, может приблизиться, если используется другая командная строка:
$ netstat -ap | grep -E -- '(agent.21283)'
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.)
unix 2 [ ACC ] STREAM LISTENING 1785049 - /tmp/ssh-W1Tl4i8HiftZ/agent.21283
К сожалению, и здесь PID недоступен без повышенных разрешений:
$ sudo netstat -ap | grep -E -- '(agent.21283|ssh-agent)'
unix 2 [ ACC ] STREAM LISTENING 1765316 10967/ssh-agent /tmp/ssh-w4fyViMab8wr/agent.10966
unix 2 [ ACC ] STREAM LISTENING 1777450 14406/ssh-agent /tmp/ssh-0XemJ4YlRtVI/agent.14405
unix 2 [ ACC ] STREAM LISTENING 1785049 21284/ssh-agent /tmp/ssh-W1Tl4i8HiftZ/agent.21283
Однако из двух решений lsof
явно выигрывает в гонках:
$ time sudo netstat -ap | grep -E -- '(agent.21283|ssh-agent)' >/dev/null
real 0m5.159s
user 0m0.010s
sys 0m0.019s
$ time sudo lsof /tmp/ssh-W1Tl4i8HiftZ/agent.21283 >/dev/null
real 0m0.120s
user 0m0.038s
sys 0m0.066s
Согласно справочной странице netstat
существует еще один инструмент:
$ man netstat | grep -iC1 replace
NOTES
This program is mostly obsolete. Replacement for netstat is ss. Replacement for netstat -r is ip route. Replacement for netstat -i
is ip -s link. Replacement for netstat -g is ip maddr.
К сожалению, ss
также требуются повышенные разрешения для идентификации PID, но он превосходит netstat
и lsof
время выполнения:
$ time sudo ss -ap | grep -E "(agent.21283|ssh-agent)"
u_str LISTEN 0 128 /tmp/ssh-w4fyViMab8wr/agent.10966 1765316 * 0 users:(("ssh-agent",pid=10967,fd=3))
u_str LISTEN 0 128 /tmp/ssh-0XemJ4YlRtVI/agent.14405 1777450 * 0 users:(("ssh-agent",pid=14406,fd=3))
u_str LISTEN 0 128 /tmp/ssh-W1Tl4i8HiftZ/agent.21283 1785049 * 0 users:(("ssh-agent",pid=21284,fd=3))
real 0m0.043s
user 0m0.018s
sys 0m0.021s
В заключение может показаться, что для некоторых идентификаторов PID требуется повышенное разрешение.
Примечание. Не всем операционным системам требуются повышенные разрешения. Например, SCO Openserver 5.0.7 lsof
, казалось, работал нормально, без повышения разрешений.
Предостережение: этот ответ может не соответствовать квалификации ОП для нахождения "первоначального создателя" сокета. В использованном примере, без сомнения, PID 21283 был инициатором создания сокета, так как этот PID указан в имени сокета. Ни lsof
, ни netstat
не идентифицировали PID 21283 как первоначального создателя, хотя ясно, что PID 21284 является текущим сопровождающим.