[HN Gopher] Pure Bash Bible - A collection of pure bash alternat...
       ___________________________________________________________________
        
       Pure Bash Bible - A collection of pure bash alternatives to
       external processes
        
       Author : rrampage
       Score  : 113 points
       Date   : 2022-02-16 18:14 UTC (4 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | infogulch wrote:
       | It's Bash Month on Hacker News, apparently:
       | 
       | My thoughts on writing a Minecraft server from scratch in Bash |
       | https://news.ycombinator.com/item?id=30347501
       | 
       | Bash Pitfalls | https://news.ycombinator.com/item?id=30345487
       | 
       | Show HN: Toolbox - A framework for modular Bash scripts |
       | https://news.ycombinator.com/item?id=30067708
       | 
       | Use Bash Strict Mode |
       | https://news.ycombinator.com/item?id=30217719
       | 
       | A Wordle clone in 50 lines of Bash |
       | https://news.ycombinator.com/item?id=30174112
        
         | krnlpnc wrote:
         | I've been sensing a stigma against shell scripting increasingly
         | over the past decade. It's nice to see bash being used in
         | creative and elaborate ways like this.
        
           | AceJohnny2 wrote:
           | The stigma is well deserved and I will enthusiastically
           | spread it.
           | 
           | Bash should be considered an esoteric programming language.
           | Shell Programming Considered Harmful.
           | 
           | It's hard to program, and easy to make mistakes in. It should
           | be left as a tool of last resort.
           | 
           | (that said, I understand the appeal of doing weird things
           | with it, like the Minecraft server, for the same reason other
           | esoteric programming languages have appeal)
        
             | asdff wrote:
             | What is so hard about it? It feels like python but with an
             | even more english language like syntax, and the man files
             | can be like tomes of knowledge. 'head file.txt' is a heck
             | of a lot easier to wrap your own head around than reading
             | something into an object and calling head on it. Python
             | programmers today would probably import pandas for that.
        
       | [deleted]
        
       | cferr wrote:
       | Another way to touch a file:
       | 
       | cp /dev/null file
       | 
       | Test if a port is listening without telnet:
       | 
       | echo > /dev/tcp/address/port && echo Yes || echo No
       | 
       | That's not actually a file. It's just a path Bash recognizes and
       | is the interface to socket functionality. udp works too.
        
       | jrm4 wrote:
       | As someone who is _genuinely_ a fan of stupid pointless hacks,
       | like Turing Completeness with CSS or Minecraft or whatnot, in my
       | opinion this is definitely _the stupidest._ Kudos.
       | 
       | The entire point of Bash/Shell scripting is (or darn it, ought to
       | be) to use it to string together OTHER programs to get stuff
       | done. "Pure Bash" to me is like a bar of soap that never gets
       | wet.
        
         | jayceedenton wrote:
         | To be fair, when writing scripts it's easy to fall foul of
         | differences between GNU and BSD tools, or using an external
         | tool that isn't available by default on some systems.
         | 
         | Pure bash solutions avoid these problems, and can be just as
         | simple as (or simpler than) an alternative that use external
         | tools.
        
       | tomcam wrote:
       | Awesome that it was made free on github. Of course I donated.
        
       | jteppinette wrote:
       | I'm sorry, but I almost spit my drink out at how unreadable the
       | very first example is.                 trim_string() {
       | # Usage: trim_string "   example   string    "           :
       | "${1#"${1%%[![:space:]]*}"}"           :
       | "${_%"${_##*[![:space:]]}"}"           printf '%s\n' "$_"       }
        
         | pavon wrote:
         | To be fair that is one of the worst. I'm definitely bookmarking
         | this site. Even if I won't use several of the functions, it is
         | really valuable to have a single place to check to see "yeah,
         | that really is the best you can do with bash, I'll exec out
         | instead", rather than scouring through multiple StackOverflow
         | answers that are subtly wrong.
         | 
         | And my bash code would probably be more readable if I started
         | collecting common operations in a function library rather than
         | repeating the same sed/awk incantations that aren't super
         | readable. At that point might as well use pure bash/sh
         | implementations to save spawning a new process when reasonable.
        
         | INTPenis wrote:
         | Oh god, you know you've become anal about bash when you can
         | actually vaguely understand what is going on.
         | 
         | I mean it's parameter expansion, just flip down to that section
         | of the manpage, and then there is posix regex in there. Not too
         | difficult to look up in the manpages.
        
         | [deleted]
        
         | mttjj wrote:
         | I mean, does it really need to be readable? I kind of took this
         | site to be "here's some snippets of code that you can use in
         | your scripts to use instead of calling an external process."
         | Which means to me, I'm going to copy/paste this function into
         | my script, call the function (since it's structured as one),
         | and never think about it again.
         | 
         | "Learn how to write routines like this and make them readable"
         | seems like it's not the point of this "Bible".
         | 
         | I'm not against readable code by any means (maybe there's even
         | a cleaner way to write this) but it seemed inconsequential in
         | my opinion.
        
           | queuebert wrote:
           | > I mean, does it really need to be readable?
           | 
           | Yes, because it says it trims strings, but is otherwise
           | unreadable to most people. If they have a bug in their script
           | caused by this function not working correctly, good luck
           | finding it.
        
           | aloisdg wrote:
           | I am more and more on your side. If this function was a
           | builtin, how many reader will check its implementation?
        
             | throwamon wrote:
             | Totally agreed. While we're at it, let's make Brainfuck the
             | official POSIX shell language.
        
             | jteppinette wrote:
             | But it is not a builtin. Someone else is going to have to
             | maintain this one day.
             | 
             | > insert quote about writing your code as if the person who
             | will have to maintain it next is a violent psychopath who
             | knows where you live
        
               | adhesive_wombat wrote:
               | This maybe true even if the next person to maintain that
               | is yourself! I have certainly wished terrible vengeance
               | to be visited on past me.
        
           | chasil wrote:
           | Ideally, the function is POSIX-compatible, so it runs on the
           | widest number of platforms.
           | 
           | Why do we want to adhere to POSIX?                 $ man bash
           | | grep slow              It's too big and too slow.
           | $ rpm -qi dash | tail -3       DASH is a POSIX-compliant
           | implementation of /bin/sh that aims to be as small as
           | possible. It does this without sacrificing speed where
           | possible. In fact, it is       significantly faster than bash
           | (the GNU Bourne-Again SHell) for most tasks.
           | 
           | So let's find out how this function works in dash.
           | $ ./testtrim       ./testtrim            $ sed -i
           | 's/dash/bash/' testtrim                 $ ./testtrim
           | foo bar
           | 
           | I think I will pass.
        
             | bewuethr wrote:
             | There is https://github.com/dylanaraps/pure-sh-bible,
             | including a trim function.
        
               | chasil wrote:
               | That is a better resource.
               | 
               | The two important places for portability are Ubuntu's
               | /bin/sh (which is dash, not bash), and the Busybox shell.
               | 
               | Commercial unix would be important, but is likely a
               | distant 3rd by the numbers.
        
             | mkdirp wrote:
             | > Ideally, the function is POSIX-compatible, so it runs on
             | the widest number of platforms.
             | 
             | But... Why? During my professional career of about 10
             | years, and even before that, I've not once had to require
             | POSIX compatibility for any of the shell scripts I've
             | written or come across. The few times I had a snippet that
             | couldn't run I have been able to install bash 4+ with ease.
             | 
             | I'm sure there are times where POSIX is kind of needed, but
             | it's becoming exceedingly rare.
        
               | pavon wrote:
               | I can't think of any time where I have needed the same
               | script to run on multiple systems, because that's not the
               | sort of thing I use shell scripts for. But there are many
               | times where I have needed to write a script for a
               | specific system that was running busybox or dash or ksh,
               | and it is worth _knowing_ what features I can use in
               | those cases.
        
               | chasil wrote:
               | I have a Korn shell script that I use to run SQL against
               | a few dozen databases.
               | 
               | I recently rewrote this script, so it would run on
               | Windows, via Busybox ash. It needed quite a few changes.
               | I've become somewhat practiced on the removal of
               | bashisms.
               | 
               | Oddly enough I had to put a few back. Busybox on Windows
               | doesn't implement stty that I needed to read a password,
               | but it did have read -s, so I used that instead. I threw
               | several snippets of ash-emulated bash back in, that would
               | never ever run on dash.
               | 
               | When you ask "but why?" this is precisely why - I need
               | this functionality in a specific place, where you cannot
               | go.
        
               | _jal wrote:
               | The Linux monoculture in internet services does reduce
               | the value of POSIX-compliance.
               | 
               | I got in the habit of at least gesturing towards POSIX
               | back when it was more common to run a bunch of different
               | unixes. And I still run both FreeBSD and Linux at home,
               | so there's value there for me.
               | 
               | Mostly, I still do it because I'm always surprised by
               | which artifacts I create end up being long-lived, and you
               | never know what will be valuable in the future. One of
               | the things I'm technically proudest of ended up only
               | being useful for less than a year, whereas I know a dumb
               | 4 line hack I wrote on a contract in 2002 is still
               | running via cron every night, now on a VM in AWS.
        
               | chasil wrote:
               | I think it would be helpful if we can update the POSIX
               | shell standard. This is the only way that the
               | Debian/Ubuntu /bin/sh will ever change.
               | 
               | Microsoft was pivotal in the formation of the standard,
               | as Korn was required to run in a 64k text segment for
               | Xenix, and this was retained for POSIX.2.
               | 
               | The parser for the Borne family is very complex, and
               | cannot be implemented with a yacc grammar. There is some
               | value in starting again with something less convoluted.
               | 
               | This guy tried to implement a POSIX shell in OCaml, and
               | he is rather perturbed with the entire Borne family (I
               | wish I knew parsers this well):
               | 
               | https://m.youtube.com/watch?v=fiJR4_059HA
               | 
               | Bash has a number of real strikes against it... GPLv3 -
               | which caused Apple to dump it, speed - which caused
               | Debian/Ubuntu to demote it, and the lingering damage
               | bashisms and their damage to portability.
        
         | lubesGordi wrote:
         | Bash syntax is so alien. The sentence before your example: "The
         | : built-in is used in place of a temporary variable." So I was
         | like wtf even before you spit your drink. Maybe someone can
         | claim there's efficiency here?
        
         | freddref wrote:
         | It gets more readable the more often you read it
        
         | avgcorrection wrote:
         | String substitution (or whatever it is called?) looks so bad in
         | Bash. Similar to the sigils for history expansion. I'll just
         | stick to Up, Down, and Ctrl+R.
        
         | [deleted]
        
         | jamil7 wrote:
         | Yeah that's pretty wild. This resource pops up here a bit and
         | it's cool but there's always a point where I'm like why would I
         | do this in Bash and not Python/Ruby or something else.
        
           | adhesive_wombat wrote:
           | I have found my life has improved where as soon as I can't
           | find the answer to a "wtf how do I do this trivial in shell"
           | question after a cursory search, it's a good time to stop,
           | and seriously consider Python (or Perl, ok, ok).
           | 
           | Sometimes, it's genuinely better to plug on in shell (e.g. if
           | you are just calling other scripts and chaining stuff), but,
           | especially if you want some less-magical string or list
           | manipulations, often Python/Perl will provide a more
           | readable, more maintainable, more _testable_ script. YMMV
           | with Perl.
        
       | ChrisArchitect wrote:
       | Plenty of previous discussion:
       | 
       |  _1 year ago_ https://news.ycombinator.com/item?id=24827360
       | 
       |  _2 years ago_ https://news.ycombinator.com/item?id=21013150
        
       | woudsma wrote:
       | Nice to see that the author uses Shellcheck. There is a very nice
       | Shellcheck VS Code extension that links examples of good/bad
       | practices when writing Bash. I can definitely recommend using it
       | if you're writing Bash scripts!
        
       ___________________________________________________________________
       (page generated 2022-02-16 23:00 UTC)