A Unix Utility to Know About: lsof (2009)
catonmat.net
catonmat.net
function fuser($relativeFile){
$file = Resolve-Path $relativeFile
foreach ( $Process in (Get-Process)) {
foreach ( $Module in $Process.Modules) {
if ( $Module.FileName -like "$file*" ) {
$Process | select id, path
}
}
}
}
In use: > fuser .\node_modules\
Id Path
-- ----
2660 C:\Program Files\nodejs\node.exe
Since it's object pipelining, you can: > fuser .\node_modules\ | killlsof | grep TCP
netstat --ip -a -p
Those particular options mean to show just IP ports (UDP/TCP), in all statuses (active, listening) and to display the local process which is involved.
In regard to ps you can memorize a few commands until something truly weird comes up since you will probably use other more specialized snapshotting and tracing tools for anything somewhat difficult to troubleshoot.
Yup, this is true. And I did. But sometimes you just need less dense manual pages.
- grep bash /proc/*/status
- readlink /proc/*/fd/* | grep /runedit: `ps aux|grep`, indeed. Silly me in the early hours of a rest day :).
I've made a note to name the executable for my next daemon "humans".
See also the 'reboot' (or is it the 'poweroff' ?) command, which is much more direct than the Linux equivalent...
ps -ef | grep $1 | awk '{print "kill -9 " $2}' | sh
Usually stored as /usr/local/bin/kllI've found it's very useful for killing specific Java programs without having to killall -9 java.
(and, yeah, I should probably be using ps -efww instead of ps -ef, but old habits die hard... I've already got ps aliased to ps -ww for interactive use, so I should probably change this script...)
What's wrong with doing that?
I've been doing that for so long I don't know why I do it
ps -C procname
ps -p pid
ps -u username
ps -t ttyname
ps -f [-w [-w]]
ps -o output-format pgk ()
{
[ -z "$*" ] && echo 'Usage: pgk <pattern>' && return 1;
pgrep -fl $*;
[ "$?" == "1" ] && echo 'No processes match' && return 1;
echo 'Hit [Enter] to pkill, [Ctrl+C] to abort';
read && pkill -f $*
}Anyway, it's just a reflex now to always:
ps aux | grep <program> | grep -v grep ps -ef | grep [p][r][o][g][r][a][m]This is why I love HN, I learn stuff I never knew I wanted to know!
Yes, I do sometimes have processes with camel-cased names which I may or may not remember exactly. So you:
ps auwx | grep -i {lc-version-of-camel-cased-name}That's why I was so happy to stumble across pstree the other day. Even the man page is excellent! Every now and again, I'll come across a util like this that I can put into immediate action w/o lots of deciphering. pstree -a is awesome for a relative newbie like me.
That together with a dump of active iptables rules normally results in an immediate fix for 90% of "why can't I connect to X" problems :)
"FAQ about lsof"[1] is very instructive.
[1] ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
The following can be adapted to provide other information: whatever procfs provides. This is a rough equivalent of "pgrep -fl .|less". Work-in-progress. Don't know if Linux grep has "-a" option.
#! /bin/sh
# Almquist clone, not Bash
case $# in
0)
exec grep -a . proc/[0-9]*/cmdline \
|exec tr '\000' '\040' \
|exec sed '
/grep -a .* proc/d;
#parent: '"$$"';
s/proc./ /;
s/\/cmdline:/ /;
' \
|exec less
;;
*)
exec grep -a . proc/[0-9]*/cmdline \
|exec tr '\000' '\040' \
|exec grep $@ \
|exec sed '
/grep '"$@"'/d;
s/proc./ /;
s/\/cmdline:/ /;
' \
|exec less
esacIf you don't like the backslash-newline-pipe sequence, if you put the pipe at the end of the previous line, you don't need the backslash; but it's less obvious that the next line is operating on the output of the previous.
Multi-line arguments to sed can be a pain (good luck getting your editor to auto-indent them). Instead, you can use -e to specify multiple sed commands.
There's nothing in there that would make it not work in bash. That should work in any Bourne-family shell.
It only handles 0 or 1 arguments correctly, not > 1.
Multiple arguments could be added if you want that. I personally do not need it as I search the cmdline patterns I need without using spaces. I use dots instead. Quick and dirty.
I write 100's of these small scripts for my own use only so I have my own style, peculiar as it may be. I never need indentation because I always keep scripts short; I only use it occasionally and randomly.
I do not use -e with sed, unless I'm using branches or loops.
The execs seem superfluous but actually make a difference, at least on the UNIX I use. Try it with and without and see if you notice.
All my scripts are portable to Bash, but they're also portable to the most basic of Bourne-compatible shells too. I do not use Bash.
Normally I would only add exec to the last command in the script, as djb does. But then I started experimenting with using it after pipes.
If you or anyone can explain why this could make scripts "seem" to execute faster, I would be grateful.
Here's the shell source: ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-release-7/src/bin/sh
Incidentally, have you ever tried execlineb? I use that sometimes too.
Also, back in the bad old days, 'lsof | grep snd' helped track down what the hell was hogging my sound card (setting up proper mixing has made that a distant memory, though).
something like,
lsof | grep <pid> | grep log