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
  • 713
  • 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