【问题标题】:SSH command works in terminal, but fails with nodejs / ssh2SSH 命令在终端中工作,但在 nodejs / ssh2 中失败
【发布时间】:2021-01-06 03:13:55
【问题描述】:

在终端中,如果我使用 ssh 登录并运行类似 service something reload 的命令,它运行得很好,但是当我使用 ssh2 库(.exec 函数)在 nodejs 脚本中执行相同的命令时,它不会运行并且我收到一个错误“ash:找不到命令”。

用sudo service.. 试过,但结果是一样的。

有些命令确实有效,例如uptime 或ifconfig,但服务无效,我需要那个。我要连接的服务器是一个运行 open wrt 的路由器。


这是 nodejs 脚本:

const Client = require('ssh2').Client;
const conn = new Client();

conn.on('ready', async() => {

  conn.exec('service network reload', {
    env: {'PATH': '/usr/sbin:/usr/bin:/sbin:/bin'},
  }, (err, stream) => {
    if(err)
      return console.log(err);

    stream.on('close', () => console.log('ok'));
    stream.stderr.on('data', data => console.log(data.toString()));
  }); 

}).connect({
  host: ROUTER_HOST,
  port: 22,
  username: 'root',
  password: '1234'
});

which 的终端输出截图:

【问题讨论】:

  • 我想您的 nodejs/ssh2 设置使用的环境与您的登录终端不同。你能做printenv之类的事情并检查结果吗?有初始化文件吗?
  • 如果您可以通过 .exec() 传递一个 options 对象,那么将 opts.shell 设置为您选择的 shell 的完整路径名会发生什么?
  • ash: printenv: not found 如果我使用 ssh2 执行此命令 :(
  • Milag 似乎没有 ssh2 exec 的 shell 选项。有一个shell 方法,但我认为它启动了一个我不想要的交互式终端。我只需要执行一个命令并退出

标签: javascript node.js linux ssh openwrt


【解决方案1】:

您收到“找不到 bash 命令错误”。因为您的 PATH 不包括服务可执行文件的位置。

将来自 ssh2 的 echo $PATH; 的结果与您的终端进行比较。如果您的 ssh2 错过了一些路径,请更新您的环境。

【讨论】:

  • 这不是 bash,而是 ash。我尝试设置路径,但同样的事情发生了
  • 也从 ssh2 运行 echo $path 不起作用。它只是停止,我必须按 ctrl-c 强制退出
【解决方案2】:

您必须传递一个选项对象,其中包含键 env,其值本身就是键值对的对象。

exec('sudo service something reload', {env: {'PATH': '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:'}}, function (error, stdout, stderr) 
{
    console.log(stdout, stderr, error);
});

【讨论】:

  • 哦,你不在bash。不要复制/粘贴,而是尝试使用指针并根据您的特定环境进行调整,例如尝试安装 sudo...
  • 但如果我可以在 macos 终端 ssh 会话中执行操作,则应该安装它。问题可能出在 ssh2 节点库中吗?
  • 我不这么认为,我认为问题出在您的 PATH 上,这就是为什么看不到 sudo 的原因 .. 所以您可以启用的任何调试都有助于弄清楚什么是错了。
【解决方案3】:

如果您收到 command not found 错误,这仅表示您的命令(在本例中为 service)在环境的 $PATH 中找不到。

要么为连接正确设置环境,要么为命令使用绝对路径。

对于 systemd 服务,使用 /usr/sbin/service something reload 或 /bin/systemctl reload something 等。

您可以使用which 命令找到可执行文件的路径,例如which service 或which systemctl。

对于较旧的初始化脚本服务,请运行 /etc/init.d/something restart。

【讨论】:

  • 有趣。我在终端中运行了which command,它没有显示sudo 或service,但显示了ifconfig 的二进制路径。所以基本上它没有显示在终端而不是在 nodejs 中工作的命令,并显示在终端和 nodejs 中工作的命令的路径
  • 尝试在终端运行which service :-)
  • 我做了,但什么也没显示。我认为这些命令在 open wrt 中没有二进制文件?但我不明白为什么它们在终端中工作,而不是在 ssh2 会话中
  • 我对 OpenWRT 没有太多经验,但这至少听起来很奇怪......它们可能只是其他可执行文件的别名,比如 systemctl。试试which systemctl
  • 同样的事情,什么也不显示。我想我别无选择,只能使用 ssh2 启动终端会话并以某种方式自动输入命令:(
猜你喜欢
  • 2013-12-28
  • 1970-01-01
  • 1970-01-01
  • 2017-09-03
  • 2014-09-17
  • 2016-09-09
  • 2020-07-28
  • 2022-08-12
  • 1970-01-01
相关资源
最近更新 更多