您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
编写一个lib库修复的php脚本(用于glibc升级失败后对ffmpeg依赖库的善后修复)
发布时间:2025-03-01 10:50:33编辑:雪饮阅读()
-
事件起因是需求上面要用到ffmpeg,在老版本系统中需要高版本glibc,结果就是无法yum或rpm升级,只能手动编译安装,编译安装失败后,系统几乎瘫痪。
强烈建议不要升级glibc,直接换一个高版本glibc的系统就行了。
之后只能找阿里云工程师修复,修复后还是缺少一些之前已经安装了的软件的lib库,阿里云工程师有先见之明,先给备份到了/usr/lib64.bak这个目录,但是千万不能批量照搬过来,里面还包含一些错误的lib库,只能按需来。
由于lib库有的软件可能依赖特别多,那么就不至于手动一个个去拷贝,特别像是ffmpeg这种(由于种种原因只能坚持用老系统,所以找了好久超级老的ffmpeg3终于安装上了)依赖就特别多,所以我手动针对这种情况编写了批处理脚本:
<?php
function listFiles($dir) {
// 检查目录是否存在
if (!is_dir($dir)) {
echo "指定目录不存在:$dir".PHP_EOL;
return;
}
// 初始化一个数组来存储文件路径
$files = [];
// 打开目录句柄
$dh = opendir($dir);
if ($dh) {
// 读取目录中的每个文件和子目录
while (($file = readdir($dh)) !== false) {
// 排除目录名为"."和".."的项
if ($file != "." && $file != "..") {
$filePath = $dir . '/' . $file;
// 检查是否为目录,如果是,则递归调用listFiles函数
if (is_dir($filePath)) {
$files = array_merge($files, listFiles($filePath));
} else {
// 如果是文件,则添加到数组中
$files[] = $filePath;
}
}
}
// 关闭目录句柄
closedir($dh);
}
if($files){
echo "正在目录".$dir."中遍历lib库".PHP_EOL;
foreach($files as $key=>&$val){
$val=str_replace("//","/",$val);
echo $val.PHP_EOL;
}
}
return $files;
}
function findLib($lib){
$lists=listFiles("/usr/lib64/");
if($lists){
foreach($lists as $key=>&$val){
$val=str_replace("//","/",$val);
$soName=basename($val);
if($soName==$lib){
if(file_exists($val)){
return $val;
}
}
}
}
return false;
}
function repair($command="ffmpeg -v 2>&1",$sourceDir="/usr/lib64.bak/",$targetDir="/usr/lib64/"){
while(true){
exec($command, $output, $return_var);
if($output){
foreach($output as $key=>$val){
/*
* lib库错误信息应如:
* ffmpeg: error while loading shared libraries: libv4l2.so.0: cannot open shared object file: No such file or directory
* */
$libErrorInfo=$val;
echo "遇到报错信息:".$libErrorInfo.",准备匹配提取缺少的lib库去解决lib库问题".PHP_EOL;
$pattern = '/ffmpeg: error while loading shared libraries: (lib.*): cannot open shared object file: No such file or directory/';
if (preg_match($pattern, $libErrorInfo, $matches)) {
//var_dump($matches);
echo "匹配到的内容是: ". $matches[1]. PHP_EOL;
$lib=$matches[1];
$findLibRes=findLib($lib);
if($findLibRes===false){
echo "lib库:".$lib."在路径".$sourceDir."及子路径中没有找到".PHP_EOL;
break;
}
//拷贝之前备份的正常lib库到正确路径
$source=$sourceDir.$lib;
$cpCommand="cp ".$source." ".$targetDir;
echo "已找到lib库正在执行拷贝命令:".$cpCommand.PHP_EOL;
exec($cpCommand);
}
else {
echo "未找到匹配项。应该不缺少lib库". PHP_EOL;
}
}
break;
}
else{
break;
}
}
}
$command="ffmpeg -v 2>&1";
$sourceDir="/usr/lib64.bak/";
$targetDir="/usr/lib64/";
repair($command="ffmpeg -v 2>&1",$sourceDir="/usr/lib64.bak/",$targetDir="/usr/lib64/");
这里的命令必然是要将错误输出和标准输出都到同一个通道,然后exec的output才能获取到。
我的原理就是正则匹配缺少lib库的报错信息,然后去原来备份目录拷贝到目标路径。
所以别人也可以参考使用这个脚本,根据自己的情况修改下即可。
最后补充一句,在命令行执行(如:php ffmpegRepair.php),不过这个懂得都懂。
关键字词:lib,修复,glibc,ffmpeg,升级,php,脚本,依赖