工作中的一個需求需要為一個現存的功能提供Web訪問界面由於這個功能是用Shell編寫的首先想到的解決方案是通過在Shell中開啟一個Server Socket來實現一個簡單的HTTP服務器提供給浏覽器訪問我並不需要實現所有的HTTP協議只要能夠處理特定的GET請求即可這個簡單的HTTP服務器將會從浏覽器發送的GET請求中截取指定參數然後通過系統調用執行現存的Shell腳本在網上查找了一下Shell Socket的相關信息發現實現技術還挺多摘錄了兩種方法(為簡明起見所列代碼做了簡化)記錄於此以備忘
Perl
use strict;
use IO::Socket;
my $server_socket = IO::Socket::INET>new
(
LocalPort =>
Listen => SOMAXCONN
Proto => tcp
Reuse =>
Timeout =>
) or die SERVER SOCKET ERROR!n;
while() {
next unless my $connection = $server_socket>accept;
my $url = get_url($connection);
if ($url =~ /^*\/(\?param=(*))?$/) {
if ($) {
system((myshell $)); #myshell是現有功能的shell程序
}
send_page($connection);
} else {
send_($connection);
}
$connection>close;
}
sub send_ {
my $sock = shift;
print $sock HTTP/ NOT FOUND\r\n\r\nNOT FOUND\r\n;
}
sub send_page {
my $sock = shift;
my $html = HTTP/ OK\r\nContentType: text/html; charset=UTF\r\n\r\n
<html><head><meta httpequiv=ContentType content=text/html; charset=UTF/>
<title></title></head><body><form method=get><input type=text name=param/>
<input type=submit value=Submit/></form></body></html>\r\n;
print $sock $html;
}
sub get_url {
my $sock = shift;
my $line = ;
while(($line = <$sock>) ne \r\n)
{
if ($line =~ /GET ([^ ]+) /) {
return $;
}
}
return ;
}
保存腳本為appserverpl 以perl appserverpl &啟動然後用浏覽器訪問:///<ip>:/即可由於Linux發行版上一般都自帶Perl這個方法的適用性還是比較普遍不過需要熟悉一點Perl語法
nc命令
while(/bin/true)
do
nc l p c $(cat /path/to/myshell) #myshell從標准輸入讀取http請求將http響應打印到標准輸出
done
這種方式可以完全通過shell來實現相對簡潔但要求nc支持c選項且myshell必須是sh語法(不能使用bash)如果把shell腳本換成二進制程序可以使用e選項不過有些Linux發行版上默認的nc不支持c和e選項(在ubuntu desktop和RHEL上就不行但在ubuntu server上可以)
由於部署環境是RHEL最終我使用了第一種方式來實現我的需求但第二種方法也很有吸引力通過在Shell中使用Server Socket可以輕易地將一個普通腳本或程序包裝成一個網絡服務這在某些情況下非常有用比如來自產品人員或決策者的臨時的訪問某些功能或數據的需求
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26300.html