Search code examples
bashsubshellcommand-substitution

echo $(command) gets a different result with the output of the command


The Bash command I used:

  1. $ ssh [email protected] ps -aux|grep -v \"grep\"|grep "/srv/adih/server/app.js"|awk '{print $2}'

    6373
    
  2. $ ssh [email protected] echo $(ps -aux|grep -v \"grep\"|grep "/srv/adih/server/app.js"|awk '{print $2}')

    8630
    

The first result is the correct one and the second one will change echo time I execute it. But I don't know why they are different.


What am I doing?

My workstation has very limited resources, so I use a remote machine to run my Node.js application. I run it using ssh [email protected] "cd /application && grunt serve" in debug mode. When I command Ctrl + C, the grunt task is stopped, but the application is is still running in debug mode. I just want to kill it, and I need to get the PID first.


Solution

  • The command substitution is executed by your local shell before ssh runs.

    If your local system's name is here and the remote is there,

    ssh there uname -n
    

    will print there whereas

    ssh there echo $(uname -n)  # should have proper quoting, too
    

    will run uname -n locally and then send the expanded command line echo here to there to be executed.

    As an additional aside, echo $(command) is a useless use of echo unless you specifically require the shell to perform wildcard expansion and whitespace tokenization on the output of command before printing it.

    Also, grep x | awk { y } is a useless use of grep; it can and probably should be refactored to awk '/x/ { y }' -- but of course, here you are reinventing pidof so better just use that.

     ssh [email protected] pidof /srv/adih/server/app.js
    

    If you want to capture the printed PID locally, the syntax for that is

    pid=$(ssh [email protected] pidof /srv/adih/server/app.js)
    

    Of course, if you only need to kill it, that's

    ssh [email protected] pkill /srv/adih/server/app.js