php模仿终端的简单操作
效果图:
blade模版:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Terminal Interaction</title>
<style>
body {
font-family: 'Courier New', Courier, monospace;
background-color: #1E1E1E; /* Darker Grey */
color: #CCCCCC; /* Light Grey */
padding: 20px;
}
.container {
display: flex;
align-items: flex-start;
}
.terminal {
border: 2px solid #555;
border-radius: 5px;
padding: 10px;
background-color: #111; /* Dark Grey */
width: 52%;
height: 300px;
overflow: auto;
margin-right: 20px;
}
.terminal p {
margin: 0;
padding: 0;
transition: background-color 0.3s ease; /* 添加过渡效果 */
}
.terminal p:hover {
background-color: #4CAF50; /* 鼠标悬停时的高亮颜色 - 绿色 */
color: white; /* 文本颜色 - 白色 */
cursor: pointer; /* 设置鼠标样式为手型 */
}
.memo {
border: 2px solid #555;
border-radius: 5px;
padding: 10px;
background-color: #111; /* Dark Grey */
width: 48%;
height: 300px;
overflow: auto;
}
.memo p {
margin: 0;
padding: 0;
transition: background-color 0.3s ease; /* 添加过渡效果 */
}
.memo p:hover {
background-color: #4CAF50; /* 鼠标悬停时的高亮颜色 - 绿色 */
color: white; /* 文本颜色 - 白色 */
cursor: pointer; /* 设置鼠标样式为手型 */
}
input[type="text"], input[type="password"], textarea {
height: 30px;
border: 1px solid #555; /* Dark Grey */
border-radius: 3px;
padding: 5px;
margin-right: 10px;
background-color: #333; /* Grey */
color: #CCCCCC; /* Light Grey */
font-family: 'Courier New', Courier, monospace;
flex: 1; /* 设置所有文本框的宽度比例相等 */
}
input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
outline: none;
border-color: #4CAF50; /* Green */
}
input[type="text"]::placeholder, input[type="password"]::placeholder, textarea::placeholder {
color: #888; /* Grey */
}
button {
background-color: #4CAF50; /* Green */
color: white;
border: none;
border-radius: 3px;
padding: 10px 20px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #45a049; /* Darker Green */
}
</style>
</head>
<body>
<div class="container">
<div class="terminal" id="terminal">
<p>$ Welcome to Terminal by ZhouJiawei for AutoTest;</p>
</div>
<div class="memo" id="memo">
<p>备忘录[点击可直接复制]</p>
<br>
<p>1.检查算法授权</p>
<p>cd /home/nle/app/aibox/lic/bin && ./licCheck</p>
<p>2.算法授权</p>
<p>cd /home/nle/app/aibox/lic/bin && ./licGetFormCloud -u zjw_test -p GB#16@*0</p>
<p>3.格式化磁盘</p>
<p>mkfs.ext4 /dev/sda</p>
<p>4.格式化TF卡</p>
<p>mkfs.ext4 /dev/mmcblk0p1</p>
<p>5.查看hosts文件</p>
<p>cat /etc/hosts</p>
<p>6.查看指定进程 如ffmpeg</p>
<p>ps -ef | grep ffmpeg</p>
<p>7.查看内存资源</p>
<p>free</p>
<p>8.上网认证</p>
<p>curl -X POST "https://int.newland.com.cn/pts/portalLogin/loginPw?password=自己修改密码&loginid=zhoujiaw" -H "accept: application/json;charset=UTF-8"</p>
</div>
</div>
<br>
<input type="text" id="serverIP" placeholder="服务器IP" value="192.168.2.203" oninput="clearTerminal()">
<input type="text" id="serverPort" placeholder="服务器端口" value="22124" oninput="clearTerminal()">
<input type="text" id="loginUsername" placeholder="登录用户名" value="root" oninput="clearTerminal()">
<input type="password" id="loginPassword" placeholder="密码 留空使用默认id_rsa密钥" oninput="clearTerminal()">
<br>
<textarea id="input" style="width: calc(70% - 300px); height: 100px; margin-top: 10px;" placeholder="请输入您的简单命令,多条命令用&&拼接,无法执行需要交互的命令" onkeydown="handleKeyPress(event)"></textarea>
<script>
var terminal = document.getElementById('terminal');
var serverIPInput = document.getElementById('serverIP');
var serverPortInput = document.getElementById('serverPort');
var loginUsernameInput = document.getElementById('loginUsername');
var loginPasswordInput = document.getElementById('loginPassword');
var input = document.getElementById('input');
function clearTerminal() {
terminal.innerHTML = ''; // 清空终端内容
writeToTerminal('$ Welcome to Terminal by ZhouJiawei for AutoTest;');
}
// 处理用户输入
function handleKeyPress(event) {
if (event.keyCode === 13) { // 如果按下回车键
event.preventDefault();
sendCommand(); // 发送命令
}
}
// 处理用户输入
function sendCommand() {
var command = input.value.trim(); // 获取用户输入的命令并去除首尾空格
writeToTerminal('$root ' + command); // 将用户输入的命令显示在终端中
// 发送命令和参数到 API
fetch('/api/general/terminal', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
command: command,
ip: serverIPInput.value.trim(),
port: serverPortInput.value.trim(),
user: loginUsernameInput.value.trim(),
password: loginPasswordInput.value.trim()
})
})
.then(response => response.json())
.then(data => {
writeToTerminal(data.message); // 将API返回的消息显示在终端中
})
.catch(error => {
writeToTerminal('Error: ' + error.message); // 处理错误
});
input.value = ''; // 清空输入框
}
function writeToTerminal(message) {
var lines = message.split('\n'); // 将消息按换行符分割成多行
lines.forEach(function(line) {
terminal.innerHTML += '<p>' + line + '</p>'; // 为每行消息添加 <p> 标签
});
terminal.scrollTop = terminal.scrollHeight;
}
// 复制备忘录内容
document.getElementById('memo').addEventListener('click', function(event) {
var target = event.target; // 获取点击的元素
if (target.tagName === 'P') { // 如果点击的是<p>标签
var text = target.innerText; // 获取<p>标签内的文本内容
// 创建一个文本域元素
var textArea = document.createElement("textarea");
// 设置文本域的值为要复制的文本内容
textArea.value = text;
// 将文本域添加到DOM中
document.body.appendChild(textArea);
// 选中文本域中的内容
textArea.select();
// 执行复制命令
document.execCommand('copy');
// 从DOM中移除文本域元素
document.body.removeChild(textArea);
}
});
</script>
</body>
</html>
public function terminal(Request $request)
{
$command=$request->input('command');
$ip=$request->input('ip');
$port=$request->input('port');
$user=$request->input('user');
$password=$request->input('password');
if($password){
$rsa = $password;
}else{
$key = Storage::get('id_rsa');
$rsa = PublicKeyLoader::load($key);
}
//连接的服务器ip 输入方式 密钥登录或者密码登录 如果是密钥直接读取 不用传 如果是密码就让用户输入
try {
$ssh = new SSH2($ip,$port);
if (!$ssh->login($user, $rsa)) {
return [
'message'=>"设备离线或者异常,无法发送消息!",
'code' => "-3",
];
}
$output=$ssh->exec($command);
$output = iconv('UTF-8', 'UTF-8//IGNORE', $output);
$ssh->disconnect();
return [
'message'=>$output,
'code' => "1",
];
} catch (Exception $e) {
return [
'message' => $e->getMessage(),
'code' => "-2",
];
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接