为什么我不能通过 ssh 命令 运行 /usr/local/bin 中的东西,而如果我使用绝对路径我可以 运行 它们在 PATH 中?

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?

我用salt写了一个脚本模板,我可以在命令中配置到运行,它会连接到列表中的多个服务器,并找到每个服务器上安装的软件版本(用于 nagios 检查)。检查配置为连接到 4 个 Linux 代理和一个 OSX 代理。

我检查了 java,我只是在为 maven 工作。

我遇到了一些我不明白的奇怪行为,我希望有人能向我解释一下。尽管 /usr/local/bin 显示在我正在连接的用户的路径中,但当我检查时,我无法 运行 位于 /usr/local/bin:

中的程序

/usr/bin 中的程序运行良好:

$ 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

但是当我对生活在 /usr/local/bin 中的东西进行同样的尝试时,我得到了这个:

$ 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

请注意,如果我指定完整路径,它就可以正常工作,如果我查询路径 /usr/local/bin 就在那里。

我尝试在同一个命令中导出路径,但我发现了这个奇怪的地方:

$ 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

我不想使用完整路径,因为在 linux 机器上路径不同。我想使用短名称以便此检查可以通用。

任何人都可以建议为什么会发生这种情况以及解决它的方法吗?

如果你想传递任意参数:

#!/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

备注:

  • 不需要 export:对预先存在的环境变量的更新都会自动进入环境。
  • printf '%q' in bash 转义内容以在单次 eval 传递中存活。
  • 引用的 heredoc,如在 <<'EOF' 中,按字面意思传递内容,不加修改。未引用的 heredoc,如 <<EOF 中,执​​行扩展。如果您希望能够替换任意内容,那么您需要这些扩展。