Rumbles
Rumbles

Reputation: 1393

Why can't I run things in /usr/local/bin when that is in the PATH via an ssh command when I can run them if I use the absolute path?

I have written a script template in salt, where I can configure in the command to run and it will connect to a number of servers in a list and find the version of the software installed on each one (for a nagios check). The check is configured to connect to 4 Linux agents and a single OSX agent.

I have a check for java, and I was just working on the one for maven.

I am getting some weird behaviour, which I don't understand, I'm hoping someone can explain this to me. Even though the /usr/local/bin shows as being in the path for the user I am connecting with, when I check I cannot run programs that live in /usr/local/bin:

Programs that live in /usr/bin work fine:

$ sudo su - backup -c "ssh -q -o StrictHostKeyChecking=no bamboomac 'java -version'"
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

$ sudo su - backup -c "ssh -q -o StrictHostKeyChecking=no bamboomac 'which java'"
/usr/bin/java

But when I try the same on something that lives in /usr/local/bin I get this:

$ sudo su - backup -c "ssh -q -o StrictHostKeyChecking=no bamboomac 'mvn -version'"
bash: mvn: command not found

$ sudo su - backup -c "ssh -q -o StrictHostKeyChecking=no bamboomac '/usr/local/bin/mvn -version'"
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T16:41:47+00:00)
Maven home: /usr/local/Cellar/maven/3.3.9/libexec
Java version: 1.8.0_121, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.11.6", arch: "x86_64", family: "mac"

$ sudo su - backup -c "ssh -q -o StrictHostKeyChecking=no bamboomac 'echo $PATH'"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Note if I specify the full path it works fine, and if I query path /usr/local/bin is there.

I tried exporting the path in the same command and I get this weirdness:

$ sudo su - backup -c "ssh -q -o StrictHostKeyChecking=no bamboomac 'export PATH="/usr/local/bin";mvn -version'"
/usr/local/Cellar/maven/3.3.9/libexec/bin/mvn: line 53: uname: command not found
/usr/local/Cellar/maven/3.3.9/libexec/bin/mvn: line 114: dirname: command not found
Error: Could not find or load main class org.codehaus.plexus.classworlds.launcher.Launcher

I don't want to use the full path, as on a linux machine the path is different. I wanted to use the short name so this check can be universal.

Can anyone suggest why this happens and a way to work around it?

Upvotes: 1

Views: 2292

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295687

If you want to pass arbitrary arguments:

#!/bin/bash

# default to running mvn -version; this is how we're getting arbitrary arguments through
(( $# )) || set -- -version

printf -v argv_q '%q ' "$@"
sudo su - backup -c 'ssh -q -o StrictHostKeyChecking=no bamboomac bash -s' <<EOF
PATH=/usr/local/bin:\$PATH
mvn $argv_q
EOF

Notes:

  • No export is needed: Updates to a preexisting environment variable all go to the environment automatically.
  • printf '%q' in bash escapes content in such a manner as to survive a single eval pass.
  • A quoted heredoc, as in <<'EOF', passes content through literally, without modification. An unquoted heredoc, as in <<EOF, performs expansions. If you want to be able to substitute in arbitrary contents, then you want those expansions.

Upvotes: 1

Related Questions