最近公司有一个需求,需要调取同事开发的shell脚本,传入shell所需的值并唤起shell,获得shell执行的结果展示。
shell在测试服务器的宿主机上,PHP是放到docker容器内的,这就让人很无奈了,秉着办法总比困难多的思想,整理出了几个思路。
1:在宿主机上部署PHP环境,这样PHP和shell不存在跨容器的情况,但是这样就破坏掉先有的docker结构,不推荐;
2:如果mysql装在宿主机上的话,用mysql做触发器,把命令行当成一个字段存入,插入一条记录的时候,直接用触发器执行这条命令行,这种方法局限性很大,还得是mysql在宿主机上,不推荐;
3:docker容器内做ssh登陆操作,直接登陆到宿主机,这样可以直接在宿主机上调取shell,暂时算最合适的处理方法。
过程:首先要在docker内安装libssh2和ssh2 PHP扩展
安装libssh2时报了一个错,少了几个依赖库,忘记截图了,大概apt-get install zlib-devel openssl-devel libssh2-devel php-devel,
提示少哪个自行安装一下:
cd tmp
wget https://www.libssh2.org/download/libssh2-1.8.0.tar.gz
tar zxvf libssh2-1.8.0.tar.gz
cd libssh2-1.8.0
./configure
make && make install
libssh2安装成功之后接下来是ssh2,百度基本都是复制说一定要下载1.0版本,但是我试了一下,报错!现在必须要求是最新版本:
cd tmp
wget https://pecl.php.net/get/ssh2-1.2.tgz
tar zxvf ssh2-1.2.tgz
mv /tmp/ssh2-1.2.tgz /usr/src/php/ext/ssh2
docker-php-ext-install ssh2
ssh2安装完成,重启docker容器 docker restart 容器名
打开phpinfo()可以看到ssh2安装成功
接下来是PHP使用SSH2调用宿主机shell
$host='127.0.0.1'; //服务器的ip
$user='root'; //用户名
$passwd='root'; //密码
$shell_command = 'ls';
$connection = ssh2_connect($host, 22); // 链接远程服务器
$auth_methods = ssh2_auth_none($connection, $user); // 获取验证方式
if (in_array('password', $auth_methods )){ // 通过password方式登录远程服务器
if (ssh2_auth_password($connection, $user, $passwd)){
$stream = ssh2_exec($connection,$shell_command); // 执行shell
stream_set_blocking($stream, true); // 获取执行pwd后的内容
echo stream_get_contents($stream);
}
}
$shell_command 这里还有一个坑,简单一点运行时间较短的shell或者.sh是可以正常唤起执行输出没问题,复杂一点并且执行时间长的没有返回结果的shell这里是唤不起来的,需要在$shell_command后跟一个输出文件,例:nohup sh /public/shell/xx.sh -configfile /public/11.txt -num 2 -con 2 -h a -ce b -t c -l d -k e -i f >/public/xx.log &,这样的话stream_set_blocking($stream, true);echo stream_get_contents($stream);这两行代码是没有意义的,注释即可!