我正在尝试使用netcat(nc)设置最小的Web服务器。例如,当浏览器调用localhost:1500时,它应该显示一个函数的结果( date 在下面的例子中,但最终它将是一个产生一些数据的python或c程序) 。 我的小netcat web服务器需要在bash中成为一个真正的循环,可能就像这样简单:
while true ; do echo -e "HTTP/1.1 200 OK\n\n $(date)" | nc -l -p 1500 ; done
当我尝试此操作时,浏览器会在nc启动时显示当前可用的数据。我希望浏览器在浏览器请求时显示数据。我怎样才能做到这一点?
答案 0 :(得分:37)
试试这个:
while true ; do nc -l -p 1500 -c 'echo -e "HTTP/1.1 200 OK\n\n $(date)"'; done
-c
使netcat在shell中执行给定命令,因此您可以使用echo。如果您不需要回声,请使用-e
。有关此问题的详细信息,请尝试man nc
。请注意,使用echo
时,您的程序(date
- 替换)无法获取浏览器请求。所以你可能最终想做这样的事情:
while true ; do nc -l -p 1500 -e /path/to/yourprogram ; done
yourprogram
必须执行协议之类的操作,例如处理GET,发送HTTP 200等。
答案 1 :(得分:34)
唐诺怎么或为什么但我设法找到这个并且它对我有用,我有问题我想要返回执行bash的结果
$ while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; sh test; } | nc -l 8080; done
注意:此命令来自:http://www.razvantudorica.com/08/web-server-in-one-line-of-bash
执行bash脚本测试并将结果返回给连接到端口8080上运行此命令的服务器的浏览器客户端
我的脚本执行此ATM
$ nano test
#!/bin/bash
echo "************PRINT SOME TEXT***************\n"
echo "Hello World!!!"
echo "\n"
echo "Resources:"
vmstat -S M
echo "\n"
echo "Addresses:"
echo "$(ifconfig)"
echo "\n"
echo "$(gpio readall)"
我的网络浏览器正在显示
************PRINT SOME TEXT***************
Hello World!!!
Resources:
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 314 18 78 0 0 2 1 306 31 0 0 100 0
Addresses:
eth0 Link encap:Ethernet HWaddr b8:27:eb:86:e8:c5
inet addr:192.168.1.83 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:27734 errors:0 dropped:0 overruns:0 frame:0
TX packets:26393 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1924720 (1.8 MiB) TX bytes:3841998 (3.6 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
GPIOs:
+----------+-Rev2-+------+--------+------+-------+
| wiringPi | GPIO | Phys | Name | Mode | Value |
+----------+------+------+--------+------+-------+
| 0 | 17 | 11 | GPIO 0 | IN | Low |
| 1 | 18 | 12 | GPIO 1 | IN | Low |
| 2 | 27 | 13 | GPIO 2 | IN | Low |
| 3 | 22 | 15 | GPIO 3 | IN | Low |
| 4 | 23 | 16 | GPIO 4 | IN | Low |
| 5 | 24 | 18 | GPIO 5 | IN | Low |
| 6 | 25 | 22 | GPIO 6 | IN | Low |
| 7 | 4 | 7 | GPIO 7 | IN | Low |
| 8 | 2 | 3 | SDA | IN | High |
| 9 | 3 | 5 | SCL | IN | High |
| 10 | 8 | 24 | CE0 | IN | Low |
| 11 | 7 | 26 | CE1 | IN | Low |
| 12 | 10 | 19 | MOSI | IN | Low |
| 13 | 9 | 21 | MISO | IN | Low |
| 14 | 11 | 23 | SCLK | IN | Low |
| 15 | 14 | 8 | TxD | ALT0 | High |
| 16 | 15 | 10 | RxD | ALT0 | High |
| 17 | 28 | 3 | GPIO 8 | ALT2 | Low |
| 18 | 29 | 4 | GPIO 9 | ALT2 | Low |
| 19 | 30 | 5 | GPIO10 | ALT2 | Low |
| 20 | 31 | 6 | GPIO11 | ALT2 | Low |
+----------+------+------+--------+------+-------+
简直太神奇了!
答案 2 :(得分:22)
将-q 1
添加到netcat
命令行:
while true; do
echo -e "HTTP/1.1 200 OK\n\n $(date)" | nc -l -p 1500 -q 1
done
答案 3 :(得分:18)
您面临的问题是,nc不知道Web客户端何时完成其请求,因此它可以响应请求。
网络会话应该是这样的。
TCP session is established.
Browser Request Header: GET / HTTP/1.1
Browser Request Header: Host: www.google.com
Browser Request Header: \n #Note: Browser is telling Webserver that the request header is complete.
Server Response Header: HTTP/1.1 200 OK
Server Response Header: Content-Type: text/html
Server Response Header: Content-Length: 24
Server Response Header: \n #Note: Webserver is telling browser that response header is complete
Server Message Body: <html>sample html</html>
Server Message Body: \n #Note: Webserver is telling the browser that the requested resource is finished.
The server closes the TCP session.
以“\ n”开头的行只是空行,甚至没有空格,只包含一个换行符。
我有由xinetd xinetd tutorial发起的bash httpd。它还会将日期,时间,浏览器IP地址和整个浏览器请求记录到日志文件中,并计算服务器标头响应的Content-Length。
user@machine:/usr/local/bin# cat ./bash_httpd
#!/bin/bash
x=0;
Log=$( echo -n "["$(date "+%F %T %Z")"] $REMOTE_HOST ")$(
while read I[$x] && [ ${#I[$x]} -gt 1 ];do
echo -n '"'${I[$x]} | sed -e's,.$,",'; let "x = $x + 1";
done ;
); echo $Log >> /var/log/bash_httpd
Message_Body=$(echo -en '<html>Sample html</html>')
echo -en "HTTP/1.0 200 OK\nContent-Type: text/html\nContent-Length: ${#Message_Body}\n\n$Message_Body"
要添加更多功能,您可以合并。
METHOD=$(echo ${I[0]} |cut -d" " -f1)
REQUEST=$(echo ${I[0]} |cut -d" " -f2)
HTTP_VERSION=$(echo ${I[0]} |cut -d" " -f3)
If METHOD = "GET" ]; then
case "$REQUEST" in
"/") Message_Body="HTML formatted home page stuff"
;;
/who) Message_Body="HTML formatted results of who"
;;
/ps) Message_Body="HTML formatted results of ps"
;;
*) Message_Body= "Error Page not found header and content"
;;
esac
fi
快乐抨击!
答案 4 :(得分:10)
我有同样的需求/问题,但这里没有任何东西可供我使用(或者我并不了解所有内容),所以这是我的解决方案。
我发布了我的minimal_http_server.sh(使用我的/ bin / bash(4.3.11)但不是/ bin / sh因为重定向):
rm -f out
mkfifo out
trap "rm -f out" EXIT
while true
do
cat out | nc -l 1500 > >( # parse the netcat output, to build the answer redirected to the pipe "out".
export REQUEST=
while read -r line
do
line=$(echo "$line" | tr -d '\r\n')
if echo "$line" | grep -qE '^GET /' # if line starts with "GET /"
then
REQUEST=$(echo "$line" | cut -d ' ' -f2) # extract the request
elif [ -z "$line" ] # empty line / end of request
then
# call a script here
# Note: REQUEST is exported, so the script can parse it (to answer 200/403/404 status code + content)
./a_script.sh > out
fi
done
)
done
我的a_script.sh(根据你的需要):
#!/bin/bash
echo -e "HTTP/1.1 200 OK\r"
echo "Content-type: text/html"
echo
date
答案 5 :(得分:8)
另一种方法
while true; do (echo -e 'HTTP/1.1 200 OK\r\n'; echo -e "\n\tMy website has date function" ; echo -e "\t$(date)\n") | nc -lp 8080; done
让我们使用curl
对2个HTTP请求进行测试在此示例中,172.16.2.6是服务器IP地址。
服务器端
admin@server:~$ while true; do (echo -e 'HTTP/1.1 200 OK\r\n'; echo -e "\n\tMy website has date function" ; echo -e "\t$(date)\n") | nc -lp 8080; done
GET / HTTP/1.1 Host: 172.16.2.6:8080 User-Agent: curl/7.48.0 Accept:
*/*
GET / HTTP/1.1 Host: 172.16.2.6:8080 User-Agent: curl/7.48.0 Accept:
*/*
客户端
user@client:~$ curl 172.16.2.6:8080
My website has date function
Tue Jun 13 18:00:19 UTC 2017
user@client:~$ curl 172.16.2.6:8080
My website has date function
Tue Jun 13 18:00:24 UTC 2017
user@client:~$
如果您想执行另一个命令,请随意替换$(date)。
答案 6 :(得分:5)
mkfifo pipe;
while true ;
do
#use read line from pipe to make it blocks before request comes in,
#this is the key.
{ read line<pipe;echo -e "HTTP/1.1 200 OK\r\n";echo $(date);
} | nc -l -q 0 -p 8080 > pipe;
done
答案 7 :(得分:4)
这是a little bash webserver的美丽,我在网上找到了它并分叉了一下并稍微整理了一下 - 它使用了socat
或netcat
我用{{1}进行了测试 - 它在一个脚本中是自包含的,并生成自己的配置文件和favicon。
默认情况下,它将启动为支持Web的文件浏览器,但配置文件可以轻松配置任何逻辑。对于文件,它传输图像和音乐(mp3&#39; s),视频(mp4&#39; s,avi等) - 我已经测试了各种文件类型到Linux,Windows和Android设备,包括智能手表!
我认为它实际上比VLC更好。我发现将文件传输到无法访问Web浏览器的远程客户端非常有用,例如Android智能手表,无需担心物理连接到USB端口。
如果您想尝试一下,只需将其复制并粘贴到名为bashttpd的文件中,然后使用socat
然后你可以去任何其他计算机(假设防火墙没有阻止到端口8080的入站tcp连接 - 默认端口,你可以使用脚本顶部的全局变量将端口更改为你想要的任何端口) 。 $> bashttpd -s
http://bashttpd_server_ip:8080
答案 8 :(得分:3)
while true ; do (dd if=/dev/zero count=10000;echo -e "HTTP/1.1\n\n $(date)") | nc -l 1500 ; done
你最好用适当的东西尽快替换它!
是啊,我的nc
与你的-p
不完全相同,它不喜欢{{1}}选项。
答案 9 :(得分:2)
输入 nc -h ,看看您是否有 -e 选项。如果是,您可以创建脚本,例如:
script.sh
echo -e "HTTP/1.1 200 OK\n\n $(date)"
然后像这样运行:
while true ; do nc -l -p 1500 -e script.sh; done
请注意,编译时需要启用 -e 选项。
答案 10 :(得分:1)
如果您使用的是Apline Linux,则BusyBox netcat会稍有不同:
{{1}}
答案 11 :(得分:1)
while true; do (echo -e 'HTTP/1.1 200 OK\r\nConnection: close\r\n';) | timeout 1 nc -lp 8080 ; done
1秒钟后关闭连接,因此不会卷曲。
答案 12 :(得分:0)
我认为列出的所有解决方案都不起作用的问题是http服务的本质所固有的,建立的每个请求都是使用不同的客户端,并且响应需要在不同的上下文中处理,每个请求必须分叉一个新的响应实例......
我认为目前的解决方案是-e
的{{1}},但我不知道为什么不起作用...也许是我的netcat
版本测试nc
...
openwrt
它有效....
我试试这个https://github.com/avleen/bashttpd
并且它可以工作,但我必须使用此命令运行shell脚本。
socat
github上的socat tcp-l:80,reuseaddr,fork EXEC:bashttpd &
和socat
示例对我不起作用,但我使用的netcat
无效。
答案 13 :(得分:0)
实际上,正常关闭连接的最佳方法是发送Content-Length
标头,如下所示。客户端(例如curl
将在收到数据后关闭连接。
DATA="Date: $(date)";
LENGTH=$(echo $DATA | wc -c);
echo -e "HTTP/1.1 200 OK\nContent-Length: ${LENGTH}\n\n${DATA}" | nc -l -p 8000;
答案 14 :(得分:0)
在 OSX 上你可以使用:
do echo -e "HTTP/1.1 200 OK\n\n $(date)" | nc -l localhost 1500 ; done