• linux Web控制台 2018-04-18 17:10:42
    前段时间做一个hadoop+Spark的性能监控页面时,...大概像这个样子的:这样就可以在网页上直接访问linux服务器了,初衷是用来远程关闭正在运行的spark任务的,做发现出来之后一般的linux命令都能执行。首先讲一下后台...

    前段时间做一个hadoop+Spark的性能监控页面时,需要一个web控制台远程登陆到master节点上去,后来发现这方面资料太少,于是自己参照着零散的东西修修改改,终于做出了一个简单的web shell,记录一下以免时间长了忘记。大概像这个样子的:


    这样就可以在网页上直接访问linux服务器了,初衷是用来远程关闭正在运行的spark任务的,做发现出来之后一般的linux命令都能执行。

    首先讲一下后台实现:

    1.建立ssh连接,并定义一些流用于收发命令。

    2.其次定义是一个接收命令和返回结果的方法,因为linux每次返回一行,所以我这里存入List<String>返回给前台处理。

    代码都如下:
    package com.java.utils;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.nio.charset.StandardCharsets;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    import ch.ethz.ssh2.Connection;
    import ch.ethz.ssh2.Session;
    import ch.ethz.ssh2.StreamGobbler;
    
    
    public class SSHLinux
    {
    	private String hostname = "11.11.11.15";
    	private int port = 22;
    	private String username = "root";
    	private String password = "123456";
    	
    	private  Connection conn;
    	private  Session sess;
    	private  BufferedReader stdout;
    	private BufferedReader stderr;
    	private PrintWriter pw;
    	
    	public SSHLinux()
    	{
    		//使用默认值		
    		long t1 = System.currentTimeMillis();
    		initSession();
    		long t2 = System.currentTimeMillis();
    		System.out.println("远程登陆linux,连接耗时:"+(t2-t1)/1000.0+"s");
    	}
    	
    	public SSHLinux(String hostname, int port, String username, String password) 
    	{		
    		this.hostname = hostname;
    		this.port = port;
    		this.username = username;
    		this.password = password;
    	
    		long t1 = System.currentTimeMillis();
    		initSession();
    		long t2 = System.currentTimeMillis();
    		System.out.println("远程登陆linux,连接耗时:"+(t2-t1)/1000.0+"s");
    	}
    	
    	//初始化连接并建立虚拟终端
    	public void initSession()
    	{
    		try
    		{			
    			conn = new Connection(hostname,port);
    			conn.connect();
    			boolean isAuthenticated = conn.authenticateWithPassword(username, password);
    			if (isAuthenticated == false)
    				throw new IOException("Authentication failed.");
    			
    			sess = conn.openSession();
    			sess.requestDumbPTY();//建立虚拟终端
    			sess.startShell();//打开一个Shell	
    			
    			stdout = new BufferedReader(new InputStreamReader(new StreamGobbler(sess.getStdout()), StandardCharsets.UTF_8));
    			stderr = new BufferedReader(new InputStreamReader(new StreamGobbler(sess.getStderr()), StandardCharsets.UTF_8));
    			pw = new PrintWriter(sess.getStdin(),true);// 准备输入命令
    			
    		}
    		catch (IOException e)
    		{
    			System.out.println("------建立ssh linux连接错误------");
    		}
    	}
    	
    	
    	public void close()
    	{
    		try
    		{
    			stdout.close();
    			stderr.close();
    			pw.close();
    			sess.close();
    			conn.close();
    		}
    		catch (Exception e) 
    		{
    			System.out.println("------关闭ssh连接错误------");
    		}
    	
    	}
    
    	public List<String> execute(String strcmd)
    	{			
    		System.out.println("在execute()中接收到命令:"+ strcmd );
    		List<String> rstList = new ArrayList<String>();
    		try
    		{		
    			if(strcmd.equals("exit"))
    			{
    				pw.println(strcmd);// 输入待执行命令	
    				close();
    				rstList.add("用户退出,关闭连接!!!");
    				return rstList;
    			}
    			
    			pw.println(strcmd);// 输入待执行命令					
    			
    			while (true)
    			{
    				String line = stdout.readLine();
    				if (line == null || line.trim().endsWith("#"))
    					break;
    				
    				System.out.println(line);
    				rstList.add(line);
    			}
    						
    		}
    		catch (IOException e)
    		{
    			System.out.println("------连接已经关闭或命令出错------");
    		}		
    			
    		return rstList;		
    	}
    
    	
    	public static void main(String[] args)
    	{
    		SSHLinux ssh = new SSHLinux("192.168.0.160",22,"root","123456");
    		List<String> list = ssh.execute("pwd");
    		System.out.println("list----: "+list);
    		//ssh.execute("exit");
    	}
    }


    3.页面后台调用前面初始化方法和执行命令的方法,这个方法叫getLinux(),主要是和前台页面交互。我在这个方法命名为linux,@RequestMapping("/linux"),前台就可以通过linux.do识别了。

    首先创建弹出框并初始化:

            /*
    	 * 创建按钮弹出框
    	 */
    	@RequestMapping("/addWindow")
    	public ModelAndView goNewAddServer(HttpServletRequest req)
    	{ 
    		//ssh连接linux---------从xml配置文件中读取参数
    		ApplicationContext ct = new ClassPathXmlApplicationContext("applicationContext.xml");
    		Permission per = (Permission) ct.getBean("linux");		
    		String hostname = per.getIp();
    		int port  = per.getPort();
    		String username = per.getUsername();
    		String password = per.getPassword();
    		System.out.println("ssh连接linux---------Permission="+per.toString());
    		
    		try {
    			ssh = new SSHLinux(hostname,port,username,password);
                            //或者将账号写死
    			//ssh = new SSHLinux("192.168.1.12",22,"root","123456");
    		} catch (Exception e) {			
    			e.printStackTrace();
    		}		
    		return new ModelAndView("/admin/cloudcompute/box");///对应web console页面
    	}
    其次执行命令,主要是和前台页面交互
            /*
    	 * 在linux web shell中执行命令
    	 */
    	@RequestMapping("/linux")
    	@ResponseBody
    	private void getLinux(HttpServletRequest request, HttpServletResponse response)throws Exception{
    		System.out.println("\n-----------------Linux Shell-----------------\n");		
    		String cmd = request.getParameter("code");
    		System.out.println("执行命令: "+cmd);
    		
    		if(ssh!=null)
    		{
    			List<String> list = new ArrayList<String>();
    			if(cmd.length()==0)
    			{
    				System.out.println("输入为空");
    				//list.add("输入为空");
    			}
    			else if(cmd!="" || cmd.length()!=0 || cmd!=null)
    			{
    				list = ssh.execute(cmd);	
    			}
    			
    			System.out.println("返回结果list----: "+list);
    			
    			String result = ""; //{'data:','
    			for(String str : list)
    			{
    				result += str.trim()+"<br/>";
    			}
    			//result +="'}";				
    			ResponseUtil.write(response, result);
    			//JsonBinder buildNormalBinder = JsonBinder.buildNormalBinder();
    			//return buildNormalBinder.toJson(result);
    		}
    		else
    		{
    			System.out.println("没有连接,不执行命令");
    			//return "";
    		}
    						
    	}//


    4.接下来看页面,页面很简单:主要是定义<ul>列表来接收命令,因为发送的命令占一行,回来的结果为一行或多行,所以<ul>列表很合适。

    <!-- 按钮触发模态框 -->
    <span class="annnys">
    	<a id="linuxWindow" class="pve-tabletack active-tabletack" href="javascript:establishDialog()" style="cursor:pointer;">控制台</a>											
    </span>
    <!-- 模态框(Modal) -->
    <div class="modal fade" id="myModal"
    	 tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    	<div class="modal-dialog"  style="width:703px;height:410px;">
    		<div class="modal-content">
    			<div class="modal-header">
    				<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
    				<p class="modal-title" id="myModalLabel">Linux 控制台</p>
    			</div>
    			<div class="modal-body" style="padding:0px;">
    				<!-- <iframe id="box" src="box.jsp" style="width:600px;height:400px;"></iframe> -->
    				
    				<div class="wingb" id="msg">
    					<ul class="myul">
    					<li>----------------------命令Demo----------------------------</li>
    					<li>关闭进程方式1:</li>	
    					<li>ps -aux | grep test.jar		//根据提交的jar包名字来查找进程,再kill -9 [pid]杀掉进程</li>
    					<li>关闭进程方式2:</li>	
    					<li>ps -aux | grep test.jar | kill -9 `awk '{print $2}'`	//查找进程id并立即杀掉</li>
    					<li>关闭进程方式3:</li>
    					<li>kill -9 $(cat my.pid)	//前提:提交任务时获取进程号: spark-submit --class demo.WordCount test.jar & echo $!>my.pid</li>
    					<li>----------------------开始操作----------------------------</li>
    					</ul>								
    					<!-- <div class="incmd"  contentEditable="true"  id='in'>$</div> -->
    					<input class="incmd" type="text" value="$" id='in'>
    				</div>
    				
    			</div><!-- modal-body -->
    		</div><!-- /.modal-content -->
    	</div><!-- /.modal-dialog -->
    </div><!-- /.modal -->
    <script>				
    $("#in").keyup(function(event) {					
    	if (event.keyCode == 13) {	//回车			
    		$.ajax({
    			async: false,
    			type : "POST",
    			url : "${pageContext.request.contextPath}/admin/cloudcompute/linux.do",
    			data : "code=" + $("#in").val().substring(1),
    			success : function(data) {
    				$("ul").append("<li>" + $("#in").val() + "</li>");  //将输入的输出到界面
    				$("ul").append("<li>" + data + "</li>"); //获取返回值并输出
    				$("#in").val("$"); //清空输入框
    				$("#msg").scrollTop($("#msg").scrollTop() + 9999);//滚动条拉到最下面,显示出输入框
    			}
    		});
    	}
    	else  if(event.ctrlKey && event.which == 81){ //ctrl+Q 中断
    		alert("ctrl+Q 中断");
    		 CloseWebPage();
    	}
    });
    
    $("#in")[0].focus();
    
    function CloseWebPage() {
    	if (navigator.userAgent.indexOf("MSIE") > 0) {
    		if (navigator.userAgent.indexOf("MSIE 6.0") > 0) {
    			window.opener = null;
    			window.close();
    		} else {
    			window.open('', '_top');
    			window.top.close();
    		}
    	} else if (navigator.userAgent.indexOf("Firefox") > 0) {
    		window.location.href = 'about:blank ';
    	} else {
    		window.opener = null;
    		window.open('', '_self', '');
    		window.close();
    	}
    }
    
    //创建按钮 弹出框
    function establishDialog(){
    	xajax.iframeLAYER('${pageContext.request.contextPath}/admin/cloudcompute/addWindow.do',
    			"linux控制台", 
    			'620px', 
    			'430px',
    			function(){	
    	});
    		
    }
    
    </script>

    这是原来的页面中增加的一个模态框,通过按钮触发。当然也可以新建一个页面专门来做控制台,代码都一样,如图:

    <%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>命令行窗口</title>
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/public-js/jquery-1.8.0.min.js"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath}/static/layer/layer.js"></script>
    
    <style type="text/css">
    body{
    	background-color: #424242;  /*背景颜色*/
    	font-size:14px;
    	font: "微软雅黑";
    }
    
    
    .incmd {
    	background-color: #9FB6CD; /*输入行颜色*/
    	border: 0;
    	color: #FFFFFF; /*输入字体颜色*/
    	outline: none;
    	font-size:14px; 
    	width: 99%;
    }
    
    .panel {/*暂时未用*/
    	background-color: #424242;  /*背景颜色*/
    	border-top: #424242 outset 2px;/*上边框*/
     	width: 700px;
    	height: 500px;
    	overflow-y: scroll;
    	overflow-x:visible;
    	font-size:14px;
    	
    }
    
    ul {
    	margin: 0px;
    	padding: 0px;
    	list-style: none;
    	color:#7CFC00; /*显示字体颜色*/
    }
    
    input {
    	background-color: #9FB6CD; /*输入行颜色*/
    	border: 0;
    	color: #FFFFFF; /*输入字体颜色*/
    	outline: none;
    	font-size:14px; 
    	width: 99%;
    }
    </style>
    
    <script>
    $(function(){
    	$("#in").keyup(function(event) {		
    	
    		if (event.keyCode == 13) {	//回车			
    			$.ajax({
    				async: false,
    				type : "POST",
    				url : "${pageContext.request.contextPath}/admin/cloudcompute/linux.do",
    				data : "code=" + $("#in").val().substring(1),
    				success : function(data) {
    					$("ul").append("<li>" + $("#in").val() + "</li>");  //将输入的输出到界面
    					$("ul").append("<li>" + data + "</li>"); //获取返回值并输出
    					$("#in").val("$"); //清空输入框
    					$("#msg").scrollTop($("#msg").scrollTop() + 32);//滚动条拉到最下面,显示出输入框
    				}
    			});
    		}
    		/* else  if(event.ctrlKey && event.which == 81){ //ctrl+Q 中断
            	alert("ctrl+Q 中断");
            }
    		else  if(event.which == 27){ //ESC 退出			
            	alert("ESC终端");
            	CloseWebPage();
            }
    			 */
    	});
    
    	$("#in")[0].focus();	
    	
    });
    	
    	
    
    function CloseWebPage() {
    	if (navigator.userAgent.indexOf("MSIE") > 0) {
    		if (navigator.userAgent.indexOf("MSIE 6.0") > 0) {
    			window.opener = null;
    			window.close();
    		} else {
    			window.open('', '_top');
    			window.top.close();
    		}
    	} else if (navigator.userAgent.indexOf("Firefox") > 0) {
    		window.location.href = 'about:blank ';
    	} else {
    		window.opener = null;
    		window.open('', '_self', '');
    		window.close();
    	}
    }
    </script>
    </head>
    
    <body>
    <div id="msg">
    	<ul>
    	<li>----------------------命令Demo----------------------------</li>
    	<li>关闭进程方式1:</li>	
    	<li>ps -aux | grep test.jar		//根据提交的jar包名字来查找进程,再kill -9 [pid]杀掉进程</li>
    	<li>关闭进程方式2:</li>	
    	<li>ps -aux | grep test.jar | kill -9 `awk '{print $2}'`	//查找进程id并立即杀掉</li>
    	<li>关闭进程方式3:</li>
    	<li>kill -9 $(cat my.pid)	//前提:提交任务时获取进程号: spark-submit --class demo.WordCount test.jar & echo $!>my.pid</li>
    	<li>----------------------开始操作----------------------------</li>
    	</ul>
    
    	<!-- <div class="incmd"  contentEditable="true"  id='in'>$</div> -->
    	<input type="text" value="$" id='in'>
    </div>
    
    </body>
    </html>
    

    5.页面调用后台代码的部分都是一样的,linux.do就会调转到前面提到的getLinux()方法。

    ok, 本文主要从后台到前台的顺序讲了如何实现一个简单web shell。

    完。

    我准备写一个公众号技术博客,回顾我学大数据以来的个人经验,希望和大家一起每天进步一点点!刚刚开始写,请大家多多支持,如有不足之处多多包含,最后多多关注哈哈哈。


    展开全文
  • 今天无意中发现,URL中的查询字符串,不一定非要是xxx=yyy&aaa=bbb格式,服务器将URL中问号后的查询字符串赋给名为QUERY_STRING的...所以我想可以直接把shell命令作为URL输入,返回shell执行的输出。试了下,果然可以。
  • Web页面执行shell命令 2019-07-15 23:37:17
    本文以apache为web服务器为例 安装apache服务yum -y install httpd 启动apachesystemctl restart httpd 创建shell脚本cd /var/www/cgi-bin/vim shell #!/bin/sh alias urldecode='sed "s@+@ @g;s@%@\\\\...
  • WebSocket的工作流程:浏览器通过JavaScript向服务端发出建立WebSocket连接的请求,在WebSocket连接建立成功后,客户端和服务端就可以通过 ...接下来介绍一个执行Linux服务器备份脚本的案例: 第一步:安装websocket
  • 1.使用开源框架GateOne (1)查看服务器python的版本和安装pip $python -V 由上图,我服务器的python版本是2.7.5 由上图,当python2的版本是2.7.9+或是python3的版本是3.4+时会自带pip,那我的python版本是2.7.5就...
  • 先小说两句:今天研究了下PHP调用LINUX命令的功能,一开始怎么做都调用不成功,试了好久才终于成功了,所以发出来分享一下。下面我将详细介绍:  PHP中提供了几个调用linux命令的函数,exec、system、passthru,...
  • 通过php重启apache可以把apache的控制放到web页面上。 但是由于php本身的运行模式,一般而言,除非apache具备root权限,否则php连/etc都访问不了,更不用说反过来控制apache了。 因此,我们需要找到别的方法。 ...
  • Java /Jsp 执行操作系统命令 windows/Linux
  • 在公司快待5个月了,连测试的妹子都会部署项目,而笔者连基本的linux命令都没用熟,真是太没面子了,于是,便自己安装虚拟机,将自己的web项目部署到linux服务上。 接下来,笔者一一进行介绍,希望给还不会部署项目...
  • 嵌入式开发应该掌握的一些Linux命令  Linux提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作、文件存取、目录操作、进程管理、文件权限设定等。所以,在Linux系统上工作离不开使用系统提供的命令...
  • 之前写过 Windows 7下Python Web开发环境搭建笔记,今天写一下在Linux系统下搭建Python Web的开发测试环境。 我使用的系统是:ubuntu 14.04 server,CentOS 参考我的最新记录:CentOS release 6.10 下 Python 3.7.5...
  • 2019独角兽企业重金招聘Python工程师标准>>> ...
  • PHP执行shell命令无效 2018-09-30 01:58:25
    $...上面的shell命令linux命令行里可以执行,PHP文件在CLI模式下也可以执行,在WEB执行返回127,找不到命令。PHP是用root权限运行的,这是什么原因?
  • Linux 搭建静态页面 2018-06-13 10:31:02
    很多时候由于测试需要,经常搭建测试网站,下面是个人写的简易shell 脚本,快速搭建静态页面,跟搭建分享下#/bin/bashecho "正在安装检测环境!!!耐心等待"port=80ping baidu.com -c 3 &gt; /dev/...
  • linux apache web站点配置详解 注意:请先在"安全性及防火墙设置"打开对www服务的访问 httpd的配置文件为/etc/httpd/conf/httpd.conf 试修改以下指令: 1. Web站点的主目录 DocumentRoot:设置...
  • linux web服务器搭建 2016-06-30 22:44:59
    linuxWeb服务器搭建 boa web服务器介绍boa是一款非常小巧的web服务器,执行代码大约只有60K,广泛应用于嵌入式平台。boa服务器是一个单任务网络服务器,只能依次执行用户的请求。bao下载地址(已经进10年没有更新...
  • 参考文章:https://linux.cn/article-6817-1.html 简易web服务器 web服务器是指在物理服务器上搭建的网络连接服务器,时刻等待客户端的请求,并作出响应。 客户端与服务器的通信,是以HTTP协议进行的,客户端...
  • web部署到Linux乱码问题 2015-06-08 11:38:05
    用IDea打包web项目 打开File —>project structure,如图 配置好之后,点击OK之后,本以为会在Output directory中出现对应的war包,可惜没有,还需要把添加好的artifacts配置到tomcat里,重启之后,才...
1 2 3 4 5 ... 20
收藏数 88,365
精华内容 35,346