当前所在位置:珠峰网资料 >> 计算机 >> 计算机等级考试 >> 正文
在Shell中打开ServerSocket
发布时间:2010/9/28 16:15:01 来源:城市学习网 编辑:ziteng
  工作中的一个需求:需要为一个现存的功能,提供Web访问界面。由于这个功能是用Shell编写的,首先想到的解决方案是通过在Shell中开启一个Server Socket,来实现一个简单的HTTP服务器,提供给浏览器访问。我并不需要实现所有的HTTP协议,只要能够处理特定的GET请求即可。这个简单的HTTP服务器将会从浏览器发送的GET请求中截取指定参数,然后通过系统调用执行现存的Shell脚本。在网上查找了一下Shell Socket的相关信息,发现实现技术还挺多。摘录了两种方法(为简明起见,所列代码做了简化),记录于此以备忘。
  1.Perl
  01use strict;
  02use IO::Socket;
  03
  04my $server_socket       =       IO::Socket::INET->new
  05(
  06        LocalPort       =>      2010,
  07        Listen          =>      SOMAXCONN,
  08        Proto           =>      'tcp',
  09        Reuse           =>      1,
  10        Timeout         =>      60
  11) or die "SERVER SOCKET ERROR!n";
  12
  13while(1) {
  14        next unless my $connection = $server_socket->accept;
  15        my $url = get_url($connection);
  16
  17        if ($url =~ /^.*\/(\?param=(.*))?$/) {
  18        if ($1) {
  19            system(("myshell", $2)); #myshell是现有功能的shell程序
  20        }
  21                send_page($connection);
  22        } else {
  23                send_404($connection);
  24        }
  25        $connection->close;
  26}
  27
  28sub send_404 {
  29        my $sock = shift;
  30        print $sock "HTTP/1.1 404 NOT FOUND\r\n\r\nNOT FOUND\r\n";
  31}
  32
  33sub send_page {
  34        my $sock = shift;
  35        my $html = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n" .
  36                "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>" .
  37                "<title></title></head><body><form method='get'><input type='text' name='param'/>" .
  38                "<input type='submit' value='Submit'/></form></body></html>\r\n";
  39
  40        print $sock $html;
  41}
  42
  43sub get_url {
  44        my $sock = shift;
  45        my $line = "";
  46        while(($line = <$sock>) ne "\r\n")
  47        {
  48                if ($line =~ /GET ([^ ]+) /) {
  49                        return $1;
  50                }
  51        }
  52        return "";
  53}
  保存脚本为appserver.pl, 以”perl appserver.pl &”启动,然后用浏览器访问http://<ip>:2010/即可。由于Linux发行版上一般都自带Perl,这个方法的适用性还是比较普遍,不过需要熟悉一点Perl语法。
  2.nc命令
  1while(/bin/true)
  2do
  3    nc -l -p 2010 -c "$(cat /path/to/myshell)" #myshell从标准输入读取http请求,将http响应打印到标准输出
  4done
  这种方式可以完全通过shell来实现,相对简洁,但要求nc支持-c选项,且myshell必须是sh语法(不能使用bash)。如果把shell脚本换成二进制程序,可以使用-e选项。不过有些Linux发行版上默认的nc不支持-c和-e选项(在ubuntu desktop和RHEL上就不行,但在ubuntu server上可以)。
  由于部署环境是RHEL,最终我使用了第一种方式来实现我的需求,但第二种方法也很有吸引力。通过在Shell中使用Server Socket,可以轻易地将一个普通脚本或程序包装成一个网络服务,这在某些情况下非常有用,比如来自产品人员或决策者的临时的访问某些功能或数据的需求。
广告合作:400-664-0084 全国热线:400-664-0084
Copyright 2010 - 2017 www.my8848.com 珠峰网 粤ICP备15066211号
珠峰网 版权所有 All Rights Reserved