0

I found this command line is not working

ssh i01n10 "/usr/sbin/lsof -p $(pgrep -nf a.out)"

it shows the error

lsof: no process ID specified

However

ssh i01n10 "$(pgrep -nf a.out)"

correctly gives the PID

Why lsof is not seeing the PID?

user15964
  • 703
  • 2
  • 13
  • 27
  • The pgrep is being substituted before ssh or lsof gets ahold of it. Are you sure that the 2nd ssh is working? Are you ssh'ing from i01n10 to itself? – Jeff Schaller Apr 20 '16 at 02:37
  • @JeffSchaller Hi, JeffSchaller. I am ssh from other node. If "pgrep is being substituted before ssh or lsof gets ahold of it", what should I do – user15964 Apr 20 '16 at 02:59

1 Answers1

1

The lsof command can't see your PID because of shell expansion. That means $(pgrep -nf a.out) will be executed on your local server, not remote.

To avoid this expansion, use single quote instead of double quote.

Simple example:

$ foo=local
$ ssh debian8 "foo=remote; echo $foo"
local
$ ssh debian8 'foo=remote; echo $foo'
remote

You might have problem with your pgrep command. This is my simple test using -of instead of -nf flags (Use -af flag to see full command):

// on remote server
# sleep 200 &
[1] 27228
# exit
// on local host 
$ ssh debian8 'echo $(pgrep -nf sleep)'
27244 <-- not expected pid
$ ssh debian8 'echo $(pgrep -of sleep)'
27228 <-- this one

This $() actually launches a subshell, pgrep doesn't report itself as a match but it does report its parent shell. Hence, using -n option will not give you actual pid but the pid of pgrep itself.

cuongnv23
  • 184
  • 5
  • Hi, cuongnv. I tried your method. `ssh i01n10 '/usr/sbin/lsof -p $(pgrep -nf a.out)'`, however, it gives me nothing – user15964 Apr 20 '16 at 04:24
  • What is that `a.out`? process name, file name, argument of command used to create the process,...? Try `set -x /usr/sbin/lsof -p $(pgrep -nf a.out)` to see what happened. Also, try `$(pgrep -of a.out)` – cuongnv23 Apr 20 '16 at 04:29
  • `a.out` is the exectuable. I just tried `ssh i01n10 'pgrep -nf a.out | xargs /usr/sbin/lsof -p'`, though it gives output now, but the results is wrong. It should give the path where the running `a.out` is located. – user15964 Apr 20 '16 at 04:35
  • actually, if I `grep txt`, it gives `/bin/bash`, while it should be the path to `a.out` – user15964 Apr 20 '16 at 04:37
  • how was that `a.out` executed? can you give the actual output of `ps aux | grep a.out`? – cuongnv23 Apr 20 '16 at 05:04
  • The output is like this http://s000.tinyupload.com/?file_id=81160837964911972942 – user15964 Apr 20 '16 at 05:51
  • I've updated my answer. I don't know why you use `-n` flag but it would return `pgrep` itself. Remove it to see what's difference. – cuongnv23 Apr 20 '16 at 07:12
  • Hi, cuongnv. I probably can't agree with you. The `-n` option just gives the newest generated process, but as I tested, this doesn't include pgrep itself, you can see from `pgrep -lf sleep`. The reason you got different PID maybe because there are many sleep command running that you don't know. – user15964 Apr 20 '16 at 10:47
  • `-of` really works. Since my `a.out` is an MPI executable. `-of` found the PID of the oldest `a.out` command, that is `mpiexec.hydra -n 6 ./a.out`, and the sshed `lsof` could resolve this PID properly. Though I still don't know why it can't resolve the MPI process correctly. – user15964 Apr 20 '16 at 11:28
  • the `pgrep -lf sleep` will not match itself if you run it directly on server. But in your situation, on ssh connection your `$(pgrep -nf a.out)` is equivalent to `bash -c "pgrep -nf a.out"` on remote server. – cuongnv23 Apr 20 '16 at 12:54