1

I know that you can find the working directory of a process a few different ways, but is there any way to do the reverse? I have some server applications written in node that are unfortunately tricky to tell apart as processes (they all show up as node server.js in a ps output) and I would like to have a simple way to determine whether or not a specific server was running.

In other words the question I need answered is; given directory /x/y/z, is there a node server.js process running with the working directory /x/y/z?

Currently my best attempt is to do ps -ef | grep "[n]ode server.js", cutting the PID and looping over them, checking pwdx for each PID. It works, but it's cumbersome and I was wondering if there was a better way.

6 Answers 6

1

Since pwdx accepts PIDS then you can use:

$ pwdx $(ps -C "node server.js" --format pid --no-headers) 2781: /home/user 4405: /home/user/src.git/ 

And possibly define a function in your .zshrc or .bashrc:

function select_by_dir() { if (( $# == 0))l then pwdx $(ps -C "node server.js" --format pid --no-headers) else pwdx $(ps -C "node server.js" --format pid --no-headers) | grep $1 fi } 

}

4
  • I'm not sure which part of your ps call it specifically objects to, but it fails with error: unsupported option (BSD syntax). I perhaps should have specified that I'm running Ubuntu 15.10. Edit: Actually, it might just be that node server.js is missing quotes. Commented Mar 29, 2016 at 7:54
  • It hadn't really occurred to me that pwdx accepted any number of PIDs. That's very helpful. Thanks. Commented Mar 29, 2016 at 7:57
  • Instead of using ps you can use pgrep. Possibly there will be no errors Commented Mar 29, 2016 at 8:02
  • pgrep doesn't work for this at all. The only way to get the PIDs with that seems to be pgrep node, but that has too many false positives. Commented Mar 29, 2016 at 8:05
1

how about

pwdx `pgrep "server.js"` 
1

I'd just search /proc.

This will list all your pids for which you know the cwd and show the cwd next to it:

(cd /proc/; for p in [0-9]*; do cwd="$(readlink "$p/cwd")" || continue; echo "$p $cwd"; done) 

You can grep that or insert your matcher right into the loop:

(cd /proc/; for p in [0-9]*; do cwd="$(readlink "$p/cwd")" || continue; [ "$cwd" != "$THE_CWD_IM_LOOKING_FOR" ] || { echo "$p"; break; } done) 
0

You may try this, if you "node" is the only process

pwdx `pidof node` 
0
0

Based on the answer from @skwllsp I've come up with the following bash function that solves the issue:

function is-server-running { local path=$(realpath "${1-.}") pwdx $(ps -C "node server.js" --format pid --no-headers) | grep --silent "$path" } 

Thanks for the help everyone!

0

The commands fuser and lsof both list processes that have a file open. In this context, having a file open includes a process's current directory.

With fuser, you only get process IDs, so you need to call ps to get the command name.

pids=$(fuser -s /x/y/z 2>/dev/null | tr ' ' ',') pids=${pids#,} node_pids=$(ps -p "$pids" -o pid=,args= | awk '$2 == "node" && $3 == "server.js" {print $1}') kill $node_pids 

With lsof, you can specify that you only want processes with that current directory (as opposed to e.g. currently listing the directory contents). You can get the command name with the c output specified, but not the arguments.

pids=$(lsof -F p -a -d cwd . | sed '1s/^p//; s/p/,/' | tr -d \\n) 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.