如何使用 bash 脚本在远程机器上运行命令?
Posted
技术标签:
【中文标题】如何使用 bash 脚本在远程机器上运行命令?【英文标题】:How to run commands on remote machine using bash script? 【发布时间】:2016-11-01 03:41:19 【问题描述】:我正在尝试在远程机器上运行以下命令,但没有执行任何操作,谁能指出以下脚本的问题?
仅供参考,settings.yml 和 fuscation_util.rb 文件存在于testuser
帐户中
脚本:
sshpass -p "PASSWORD" ssh -o StrictHostKeyChecking=no -T root@HOSTNAME <<EOF
su - testuser
NEWLINE=$'\n'
read -s -p "Enter Presto Password:$NEWLINE" VD_PASSWORD
KEY=`cat settings.yml |grep '^key:'|sed 's/^key: //'`
VALUE=`ruby fuscation_util.rb encrypt "$KEY" "$VD_PASSWORD"`
echo "$VALUE"
EOF
输出:
cat: settings.yml: No such file or directory
ruby: No such file or directory -- fuscation_util.rb (LoadError)
只有当我尝试将 poutput 分配给某个变量时,我才会遇到错误,使用下面的脚本我没有收到任何错误
脚本:
sshpass -p "PASSWORD" ssh -o StrictHostKeyChecking=no -T root@HOSTNAME <<EOF
su - testuser
NEWLINE=$'\n'
read -s -p "Enter Presto Password:$NEWLINE" VD_PASSWORD
cat settings.yml |grep '^key:'|sed 's/^key: //'
ruby fuscation_util.rb encrypt "testvalue" "testpassword"
EOF
输出:
WORKING FINE
【问题讨论】:
尝试将确切的路径添加到文件 w.r.troot
user。
@Shravan40 - 这是一个很好的建议 - 介意我将其作为第二个选项添加到我的答案中吗?
@Lix : 请补充。
我想指出一些你可以改变/改进的事情。 1. 我认为在 ssh 脚本中执行 read
和获取 VD_PASSWORD
没有任何意义。您可以从外部执行并将其传入。 2. 正如其他人所建议的那样,对 settings.yml 和 fuscation_util.rb 使用绝对路径
cat: /opt/settings.yml: 没有这样的文件或目录 ruby: 没有这样的文件或目录 -- /opt/fuscation_util.rb (LoadError) 使用绝对路径也会出现同样的错误
【参考方案1】:
我相信因为您是以 root 身份连接,所以您在连接时登陆的目录是 root 用户主目录。即使您更改了用户,您仍然会在同一个起始文件夹中(可能是/root
)。
如果您在执行命令之前明确cd
到所需位置,您将可以访问所需文件。
另一个选项 (suggested by Shravan40) 是指定要处理的文件的绝对路径。
还应该提到的是,允许通过 SSH 进行 root 访问被认为是一种安全风险。我建议尽可能避免这种情况。
【讨论】:
cat: /opt/settings.yml: 没有这样的文件或目录 ruby: 没有这样的文件或目录 -- /opt/fuscation_util.rb (LoadError) 使用绝对路径也会出现同样的错误 您说“文件存在于 testuser 帐户中”是位于 /opt 文件夹中的 testuser 帐户吗?您确定这是文件的正确路径吗? 是的,我们已授予 testuser 访问 opt 目录的权限,仅供参考,我们的服务器架构完全不同,我们所有的服务器仅供内部使用 我不是指权限 - 错误表明找不到文件。您确定所需的文件在 /opt 文件夹中吗? 文件存在,只有当我尝试将输出分配给变量时才会出现错误,如果我删除分配,那么一切正常【参考方案2】:一旦您的 ssh 以 root 身份连接到远程主机,它就会转到根目录。所以尝试更改目录或提供文件的绝对路径。
尽管远程运行命令存在安全风险。可能你可以在远程主机上放置一个脚本并传递参数,而不是在 ssh 中使用 echo。
更新:
只需在 ssh 之前进行所有赋值,并在调用 ruby 时使用键值作为表达式。
试试这个:
read -s -p "Enter Presto Password:$NEWLINE" VD_PASSWORD
sshpass -p "PASSWORD" ssh -o StrictHostKeyChecking=no -T root@HOSTNAME <<EOF
su - testuser
cat settings.yml |grep '^key:'|sed 's/^key: //'
ruby fuscation_util.rb encrypt `cat settings.yml|grep '^key:'|sed 's/^key: //'` $VD_PASSWORD
EOF
【讨论】:
cat: /opt/settings.yml: 没有这样的文件或目录 ruby: 没有这样的文件或目录 -- /opt/fuscation_util.rb (LoadError) 使用绝对路径也会出现同样的错误 "/opt/settings.yml: no such file" 因为该命令是在本地机器上执行的,而不是在远程服务器上。确认 cd 到不同的目录,如 /tmp 并查看 /opt/settings.yml 如何变为 /tmp/settings.yml。【参考方案3】:除了使用完整路径以及您需要将<<EOF
替换为<<'EOF'
或所有反引号将在它们发送到远程端之前在调用端进行处理。
【讨论】:
我已经试过了,当我用'EOF'替换时,变量赋值不起作用以上是关于如何使用 bash 脚本在远程机器上运行命令?的主要内容,如果未能解决你的问题,请参考以下文章