在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,可以轻易地将一个普通脚本或程序包装成一个网络服务,这在某些情况下非常有用,比如来自产品人员或决策者的临时的访问某些功能或数据的需求。