25 ms·
I got tired of PHP and Perl, so I tried bash
- nerdgeneration 7y agoSo anyway, I've been writing websites for 20 years, and this seemed fun. Some friend suggested I post it here, so I'm doing that just to shut him up.
- KerryJones 7y agoYour title made me smirk
- jaequery 7y agoWhat will you do once you get tired of bash?
- mirkules 7y agoPort it to Javascript, naturally. bash.js has a nice ring to it
- shaan7 7y agoLOL. I see what you did there xD
- DyslexicAtheist 7y agoWebAssembly would be pretty cool too. I hear there is now something called WebAssembly "usermode" which can run directly in ring-0. WebAssembly + Ring-0 = Security /s https://github.com/cervus-v/cervus https://github.com/cervus-v/cervus
- unforswearing 7y agohttp://adilapapaya.com/docs/shelljs/ http://adilapapaya.com/docs/shelljs/
- nerdgeneration 7y agoI made some progress with an assembler version but it's just gruelling, hard work.
- aasasd 7y agoI knew a guy who was writing Win32 apps in asm in high school. Heard that he became really weird in uni.
- vortico 7y agoEverything being a string does solve potential type issues...
- TazeTSchnitzel 7y agoIt also creates in-band signalling security hell, even worse than the web already inherently has.
- kowdermeister 7y agoThanks, I almost killed my laptop spitting coffee on it :)
- tlrobinson 7y agoI wrote something similar, including a CGI webserver written in shell: https://github.com/tlrobinson/martin.sh https://github.com/tlrobinson/martin.sh
- wahern 7y agoIf you used `<<-EOT` you could tab-indent the HTML so it reads better. The tabs will be automatically removed and the source code will be much more readable.[1] Of course, it would require tab-indenting all your shell code (but not the HTML itself), which may be a hard pill to swallow if you're a spacer. But the fact is that tab indenting was once upon a time the norm in the land of Unix programming and the tools reflect this. Windows converts and Python programmers are the ones who turned the tide. I suspect that when most read older source code from the Unix universe they don't realize it's almost entirely tab indented because 90% of the source code will still look clean no matter the tab stop (which is of course the very point of hard tabs =) [1] I never understood why Perl's heredoc construct didn't also adopt this behavior. I always cringe when people use heredoc (even in shell) without indenting the entire body properly. I mean, that's kinda the point of the heredoc--so the data becomes part of the code.
- jmontano 7y agoCool Idea, and very easy to migrate between VMs.
- Twirrim 7y agoSee also: https://github.com/avleen/bashttpd https://github.com/avleen/bashttpd
- foobarian 7y agoAnother way to skin the cat: https://github.com/cemeyer/httpd.sh https://github.com/cemeyer/httpd.sh Based on ctypes: https://github.com/taviso/ctypes.sh/ https://github.com/taviso/ctypes.sh/
- rgoulter 7y agoOn the topic of "why would you write that with that", this is worth a mention: https://github.com/azac/cobol-on-wheelchair https://github.com/azac/cobol-on-wheelchair
- earenndil 7y agoAnd bourne shell server pages https://web.archive.org/web/20170208092035/http://hyperrealm.com/wtfd00d/shsp/ https://web.archive.org/web/20170208092035/http://hyperrealm...
- jsks 7y agoHad to register just for this, hilariously inappropriate web servers written in various *sh dialects is my weird pet hobby. Some additional related projects not yet mentioned: balls (bash): https://github.com/jneen/balls https://github.com/jneen/balls czhttpd (zsh; full disclosure, author here): https://github.com/jsks/czhttpd https://github.com/jsks/czhttpd sh-httpd (ksh): https://www.dartmouth.edu/~rc/classes/ksh/sh-httpd.html https://www.dartmouth.edu/~rc/classes/ksh/sh-httpd.html zshttpd (zsh): https://github.com/hkoba/zshttpd https://github.com/hkoba/zshttpd ZWS (zsh): http://www.chodorowski.com/projects/zws/ http://www.chodorowski.com/projects/zws/ With zsh you can avoid the dependency of netcat/socat and use the builtin TCP module which is both super cool and terrifying.
- munificent 7y agoThat title reads like "I got tired of punching myself in the face and kidney, so I tried punching myself in the crotch". I love it.
- svnpenn 7y agoThat's exactly how I read it. Php and Perl are really from a time gone by. neither have REPL. php doesn't even have to a proper print command, you have to add your own newline. Granted they are both quite fast, but with perls "write only" syntax I would only use either of them for the most basic of scripts.
- nicoburns 7y agoPHP has a repl https://github.com/bobthecow/psysh https://github.com/bobthecow/psysh
- empyrical 7y agoAlso, `php-cli` has a very basic REPL which can be accessed using `php -a`.
- ambicapter 7y agoRemember to terminate every line with a semicolon, and enjoy quirks like true printing boolean(true) and false printing nothing at all.
- carmate383 7y agoExcept that PHP does have a REPL, and using PHP_EOL is hardly a big deal. PHP induces an undeserved gag-reflex for most Ruby / Python / JS devs because they read some "why php sucks" post on someone's blog ten years ago, but really the language is quite modern now (not to mention faster).
- TazeTSchnitzel 7y ago
- LeoNatan25 7y agoNot the smartest idea putting "www.sh" in the title, which redirects to a Chinese site.
- whalesalad 7y agoThe best thing about projects like this is how well they illustrate the MVP web framework. A lot of people think things like Django or Rails are magical massive beasts, and to some extent they are, but vast portions of it can get boiled down to something like this. tl;dr if you’re not sure how to roll your own very simple web request/response framework, this is a great intro.
- tyingq 7y agoBocker is similar for better understanding Linux containers. https://github.com/p8952/bocker https://github.com/p8952/bocker
- brainpool 7y agoI wrote a CMS in Standard ML. My only excuse was that I did not know better. The only other language I knew was Prolog. Should have done it in bash instead, would have been easier.
- LeoPanthera 7y agoI can't tell you which one, but I know that a very popular website you will have heard of with a surprisingly high Alexa ranking is almost entirely powered by a bash script via CGI. I'm constantly surprised it hasn't exploded yet.
- omarchowdhury 7y agoThis anecdote means nothing without identifying the site.
- deepakhj 7y agoCraigslist?
- cutler 7y agoPerl and MySQL.
- Stranger43 7y agoIm not the old mod_cgi model when done by a competent programmer for things that should be simple, stacks up surprisingly well against modern complexity because we can "kitchen sink included" frameworks.
- themodelplumber 7y ago> Im not the old Could you clarify?
- maimeowmeow 7y agoebay?
- frumph 7y agoGanesh is a fun option as a sinatra-inspired bash web framework for internal services: https://github.com/tropicloud/ganesh https://github.com/tropicloud/ganesh
- _Marak_ 7y agoDoes anyone know what the theoretical limitations of trying to use Bash as a Web Server are? How many requests per second could it serve? What about HTTP/2 support?
- jniedrauer 7y agoPerformance is kind of a meaningless question in this case, since the "bash" script makes calls to external binaries. You could write a webserver binary in C, then invoke it with bash and call it a shell script.
- Lowkeyloki 7y agoThis is a good question. I've always kind of wondered what bash's performance characteristics were compared to other programming languages. Bash certainly feels fast.
- Can_Not 7y agoMaybe you could ask the people who use/maintain this: https://github.com/avleen/bashttpd https://github.com/avleen/bashttpd
- nightfly 7y agoIt would share all the same limitations as any other forking server, plus extra overhead for any spawned child processes. Basically the same as using CGI scripts, and probably not much worse any Apached hosted PHP based website, tbh. Probably wouldn't be worth implementing HTTP/2 since it would increase the complexity with no real benefit.
- dec0dedab0de 7y agoReally you should be starting with bash, thats how you know why these other languages exist. My rule of thumb used to be if I have more than one "if" in a shell script then its going to python... But now its any ifs or variables Edit: now that I read the readme I think the title should have been "show hn: I made a web framework in bash" this is pretty neat, I still wouldnt use it, but its cool as hell.
- ryl00 7y agoLearning perl first stunted my bash knowledge; I'm very, very quick to bail into perl at the first sign of difficulty. :)
- JshWright 7y agoDo you consider that a bad thing?
- tmh88j 7y agoUnless he didn't mean to use the word "stunted", I would say yes.
- BoorishBears 7y agoNote to self: Don't ask rhetorical questions on HN.
- earenndil 7y ago> My rule of thumb used to be if I have more than one "if" in a shell script then its going to python... But now its any ifs or variables Hmm. I have a slightly different view. If logic is complex, then it should be moved to a different language. But if there are a lot of flat if statements then shell is fine.
- dmitryminkovsky 7y agoYeah it’s almost inevitable for a bash script to have lots of ifs but they’re almost always simple, checking some variable is empty or something.
- alexanderscott 7y agoLook thru the code though... Thought this would do more than serve a static html file. Not impressed
- nerdgeneration 7y agoIt doesn't. The route defines the controller. The controller displays the content, ideally using the view function (there are examples with and without a view, but always with a controller). The view function takes an associative array for template replacements.
- telaelit 7y agoYou monster
- nerdgeneration 7y agoThank you! ;)
- waterhouse 7y agoSuggestion: You use "set -e". The problem with this is that it's silent about which line the script died at, so if your script doesn't print a lot, you may have to do detective work. This is an automatic way of giving you a bit of a hint: $ cat meh.bash #!/bin/bash set -e die() { echo "Failed at line $1: $2" } trap 'die $LINENO "$BASH_COMMAND"' ERR echo a test 1 = 3 echo b $ ./meh.bash a Failed at line 8: test 1 = 3 Adapted from: https://unix.stackexchange.com/a/462157 https://unix.stackexchange.com/a/462157
- shakna 7y agoIf you also set 'x' then you'll get a log of how it's interpreting each line.
- jmcnulty 7y agoThat's useful. Thanks.
- arendtio 7y agoIf your script dies because of `set -e` the detective work is just the punishment to condition yourself to write more stable code in the future ;-) By the way, if you are just using Bash (instead of POSIX /bin/sh) you can do even better. Some time ago I found a stacktrace function somewhere: set -Eeuo pipefail trap stacktrace EXIT function stacktrace { if [ $? != 0 ]; then echo -e "\nThe command '$BASH_COMMAND' triggerd a stacktrace:" for i in $(seq 1 $((${#FUNCNAME[@]} - 2))); do j=$(($i+1)); echo -e "\t${BASH_SOURCE[$i]}: ${FUNCNAME[$i]}() called in ${BASH_SOURCE[$j]}:${BASH_LINENO[$i]}"; done fi }
- Lowkeyloki 7y agoHas this been run through ShellCheck? Once scripts are run through ShellCheck, I'd almost consider them safe. No disrespect to ShellCheck, though. It's a fantastic tool.
- proboscis 7y agoShellcheck is indeed great. I needed to make a BASH script to give to my girlfriend that would install on her OS X a snake game I made. Using shellcheck made that a lot easier. For example, I didn't know that the [[ ]] syntax wasn't POSIX compliant. Really great for learning and remembering little things like that for portability.
- nerdgeneration 7y agoNope. TIL about ShellCheck and BATS, and got a Dockerfile feature request. They're all on my to do list.
- neokantian 7y agoBash is the love of my life. However, it has serious weaknesses. Its array/table concept is flawed. You cannot do tables containing tables. Secondly, out of the box it cannot load or invoke functions in libraries. Fortunately, ctypes.sh solves this problem, and to some extent, indirectly, also the table of tables problem.
- xelxebar 7y agoShell scripting gets a lot of hate, but after spending time to grok the language (and copious use of shellcheck), I've grown quite fond of it. This also has the nice side effect of emphasizing use of old unix tools. I think the "big realization" for me was shifting to think in pipelines instead of passing state around in variables. That completely removed the pain of no arrays in POSIX shell for me. Stdin/stdout are your friend. Certainly, shell scripting isn't the answer for everything, but with shellcheck (and bats!), I feel like it's a really reasonable default for systemy things. Heck, the status bar I use in my window manager is essentially just a 700 line bash script, with asyncronous update and everything. It's even quite readable and orthogonally organized, if I might boast. Have been pleasantly surprised over the years every time I go back and read it.
- thundergolfer 7y agoHaven't tried BATS before, but it sounds like the missing part of our bash codebase, which I am currently mostly skeptical of because it isn't unit tested. I'd fear though that having BATS would just increase the tendency to let a bash script grow from 50 lines through to 200, when it should've just been ported to Python at 100.
- mstade 7y agoActually, my experience with bats is that it forces you to modularize and keep things small. Easier to test things that way. Bats is truly an indispensable tool when doing shell scripting – I even use it to test CLIs built in other languages too!
- yakshaving_jgt 7y agoIf that was the big realisation, you may enjoy FP.
- hyperpallium 7y ago> [...] the "big realization" for me was shifting to think in pipelines instead of passing state around in variables. That completely removed the pain of no arrays [...] Could you elaborate please? I see that data - especially sequential, array-like data - is conveniently passed via pipes (and e.g. jq https://stedolan.github.io/jq/ https://stedolan.github.io/jq/ uses this concept), but I feel you're saying something deeper or a different kind of use-case... [perhaps because you say "state" not "data")
- honkycat 7y agoIf you are writing more than 10 lines of bash, write python instead. Awful language. Waste of time.
- roryrjb 7y agoYou're using it wrong. The things that bash is good for are not the same things that Python should be used for. For what bash is good for, it is the simplest and fastest language one could use.
- okasaki 7y agoWhat is bash good for?
- roryrjb 7y agoPlugging programs together; pipelines. It exposes the UNIX principle. You can use it to augment, to extend, to improve programs written in any language you can imagine, past, present and future. If the program is written in C, C++, Rust you'll get the performance of those programs. What I'm saying you might find very obvious when using it interactively but there have been so many instances where it fulfils my needs. More often than not in certain problem domains it's the first thing I reach for and it usually solves the issue. I'd also like to add that I exclusively write POSIX shell scripts rather than Bash.
- h1d 7y agoFor a task like taking backups on servers that involves invoking bunch of commands, I'd rather not use a scripting language that asks you to open a process, bind variables on its stdin/stdout and all the boilerplate handling. How do you do this in a scripting language without complication? $ ssh remote.server 'mysqldump db | gzip -c' | gunzip -c | mysql db It's the power of individual commands though I admit bash sucks as a language but it got invented forever ago, so can't blame it. But we need something better than bash. Fish is close but not too good.
- AceJohnny2 7y agoI hated Perl until I had to do Bash scripting. I must apologize to Perl. I see now where it was coming from [1], and what it saved us from. May god have pity on your soul for inflicting us with this. [1] There are lots of quirks in Perl that I now recognize come from shell scripting. Most obviously, $VAR notation and string quoting.
- StreamBright 7y agoWhy not OCaml or Rust?
- nerdgeneration 7y agoMaybe when I finish the assembler version...
- hyperpallium 7y agoWhen you're tired of PHPing and Perling yourself in the head.
- hyperpallium 7y agoKnock bash if you will, but in my experience, it has the best and most helpful community on SO of any language.
- h1d 7y agoProbably because more grown ups know it well.
- revskill 7y agoI got tired of bash. Still waiting for `typed bash`.
- Pamar 7y agoThis is of course just personal preference, and I have to admit that it might be heavily influenced by the shift in responsibilities (i.e. my job involves less and less scripting at the CLI level nowadays) but I was always partial to DCL: https://en.wikipedia.org/wiki/DIGITAL_Command_Language https://en.wikipedia.org/wiki/DIGITAL_Command_Language
- louwrentius 7y agoMany years ago I learned myself Bash by writing this: https://github.com/louwrentius/PPSS https://github.com/louwrentius/PPSS It's a huge bash script for parallel processing of work. It was great fun and I'm proud of it as I don't see myself as a programmer of any sort. But gosh since I learned Powershell and Python, I would never ever ever ever ever use Bash for anything substantial. If you ever feel like you grow 'fond' of Bash or Shell scripting, it's time to seek a doctor. Please learn Python or some equivalent instead. ----------------- Edit: reading the code of this web server project: Let's be absolutely clear: this is a joke project. DO NOT USE THIS FOR # ANYTHING, ESPECIALLY ON A PUBLIC FACING SERVER.
- DyslexicAtheist 7y agonice one. this is my favorite way of learning languages. find it really hard going step by step through a book from scratch and my fingers get really itchy and want to skip ahead into solving real problems. my result is usually a lot worse than what you built there. seems a lot of effort and iterations went into this? I have seen quite a bit of legacy plumbing like this in production / automation until better (or at least standardized) tooling came along with the agile/devops movement. A lot of this plumbing survived surprisingly long (which is also scary). Often code like this matures over long periods into stable solutions that could even deal with errors well. Makes them hard to replace. I agree it doesn't belong in production but it looks pretty neat for small internal stuff even in 2019.
- louwrentius 7y agoIt was a lot of work but it was my first real attempt at programming and the topic itself was motivating enough to bring it to completion. Learning from books doesn't work, you need to have a project with a goal to apply it in. The horrible honest truth is that the world actually doesn't run on bash, python, C or Java. It runs on Excel macro's.
- aloisamae 7y agoThis. Some of my Structural engineering professors have invested so much time in Excel they practically have an instance of their mind in it. Really fancy systems too that could do just about anything they needed. Always impressed me. Your project is a great read!
- isostatic 7y agoWhenever I write websites in bash, I start off fine, but tend to regret it, and end up refactoring into Perl.
- nerdgeneration 7y agoWhenever I write anything in bash, I start off fine, but tend to dig my heels in as it gets harder and refuse to switch languages.
- tasubotadas 7y agoI got tired of crack and meth, so I tried heroin.
- proboscis 7y agoIf I'm doing any scripting, I always use BASH. However, I'm trying to actively push myself to learn another more portable scripting language. I still haven't been able to decide which out of Python, Perl and Ruby that I really want to throw myself into -- although recently I have started to become more and more attracted to Ruby.
- tyldum 7y agoIf you are thinking about Perl, then take a look at Mojolicious. An amazing framework to work with that covers so many common use cases with async and functional programming style. I find that the code becomes very precise and readable.
- ricardobeat 7y agoI write shell scriots all the time for a myriad of tasks, but will tore my arm off before writing a server in it. It is very well suited for imperative scripts, but the language breaks down pretty quickly once complexity and the level of abstraction go up; you start relying on obscure syntax, behaviour, and piling up more and more patterns that require full week-long immersion to grasp. Perl is harmless in comparison.
- k__ 7y agoalso: there is a AWS Lambda Bash runtime. https://github.com/gkrizek/bash-lambda-layer https://github.com/gkrizek/bash-lambda-layer
- Matumio 7y agoI think "One does not write a web server in Bash" is like "One does not simply walk into Mordor." You're practically daring short people with hairy feet to attempt it. (Quote: seebs on slashdot)
- nihil75 7y agolol living life in reverse :)
- redm 7y agoIt’s a neat experiment, totally impractical, but neat. What this has to do with PHP or Perl I have no idea.
- nerdgeneration 7y agoIt's just personal. I did Perl in 1997/98 and 2017 to now. I did PHP from 1998 to 2017.
- zimbatm 7y agoBash is a misunderstood language. A lot of developers don't take time to learn it enough and discard it because of that. So I started a twitter handle that posts semi-regular tips and tricks about it: https://twitter.com/thewayofbash https://twitter.com/thewayofbash