NiceLeeのBlog 用爱发电 bilibili~

备忘录 Serv00 php调用shell脚本

2024-10-06
nIceLee

阅读:


最初的起因是母鸡经常重启,但是呢,账号有没有权限设置开机自动运行的脚本。
注意到放到~/domains/{domain}/public_html路径下的php是可以直接使用的,遂有了这个想法。
在这里先要声明: 虽然这样也能解决问题,但是最佳方案是在Web Panel端建立Cron Job,运行时机为after reboot,执行你想要的脚本。
本文只讲思路,过程可能略省。

php报错:没有权限执行proc_open

2024/10/17 有修改

  • 在Web Panel里面启用exec、eval函数:
    • 登录管理面板
    • 点击WWW Websites
    • 点击Manage按钮,
    • 点击Details
    • 开启Allow PHP eval() function
    • 开启Allow PHP exec() function
    • 点击Save changes保存

下面这些就没有必要了
要绕过这一点,需要将public_html真实位置弄到其它目录,然后再进行链接。

mkdir ~/workspace/public_html
# 这里直接删除,如果有内容可以按需自行处理
rm -rf ~/domains/foo.bar/public_html
ln -fs ~/workspace/public_html ~/domains/foo.bar/public_html

php报错:没有权限执行目标程序

实测只能执行bin目录下已有命令,例如bash ls ssh curl这种,执行~/workspace/app这种不太行。

要绕过这一点,我能想到的解决方案是尝试使用ssh本地登录代传命令。

ssh无交互登录

可以使用sshpass,或者使用密钥登录。推荐后者。

// 生成密钥对
ssh-keygen -t rsa
// 将公钥纳入授权
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
// 尝试ssh命令
ssh -t -l {用户名} -P 22 127.0.0.1 "ls -l"

php模板


// https://{domain}/foobar.php?key=value
<?php
header('Content-Type: text/plain; charset=UTF-8');

if (!isset($_GET['key']) || $_GET['key'] != 'value') {
    http_response_code(403);
    die('Permission denied');
}

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open('ssh -t -l {usename} -P 22 127.0.0.1 "bash ~/workspace/app/start.sh" 2>&1', $descriptorspec, $pipes);

if (is_resource($process)) {
    while (($line = fgets($pipes[1])) !== FALSE) {
        // 输出实时获取的命令执行结果
        echo $line;
        ob_flush();
        flush();
    }

    fclose($pipes[0]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($process);
    
} else {
    echo "Failed to execute command.\n";
}

?>

内容
隐藏