【问题标题】:Inappropriate ioctl for device设备的 ioctl 不合适
【发布时间】:2018-08-24 03:23:34
【问题描述】:

我正在尝试通过 PHP 应用程序执行 SSH 命令。

通过 PHP 应用程序,我键入“./SSDownload.sh”。 通过我的终端 SSH,我输入“./SSDownload.sh”。

SSDownload.sh 包含:

cd /var/www/html/dev/media/mp3/$1
spotify-to-mp3 songs.txt

通过我的终端 SSH,我得到以下响应:

Resolving "fancy iggy azalea"
Searching "fancy iggy azalea" on Grooveshark
"Iggy Azalea - Fancy (feat. Charli XCX)" will be downloaded

Downloading tracks...
[1/1] Iggy Azalea - Fancy (feat. Charli  100% [==================================] Time: 00:00:01
Download complete

文件下载成功,并将文件放在正确的目录中。

我使用以下代码对 PHP 进行了同样的尝试:

include('Net/SSH2.php');
$ssh = new Net_SSH2('iphere');
if (!$ssh->login('root', 'password')) {
exit('Login Failed');
}

echo "1 : " . $ssh->exec('./SSDownload.sh ' . $_GET['player']) . "<br />";

输出:

Resolving "fancy iggy azalea" Searching "fancy iggy azalea" on Grooveshark "Iggy Azalea - Fancy (feat. Charli XCX)" will be downloaded Downloading tracks... [0;31;49mInappropriate ioctl for device[0m [0;32;49mDownload complete[0m

文件没有下载成功,没有把文件放到正确的目录下。

我想提醒您注意“Inappropriate ioctl for device”,不管它是什么意思。

为什么反应不同?我该如何解决它?

【问题讨论】:

  • 偷窃是不好的,mkay
  • @zerkms 用于 Spotify 应用程序:3
  • 这里怎么涉及ssh?
  • @Kenster 好吧,我想知道为什么在同一台机器上执行相同的脚本会产生两种不同的结果。涉及 SSH 是因为两个应用程序都使用 SSH 来执行脚本。谢谢。
  • PHP 应用程序正在使用 ssh?你能从 PHP 应用程序中添加相关的源代码吗?

标签: php bash ssh phpseclib


【解决方案1】:

“ioctl”是一种 POSIX 操作,用于向设备发送控制命令(“I/O 控制”)。 “不适当的 ioctl”错误意味着程序将 ioctl 发送到在某些方面不正确的设备。问题是这个 spotify 程序可能使用的 ioctl 取决于它的运行方式。

当您从命令行运行 spotify 程序时,它有一个 TTY。当您的 PHP 代码启动程序时,它没有 TTY。它可能出于某种原因将 ioctl 发送到其标准输出,期望标准输出是 tty。我的猜测是它使用 ioctl 来获取终端宽度,以便它可以显示该进度条图形。

有两种方法可以解决此问题。您可以查看此 spotify 程序的文档,以查看它是否具有禁用打印进度条的非交互模式或批处理模式或安静模式。这可能会避免执行失败的 ioctl。

另一个解决方法是让 PHP 为 ssh 会话请求一个 pty(伪 TTY)。我不是 PHP 编码员,但 this page 似乎描述了 Net_SSH2 API,它 lists a function to enable requesting a PTY 用于调用 exec()。

【讨论】:

  • 我正在测试它
  • 答案基本正确。我试图重现这个问题,也偶然发现了enablePTY()。当我使用它时,该命令只输出一个1.. 想知道为什么目前。
  • 向你致敬。有效。真的很感激,谢谢!解决方案: $ssh->enablePTY(); $ssh->exec('./SSDownload.sh ' . $_GET['player']); echo $ssh->read();
  • @Toby 您需要解决的一个导入问题:您需要使用escapeshellarg($_GET['player']) .. 否则可以使用player 变量从远程执行任意命令
  • @hek2mgl When I use it, the command simply outputs a 1 如果 spotify 正在检查终端宽度以格式化进度线,则可能是 PTY 正在获取一个不合理的默认终端宽度。在我链接到的页面上,有设置 PTY 宽度和高度的功能。他们可能会有所帮助。
【解决方案2】:

试试

echo "1 : " . $ssh->exec('/bin/bash -c '.escapeshellarg('./SSDownload.sh ' . escapeshellarg($_GET['player']))) . "<br />";

【讨论】:

    猜你喜欢
    • 2010-12-08
    • 2014-09-17
    • 2015-02-03
    • 2021-11-25
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2022-06-27
    • 2013-01-28
    相关资源
    最近更新 更多