Sherver: Bash lightweight web server
github.com
github.com
#!/bin/bash
while : ; do cat conference.txt | nc -l 80; done
Here's the story behind it:Two comments:
- using "ping -a" creates an audible ping so you can find the server if you're by yourself without having to look at the screen.
- No need for cat:
while :; do nc -l 80 < conference.txt; done $ ping -a 127.0.0.1 | less
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.029 ms^G
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.023 ms^G
Looks like you need a terminal that has a BEL sound.Edit: Uhm, right. I have also silenced all system sounds in Windows.
Why does firefox shows the "chose an application to open this link" when you access the http://localhost link, but shows the content correctly when you access the 127.0.0.1/0.0.0.0 ip-based version?
HTTP/1.1 200
Content-Type: text/plan;
1st line of contentPersonally, in that case, I'd use:
python3 -m http.server
For example I ran a simple hello world test service on Kubernetes once using Python's http.server.
Just having 3 Kubernetes health checks happen on regular intervals would routinely cause the server to respond with errors. I think what ends up happening is if you have 2 requests coming in within a short enough period of time one of them will fail. You have to use a more complicated threaded http server if you want a zero dependency solution.
Also works great (but a bit bulkier sure).
Personally I use busybox's httpd (which does support CGI) for a small portable web server.
The pages could be served as part of a project (all version-controlled), or as documentation pages, or as wiki. Styling is somewhat limited, but could still be done creatively.
Additionally, a static website or even a whole application (PHP or the likes) could be rolled out via /ext, the 'extension' path.
Definitely not “pure”.
edit: on top of that, I already found a perl script utility in the repo: https://github.com/remileduc/sherver/blob/master/scripts/uti...
EDIT: changed link to the github issue I created with inlined utility.
I am wrong! See response.
Thanks for correcting me :)
HEAD_TEMPLATE=$(cat <<EOF
<title>Sherver example</title>
<meta name="description" content="Sherver example">
EOF
)
https://github.com/remileduc/sherver/blob/master/scripts/ind...That would be surprising. How would that work? `cat` is definitely not a bash built-in.
Other examples include `which`, `time`, `echo`, etc. They're usually promoted to built-ins when it's clear that's the intended command to run, but there are still analogs on the PATH if need-be - I'm not sure exactly how bash would detect a non-standard executable there to know when it's unsafe to promote to a built-in, though.
For example with echo:
$ bash -c 'echo hi'
hi
$ strace bash -c 'echo hi' | grep 'exec'
execve("/usr/bin/bash", ["bash", "-c", "echo hi"], 0x7fffe264aad0 /* 24 vars */) = 0
$ strace bash -c '$(which echo) hi' | grep 'exec'
execve("/usr/bin/bash", ["bash", "-c", "$(which echo) hi"], 0x7fffe36c6cd0 /* 24 vars */) = 0
execve("/usr/bin/echo", ["/usr/bin/echo", "hi"], 0x7fffe2e16ff0 /* 25 vars */) = 0
In fact for me, `cat` always gets inlined, even if I call it with its full path or with `which cat`.There are cases where the built-in and the actual executable differ - the most prominent case being `time`. The built-in does not have the command line arguments to print out things like pre-empted scheduling (forced context swiches).
$ time --help
--help: command not found
$ /usr/bin/time --help
Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]
[--portability] [--format=format] [--output=file] [--version]
[--quiet] [--help] command [arg...] $ strace bash -c 'echo hi' | grep 'exec'
execve("/usr/bin/bash", ["bash", "-c", "echo hi"], 0x7fffe264aad0 /\* 24 vars */) = 0
Something seems off. strace(1) prints the trace to stderr not stdout, so you should need |& not | to catch it with grep. At least, that's how it works here.Also, cat does not appear to be inlined for me:
rascul@smarts:~> strace bash -c 'cat /etc/os-release' |& grep 'exec'
execve("/usr/bin/bash", ["bash", "-c", "cat /etc/os-release"], 0x7ffe7b5334e0 /* 88 vars */) = 0
execve("/usr/bin/cat", ["cat", "/etc/os-release"], 0x562c447076f0 /* 88 vars */) = 0*The output was copied 1:1 though.
The inlining is an implementation detail and I've seen it happen differently across different platforms.
Do you have more information on this? I would be interested to read more about it. As far as I was aware (and my knowledge is certainly not exhaustive), the only thing kinda related is as noted in the bash man page:
> The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).
strace -ff -e execve /bin/bash -c 'x="$(cat <<< "test")"'
... snip
[pid 311214] execve("/usr/bin/cat", ["cat"], 0x56280da76fc0 /* 3 vars */) = 0They are not comparable. I've never seen a shell inline cat, probably because it would make no sense given there are POSIX builtins to do exactly what cat does.
strace doesn't lie here, and I've seen it substitute cat in trivial cases quite often.
I'm genuinely curious to see an implementation but I suspect you've misunderstood something in the past and your statement was incorrect.
Your second strace is misleading, you didn't trace child processes.
$ strace bash -c '$(which echo) hi' 2>&1 | grep 'exec'
execve("/bin/bash", ["bash", "-c", "$(which echo) hi"], 0x7ffddfcdaee0 /* 59 vars */) = 0
execve("/bin/echo", ["/bin/echo", "hi"], 0x55eb565cb0b0 /* 59 vars */) = 0
$ strace -f bash -c '$(which echo) hi' 2>&1 | grep 'exec'
execve("/bin/bash", ["bash", "-c", "$(which echo) hi"], 0x7ffd09b3e228 /* 59 vars */) = 0
[pid 81493] execve("/usr/bin/which", ["which", "echo"], 0x5560d172e0b0 /* 59 vars */) = 0
execve("/bin/echo", ["/bin/echo", "hi"], 0x5560d172e0b0 /* 59 vars */) = 0There’s no runtime “promotion”. You can read about it all in bash(1).
IFS='' read -r -d '' HEAD_TEMPLATE <<'EOF'
<title>Sherver example</title>
<meta name="description" content="Sherver example">
EOF
https://stackoverflow.com/questions/1167746/how-to-assign-a-... HEAD_TEMPLATE='
<title>Sherver example</title>
<meta name="description" content="Sherver example">
'[0] https://github.com/remileduc/sherver/blob/master/scripts/ind...
``` caddy file-server --browse --listen :80 ```
Since the title reads "pure bash" however I was expecting to see an implementation using builtin bash features such as /dev/tcp.
Have you considered solving this problem using BASH builtin support for TCP?
It can also run on Unix via plan 9 port (p9p) or derivatives.
https://github.com/9front/9front-test/blob/master/rc/bin/rc-...
darkttpd: When you need a web server in a hurry.
If you ignore all of the manual installation instructions and any dev time you took to create this, then sure.
I’m not going to argue that the author should have used something else instead though. It’s a personal project used purely on an internet system of his house. For those kinds it projects “because I could” is as good a reason as any. I just think more authors should be honest and say “I just did it because it seemed fun at the time”
Don’t get me wrong, I have nothing against building things for fun. But the technical arguments made for why this is preferable over an established solution doesn’t stack up.
Just as I would use this (would look into it more first though), the netcat trick mentioned here or python3 -m http.server over ever considering installing Ansible and/or nginx/apache.
Totally different use case though.
Or I’d use Docker.
But as said before, there’s no wrong answer here since it’s just a hobby project running on a HTPC.