1

My lsof command output is correct while the application I am tracking with lsof -a is running. As soon as I quit that application the same lsof -a call displays results for every process that has an ESTABLISHED connection.

lsof -lnPO -i -sTCP:ESTABLISHED -a -p "$(pgrep -d, qbittorrent)" +c0

Upon closing qbittorrent it then shows every connection that is "ESTABLISHED"

I want results for ESTABLISHED qbittorrent connections and when there are none, no connections.

I am displaying this output through GeekTool on the Desktop. It runs as a shell script.

nice -n 9 /Users/john/ShellScripts/GeekTool/qBT-Activity.sh

3
  • I'd assume this has to do with pgrep -d, qbittorrent returning nothing, and lsof interpreting -p "" as meaning "all processes". The thing I don't understand is why it doesn't show everything before you start qbittorrent the first time. Dec 9, 2022 at 0:30
  • @GordonDavisson I get all processes listed even without having run qbittorrent once. So either there are no ESTABLISHED connections the first time the OP runs the command (unlikely), or we miss part of the picutre.
    – nohillside
    Dec 9, 2022 at 9:48
  • @GordonDavisson @nohillside I apologize. I must be losing my marbles. After looking at it again, restarting the computer does nothing to change behavior. I don't know for sure what is different but I agree that -p "" seems to be interpreted as "all processes". It may be the difference between the proctools version of pgrep and the system installed version. I recently changed my $PATH to put the proctools version first because the native pgrep was having an issue with -d , flag adding a ',' as a terminator a while back.
    – John
    Dec 9, 2022 at 17:12

2 Answers 2

3

If pgrep doesn't find a match, it returns an empty string which apparently triggers lsof to return all established connections.

In Bash, try

lsof -lnPO -i -sTCP:ESTABLISHED -a \
    -p "$(p=$(pgrep -d, qbittorrent); echo ${p:-9999999999999999})" \
    +c0

instead (which substitutes an unlikely "pid" if no qbittorrent process is running).

4
  • Thanks @nohillside. I am not familiar with the notation :-. What is happening in that command substitution or parameter expansion? Max PID is 99998 on macOS... so definitely unlikely.
    – John
    Dec 9, 2022 at 16:27
  • @john if p is set and not empty, the value of p is used. Otherwise the value after :- . See man bash for details.
    – nohillside
    Dec 9, 2022 at 17:15
  • 1
    pgrep (at least in the versions I know of) exits with error status if it doesn't find any matches, so ... -p "$(pgrep -d, qbittorrent || echo 9999999999999999)" ... should also work. Dec 9, 2022 at 18:15
  • @GordonDavisson Ahhhh, right, absolutely!
    – nohillside
    Dec 9, 2022 at 18:34
0

@nohillside Thanks for your solution! I found a method by testing for exit status. I don't know which is more "efficient".

Now using /usr/bin/pgrep and not /usr/local/bin/pgrep

my_func() {
if /usr/bin/pgrep -q qbittorrent
then
  lsof -lnPO -a -i -sTCP:ESTABLISHED -a -p "$(/usr/bin/pgrep qbittorrent)" +c0
fi
}

The opposite (testing for 1 exit code)

my_func() {
if ! /usr/bin/pgrep -q qbittorrent
then
  return
else
  lsof -lnPO -a -i -sTCP:ESTABLISHED -a -p "$(/usr/bin/pgrep qbittorrent)" +c0
fi
}

-q flag suppresses stdout, but only in macOS installed pgrep and unfortunately not the proctools version of pgrep

1
  • This works as well, but there is a race condition if the BitTorrent process ends after the if and before the lsof (unlikely but possible). It also runs pgrep twice.
    – nohillside
    Dec 9, 2022 at 18:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .