[HN Gopher] The Case for Bash (2021)
___________________________________________________________________
The Case for Bash (2021)
Author : memalign
Score : 90 points
Date : 2023-05-18 08:09 UTC (14 hours ago)
(HTM) web link (www.neversaw.us)
(TXT) w3m dump (www.neversaw.us)
| rfittich wrote:
| I think this perspective is essential in our ever-evolving tech
| industry. Bash, despite its quirks and often steep learning
| curve, has its niche in our toolset.
|
| Its power lies in its simplicity and direct access to system
| level functions, which makes it an efficient tool for system
| administrators and developers working in DevOps. It's excellent
| for automating small to medium-sized tasks on UNIX-like systems
| where the overhead of a full-fledged language would be overkill.
|
| While it's true that bash has its limitations, the value of its
| ubiquity cannot be overstated. The bash shell is everywhere -
| from massive server clusters to tiny embedded systems. This means
| that a bash script written on one system is very likely to work
| unchanged on another.
| csdvrx wrote:
| > the value of its ubiquity cannot be overstated
|
| TBH it's among the many reasons I've return to bash from zsh
|
| I want to experience first hand the limitations I may hit on
| other servers.
|
| I also try to use #!/bin/ash in my scripts to live life in hard
| mode :)
| jagged-chisel wrote:
| > It coordinates programs...
|
| Sounds like a case for shells in general. No other script-
| execution tools make running other programs (and linking their
| inputs and outputs) so simple.
|
| To overcome Bash's problems, one can choose another shell. But I
| suppose you can't just pick your personal favorite and script in
| its dialect, because then how would the human tasked with
| integrating the script into $wherever know which shells to have
| installed? You can stick with sh which is guaranteed to be
| installed, or bash (indeed an improvement over sh) which is
| nearly guaranteed to be installed.
| mrspuratic wrote:
| More than a decade ago I needed a multi-platform way to manage
| Nagios client data collection (mostly) using whatever native
| tools were available, so I wrote one. bash, gawk and send_nsca
| were the only 3 binaries needed, and it ran well on 10
| different *nixs (free and commercial) on Alpha, ARM, MIPS,
| SPARC, X86 and X86_64 platforms.
|
| Of course, after a decade of incremental tinkering I ended up
| with exactly what you anecdon't want: ~2500 lines of shell
| script and ~1000 lines of awk... LOC misleads of course, there
| were 15 modular plugins, so there was a lot of boilerplate, and
| this includes non-runtime ~1000 lines for install, self-test
| and sanity checks.
| JdeBP wrote:
| Or one can learn the lessons that Debian learned over a decade
| ago, and Ubuntu almost two decades ago, about bashisms,
| maintainability, and performance; and script in at most the
| Debian Almquist shell, whatever fancy shell one may be using
| interactively.
|
| * https://wiki.ubuntu.com/DashAsBinSh
|
| * https://wiki.ubuntu.com/DashAsBinSh/Spec
|
| *
| https://wiki.debian.org/BootProcessSpeedup#Using_a_faster_sy...
|
| * https://lists.debian.org/debian-
| release/2007/07/msg00027.htm...
|
| * https://lwn.net/Articles/343924/
|
| * https://www.debian.org/doc/manuals/debian-
| reference/ch12.en....
| rascul wrote:
| Interesting that efficiency is cited as the main reason in
| several of those links. And here I see that dash starts up
| only .001 seconds faster then bash. Maybe things were
| different 15 years ago, I don't know.
|
| The other concerns seem to have a very simple solution: use
| bash in the shebang instead of sh if your script uses
| bashisms.
| JdeBP wrote:
| That was one of the counterarguments to a common straw man
| of the time. Changing the interpreter line was a valid
| route. If you choose to use Bashisms, the counterargument
| went, you just make that choice explicit; just as people
| who used Korn/Z/whatever shell idiosyncrasies already had
| to.
|
| As for efficiency, recall that there were hundreds of
| /bin/sh scripts in startup, administration, and everyday
| operation of the system, from all of the /etc/rc.d/
| (sub)scripts through things in cron and build systems and
| package install/deinstall scripts to bunches of commands
| that were /bin/sh scripts under the covers. So multiply
| that difference by several orders of magnitude.
|
| Amusingly, this is to a major extent still true. On these
| operating systems systemd is nowadays parsing .INI files
| over and over with its own custom .INI file parser, instead
| of a chosen flavour of /bin/sh parsing shell scripts over
| and over with whatever (Bison/YACC) parser they were using.
| They haven't actually gone down the SunOS SMF (and s6)
| route of compiling things into a machine-readable database.
| And there are still lots of /bin/sh scripts elsewhere, as
| service management is only one of several areas.
|
| An interesting alternate history would have been if the Z
| shell had been /bin/sh on Debian and Ubuntu instead of the
| Bourne Again shell when this came up, and how much of a
| difference employing zcompile everywhere would have made.
| rascul wrote:
| > As for efficiency, recall that there were hundreds of
| /bin/sh scripts in startup, administration, and everyday
| operation of the system, from all of the /etc/rc.d/
| (sub)scripts through things in cron and build systems and
| package install/deinstall scripts to bunches of commands
| that were /bin/sh scripts under the covers. So multiply
| that difference by several orders of magnitude.
|
| And one of the links leads to a savings of 1 second on an
| eeepc. Not very convincing.
|
| https://wiki.debian.org/DebianEeePC/Dash
| lloeki wrote:
| > The Python and Ruby versions would be similar
|
| Not Ruby! sh = Shell.cd('/') sh.transact do
| system('tail -fq /var/log/nginx/access.log') | system("awk
| '{print $7}" | system("sort") | system("uniq -c") | system("sort
| -rn") end
|
| Pretty sure one could get without the system method with Shell
| having def method_missing(meth, * args) to call
| system([meth.to_s, * args]) or something, turning it into:
| sh.transact do tail '-fq' '/var/log/nginx/access.log' |
| awk '{print $7}' | sort | uniq '-c' | sort '-rn' end
|
| https://github.com/ruby/shell#pipe-etcprintcap-into-a-file
| deafpolygon wrote:
| Bash is a shell. Learn the shell, and you "learn" bash.
| DonHopkins wrote:
| At the risk of being accused of bash bashing, I'll throw down
| that bash is a weak ineffective shell. A "shell" can and should
| be so much more than all bash has to offer.
|
| The much earlier more powerful ITS (Incompatible Timesharing
| System) shell DDT (whose job name was HACTRN) had an integrated
| PDP-10 machine language debugger / assembler / disassembler, so
| you could interactively or batch "script" and patch DDT and
| even other jobs in full blown PDP-10 assembly language.
|
| Why invent yet another half assed "scripting" language that no
| other jobs in the system are using, when you can use the same
| fully powerful machine language that every job in the system is
| using? And if you need to do anything complicated, there's
| always LISP!
|
| DDT's syntax was even more obscure than bash (and only a bit
| less obscure than TECO), but it was much more powerful and
| elegant, unleashing the full undiluted power of the PDP-10 at
| your fingertips.
|
| https://github.com/PDP-10/its/blob/master/doc/_info_/ddtord....
|
| You could also write DDT commands in text files like your login
| file, i.e. assembling a few lines of code to print the prompt
| by making a system call to get the time and format it as text.
|
| You could examine and deposit code and data, load and change
| symbols, set breakpoints, in your own and even other user's
| running jobs (processes)!
|
| You could disconnect without logging out (accidentally or not)
| and all your jobs would stay around until you logged back in,
| at which time you could reattach your job tree and continue
| what you were doing, all without running something like
| "screen" -- that crucial feature was just built in and always
| worked.
|
| You could also pass ownership of jobs (like a running ZORK game
| or LISP interpreter or FOOBAR feeper) back and forth between
| users to share, like passing a joint. ;)
|
| https://news.ycombinator.com/item?id=22840639
|
| >It helped that ITS had no security whatsoever! But it had some
| very obscure commands, like $$^R (literally: two escapes
| followed by a control-R).
|
| >There was an obscure symbol that went with it called "DPSTOK"
| ("DePoSiT OK", presumably) that, if you set it to -1, allowed
| you to type $$^R to mess with other people's jobs, dynamically
| patch their code, etc. (The DDT top level shell had a built-in
| assembler/debugger, and anyone could read anybody else's job's
| memory, but you needed to use $$^R to enable writing).
|
| http://www.poppyfields.net/filks/00117.html
|
| The HACTRN Original song: The Raven
| Original artist: Edgar Allan Poe Filk author: Guy L.
| Steele Jr. Intro: Notes for those not familar with the
| terms in this poem -- see below
|
| [...]
|
| DDT ("dee dee tee")
|
| HACTRN ("hack-tran") = top level debugging and job controlling
| procedure, capable of controlling up to eight simultaneous jobs
| (which may themselves be DDTs!) and performing other
| miscellaneous functions. HACTRN specifically denotes a DDT at
| the top of a job tree, while DDT is the more general term. The
| two terms refer to the same job in the poem, and are thus
| treated as synonymous. Note that DDT requires its subjobs to
| have unique names for obvious reasons; hence the concern over
| seven jobs all named FOO.
| hello_computer wrote:
| Several of these sound like anti-features. Others are OS
| issues and have no bearing on the shell (i.e. ownership hot-
| swap). The ones that are useful have already been solved by
| other programs (screen, gdb, et al). What is the advantage of
| having it all packed inside the same executable?
| deafpolygon wrote:
| > And if you need to do anything complicated, there's always
| LISP!
|
| Are you an Emacser?
| sigmonsays wrote:
| it seems like most people that have dislike bash never spent the
| time to learn it.
|
| I have a love/hate relationship with is. I started with computers
| in 2000 and wrote a ton of bash for various things. Compiling
| software, running cicd, adhoc batch jobs, etc.
|
| I've managed many cicd pipelines with bash in my time. While it's
| not great, once you know the basics, you can be very successful.
| That being said, rewriting the bash "program" in another language
| is much advised. If your bash is over a few hundred lines,
| chances are you've outgrown it
|
| Some things in bash (mainly pipes and redirection) are just too
| easy. Job control is also great. The 'process' and 'shell script'
| are two primitives that make a lot possible.
|
| Trying to do pipes or redirection in python is awful. There are a
| ton of subtle bugs you have to worry about
| bluepizza wrote:
| Seems like you spent the time to learn it and still dislike it?
| JdeBP wrote:
| The article is a bit confused about whether it's making a case
| for shell scripting in general, or for the Bourne Again shell in
| particular. By the looks of things, its target readership is
| people who don't use shell scripting, or interactive shells, _at
| all_ ; so the former case would be more appropriate, and the
| drawing of a distinction between the Bourne Again, Friendly
| Interactive, Z, and other shells just muddies the waters for that
| readership.
| cwingrav wrote:
| BASH is like Obi Wan. It isn't the most powerful or flashiest,
| but it survived a long time, where others didn't, for very good
| reasons. Bash runs basically everywhere. It has many modern
| features you wouldn't expect. Its syntax is literally what you
| would type on the command line if you were diagnosing or fixing
| systems so you don't need to transpile to another language. Its
| reliance on other programs means it is glue and can easily
| incorporate highly cohesive functionality/tools others write and
| maintain. Also, it's been around and is everywhere so you don't
| worry about trying to incorporate the current latest and greatest
| declarative tool (which will blow over in 5 years) into your
| other workflows. Basically, don't disparage a Jedi/tool that has
| survived where others didn't. There is a reason.
| cwingrav wrote:
| Also, use shellcheck. Incorporate it into you editor. Fix all
| warning and don't ignore them. This will push you deep into
| bash syntax rabbit holes but you come out better the other
| side.
| ndsipa_pomu wrote:
| Also, familiarise yourself with
| https://mywiki.wooledge.org/BashPitfalls
| blueflow wrote:
| Find the problem: echo "$(tr -dc A-Za-z0-9
| </dev/urandom | dd count=1 bs=16 2>/dev/null)" ^--
| SC2005 (style): Useless echo? Instead of 'echo $(cmd)', just
| use 'cmd'.
|
| I have experienced so many situations where shellcheck is
| giving harmful advice or warns me about the thing that is
| exactly my intention.
| rascul wrote:
| I would probably do it this way:
|
| tr -dc A-Za-z0-9 </dev/urandom | dd count=1 bs=16
| 2>/dev/null; echo
|
| A few less characters to type, you get your newline, and
| shellcheck doesn't complain.
| ndsipa_pomu wrote:
| Using "echo" at all is a problem. It's recommended to
| switch to "printf" instead as echo has unfixable problems,
| especially with strings that start with a dash.
| printf "%s\n" "$(tr -dc A-Za-z0-9 </dev/urandom | dd
| count=1 bs=16 2>/dev/null)"
|
| If you don't require the line feed, then you can just use:
| tr -dc A-Za-z0-9 </dev/urandom | dd count=1 bs=16
| 2>/dev/null
| blueflow wrote:
| The thing with echo is repeated again and again but not a
| problem in the code i've just posted (due to A-Za-z0-9).
|
| And i do require the line feed. Following shellcheck's
| advice broke the code.
| ndsipa_pomu wrote:
| I'd also add that in the cases where you disagree with
| shellcheck (it doesn't get everything correct all the
| time), you can include a disabling comment just before
| the line to tell shellcheck that you know best:
|
| # shellcheck disable=SC2005
| ndsipa_pomu wrote:
| Not a problem until the random string starts with a dash
| and you get unexpected results from "echo" interpreting
| it as an option instead of an argument. Using "printf"
| bypasses that issue as it's clear what the argument is.
|
| Just tested it and ShellCheck is happy with the printf
| version: printf "%s\n" "$(tr -dc
| A-Za-z0-9 </dev/urandom | dd count=1 bs=16 2>/dev/null)"
|
| It's also got a stylistic improvement (in my opinion,
| anyhow) in that the line feed is explicit in the printf
| command rather than being almost a side effect of echo.
|
| Edit: I see your point about the "tr" not enabling a
| dash, so my example falls a bit flat, but my point stands
| in other scenarios. It's good practise to avoid echo
| where feasible. I think the double quotes will also
| protect in this instance. The problem with relying on the
| tr string to not foul up echo is that you may later adapt
| the code and use a different translate string which could
| then introduce a tricky bug to track down.
| [deleted]
| xorcist wrote:
| The style issue shellcheck reports here is probably what we
| both suspect it is.
|
| The call to echo has a likely purpose is to trim some
| spaces from a string, but it's not at all obvious why this
| is done or what the benefit is. In the best case, it leaves
| the reader pondering this weird semi-no-op.
|
| If you think shellcheck, and probably most readers, is
| wrong in this assertion, just speak your mind and let's
| learn from one another. But I certainly can't guess your
| intention here.
| saagarjha wrote:
| ...what's the problem?
| cwingrav wrote:
| A lot of bash errors are not understanding possible cases due
| to white space.. which shellcheck catches. After using it for
| a while, I don't even really worry about white space because
| of the good habits I've learned/(been forced to use).
| ndsipa_pomu wrote:
| That's all well and good until you come across a filename
| with a linefeed in it - null termination is where it's at!
|
| (I can't actually recall encountering a filename that
| includes a linefeed)
| Joker_vD wrote:
| I've got several empty files on my desktop (on Windows)
| serving as sticky notes of some sort, and they have line
| breaks in their names, obviously.
| ndsipa_pomu wrote:
| I didn't even know that Windows supported that, but I try
| to keep away from it as much as possible. Makes for an
| interesting test of scripts, I suppose. Sometimes, I
| script BASH to cope with any any filenames, but it
| depends on the usage as a lot of the time you can
| guarantee that files will be at least semi-sensible.
| rascul wrote:
| Also maybe check out the bash language server.
|
| https://github.com/bash-lsp/bash-language-server/
| ghostbrainalpha wrote:
| So if Bash is like Obi Wan surviving where other didn't....
|
| Is Bash just surviving because no one knows about it or has
| remembers it while its been hiding in your system for 20 years?
| paulddraper wrote:
| Also, what will it be like as a Force ghost?
| pjc50 wrote:
| The only real advantage of bash (or other shells) is the ability
| to build up to it from the command line; to use it as a REPL then
| embed the stuff you've just done into a script.
|
| The massive disadvantage of bash is that it uses a legal filename
| character " " as a delimiter ("$IFS"). That means it's very easy
| to write scripts which work fine on your test case but blow up in
| a different context. And the worst case of that is accidentally
| deleting the user's file system.
|
| So many of the cute little bash examples you'll see, including I
| think the awk one on this page, will go wrong if you have a space
| in the wrong place in your filesystem. Or, god help you, a
| newline. Or a file named "*". Or "--".
| JdeBP wrote:
| Or, put another way:
|
| Getting the 10% of the cases that have whitespace or
| metacharacters in variable values and filenames to work ...
| takes the other 90% of the time. (-:
|
| I habitually quote variable expansions, even when I _know_ that
| the variables are never going to contain whitespace. Because
| long experience has taught me that one day they will.
|
| Just like I've learned never to assume that ${PATH} is always
| non-blank and so assume that PATH="${PATH}:/something" won't
| accidentally add the current directory to my search path. (-:
| SAI_Peregrinus wrote:
| /This name iss a valid POSIX /--file path
| rascul wrote:
| It might be nice to be more restrictive about what can be
| in a filename. I'm sure there would be a lot of different
| opinions though.
| 9dev wrote:
| Or, you know, it would be nice to have a shell that
| didn't assume everyone lives in North America and speaks
| only a single language..?
|
| Lots of things written more recently have shown that
| support for more, eh, inclusive, character encodings can
| work just fine.
| stcroixx wrote:
| Hm, I write bash scripts routinely and never do it that way.
| Always develop and run my scripts as files, starting with 'set
| -x' if I need debug info. I keep interactive mode solely for
| command line work, not development of scripts I plan to from
| files.
| wolletd wrote:
| I guess the URL path in the Nginx log would be URL-encoded and
| have a %20 instead of a space. And otherwise, it would actually
| also a problem of that text based log format that uses spaces
| as field delimiters itself.
|
| Anyway: When I can "build up from the command line", then
| apparently whatever I'm building up can be easily and
| intuitively done in the command line. So, stuffing it into a
| bash script is fast and easy and should be easy to understand
| as well.
|
| I just have real-world applications for small scripts that
| aren't much bigger than those "cute little bash examples". When
| you work with embedded systems, you do a lot of repeatable
| stuff via SSH. I once ported an Installer to Python and now I
| hate it because it has so much unhelpful noise between the
| actual relevant commands being executed.
|
| Yes, Bash has it's issues and requires some discipline, but so
| do most other languages.
| d0mine wrote:
| > A lot of repeatable stuff via SSH
|
| It looks like a use-case for fabric
| https://docs.fabfile.org/en/stable/getting-
| started.html#adde... It is the best of both worlds: shell
| pipeline for one-liners, Python -- for complex logic.
|
| Or if more declarative approach works in you case then
| something like ansible could help https://docs.ansible.com/an
| sible/latest/getting_started/inde...
| hereonout2 wrote:
| I spent my entire career avoiding file paths with spaces in.
|
| On the very rare occasions I'm using an external dataset that
| includes them I'll make a copy with renamed files using
| underscores.
|
| If more junior team members produce files with spaces in their
| paths I quickly educate them in how problematic it can be.
|
| It's pretty rare this is a problem for me or my team, perhaps
| we're lucky in what we work on though.
|
| Thankfully I have never seen a file named "*" or "--".
| ndsipa_pomu wrote:
| I too often avoid spaces in filenames, but when writing
| scripts it's far better to ensure that you cope with them
| properly. The trick is to always quote your variables by
| default and then run shellcheck on your script so that it can
| flag up the corner cases where quoting acts to unquote the
| string. Of course, it'll also flag up a host of other
| possible issues which are well worth fixing or at least
| understanding why it's a possible issue.
|
| Another common footgun is not including a double dash ('--')
| at the end of command options so that the following filename
| won't be interpreted as an option when it begins with a dash.
| vram22 wrote:
| >Another common footgun is not including a double dash
| ('--') at the end of command options so that the following
| filename won't be interpreted as an option when it begins
| with a dash.
|
| Yes. And if you have a file name that begins with a dash,
| and you want to delete it, you can use this command:
|
| $ rm -- -filename
|
| where -filename is that file. Here, the -- (double dash)
| means "end of the command-line options", so any argument
| after that is treated as a non-option argument, in this
| case, a filename for rm to delete.
|
| This -- (double dash) works with many Unix commands. It was
| introduced relatively early on in Unix history, after the
| issue of filenames starting with a dash was found.
|
| Although it is more likely that you would want to rename
| the file, to remove the dash from the name.
| throwaway858 wrote:
| If you ever need to use GNU make (still a popular tool)
| then you will be glad that you kept a policy of avoiding
| spaces in file names.
|
| There are places in Makefiles where no amount of quoting
| will help you, and it simply cannot handle files with
| spaces.
|
| Yeah, this is a problem with the tool that should be fixed,
| but my understanding is that it will never be fixed because
| of architectural reasons. And it's a very popular, useful,
| and most importantly, ubiquitous tool.
|
| So this is another good reason to simply have a policy of
| banning filenames with spaces (and there are many more
| reasons).
| munificent wrote:
| Having to completely change the naming scheme you use for
| human-authored and human-read artifacts entirely to route
| around shitting, confusing escaping in a programming language
| is not a convincing selling point for that language.
|
| If you have a file whose contents are Shakespeare's "As You
| Like It", you should be able to name that file "As You Like
| It" without having to worry that the computer will vomit and
| die on it. We deserve better tools.
| Joker_vD wrote:
| Quotes, dot-slash, quotes, double dash and quotes. Quotes,
| quotes, shellcheck and quotes. Quotes, quotes, quotes, lovely
| quotes!
|
| Just don't write bugs, what's so hard about shell programming?
| EuAndreh wrote:
| Just shellcheck is enough.
| ndsipa_pomu wrote:
| Shellcheck won't catch the missing dashes ('--') at the end
| of command options, so you could be in trouble if a
| variable starts with a dash and the command interprets it
| as an option rather than the filename. It's not
| particularly obvious, but if people can upload a file and
| specify its name, then they could compromise a script by
| choosing a suitably evil name. If you get into a habit of
| putting '--' at the end of the options and before the
| filename variable, then you protect against that.
| augustk wrote:
| This article is not specifically about Bash, but about the shell
| command language sh. The POSIX Shell is a standardized subset of
| Bash which has even better portability. I would recommend
| learning and using sh unless you really need Bash.
|
| https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...
|
| Your script will use sh if it starts with #!/bin/sh (instead of
| #!/bin/bash).
|
| I can also recommend ShellCheck which is a shell script analysis
| tool (implemented in Haskell) which can find errors and potential
| problems in your scripts. On a Debian system, installing
| ShellScheck is as simple as `sudo apt install shellcheck'.
| ndsipa_pomu wrote:
| I usually target BASHv3 in my scripts, but then I know the
| environment that will be using those scripts. My biggest issue
| with POSIX is the use of the backtick which is difficult to
| read and parse.
|
| ShellCheck is absolutely the most important thing to use when
| writing scripts. Each time that you get a warning that you
| don't recognise is a learning opportunity - just follow the
| link provided in the warning. Also, take the time to add the "#
| shellcheck disable=" comments so that scripts don't issue any
| warnings from shellcheck.
|
| I also recommend visiting https://mywiki.wooledge.org/BashFAQ
| for avoiding the many footguns, especially with filename
| parsing.
| rascul wrote:
| > My biggest issue with POSIX is the use of the backtick
| which is difficult to read and parse.
|
| POSIX also has $(command) for command substitution. It can
| certainly be annoying when it's not used, though. I think
| shellcheck will recommend it over backticks.
| ndsipa_pomu wrote:
| Thanks, I didn't know that, but then I almost never target
| POSIX. My next complaint would be the use of '[' as a test
| rather than my preferred '[['.
|
| Edit: After looking for a problem with POSIX, I found this
| obscure issue that may well catch out people as under
| POSIX, IFS is a terminator rather than a separator:
| https://mywiki.wooledge.org/BashPitfalls#IFS.3D.2C_read_-
| ra_...
| augustk wrote:
| > My biggest issue with POSIX is the use of the backtick
| which is difficult to read and parse.
|
| I always use $(...) or rather "$(...)" instead of backticks.
| Command substitution shall occur when the command is enclosed
| as follows: $(command) or (backquoted
| version): `command`
|
| https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V.
| ..
| dspillett wrote:
| _> The POSIX Shell is a standardized subset of Bash which has
| even better portability._
|
| It would be much more correct to say that bash's features are a
| superset of the shell features standardised by the POSIX
| standard, as is the case for several other shells (each adding
| their own parts on top of the standard) too.
| everybodyknows wrote:
| > This article is not specifically about Bash, but about the
| shell command language sh.
|
| Exactly. The title is just plain _wrong_. Furthermore, TFA does
| not argue a "case", it simply tries to specify the language.
| VWWHFSfQ wrote:
| > I would recommend learning and using sh unless you really
| need Bash.
|
| Nah I like using bash features and all the systems that I care
| about have /bin/bash so it doesn't matter.
| spyremeown wrote:
| >I would recommend learning and using sh unless you really need
| Bash.
|
| I don't buy this argument. Ok, it's a standard, but sometimes
| it's a pain-in-the-hole standard. Bash augmentations lessen
| some of the pains, and it's just nicer. The only situation is
| if you're using busybox in a very limited system or you
| reeeeeally need your script to run on many difference unices,
| which let's be honest, is not that common nowadays.
| kaba0 wrote:
| > Bash augmentations lessen some of the pains, and it's just
| nicer
|
| Both sh and bash are terrible, ugly hacks. Anything that
| requires more than 3 lines of them (including the #! line)
| should be written in a proper scripting language.
|
| Though I do agree that cross-platformity to that level is
| rarely meaningful, and so things like python are just as
| likely available/can be made available.
| wvh wrote:
| My system Python tree is almost 1GB. That doesn't matter
| for desktop systems, but most software is published as
| container images these days and using a language like
| Python, Ruby or Perl for an image that doesn't already need
| it is pretty wasteful and pulls in a lot of extra
| dependencies.
|
| I'm not sure there is a good alternative to sh/bash shell
| scripts as most dynamic languages have become pretty large
| dependencies these days.
| kaba0 wrote:
| That surely includes plenty of globally installed
| dependencies. I looked at the package sizes for debian
| and it is around 100 kB for the python3 package and on
| the order of another 100kb for python3-minimal. Couldn't
| find a cumulative install size, but it is surely not
| larger than a few megabytes.
| CamJN wrote:
| Just span up a clean alpine linux container and installed
| python3, it added 51MB according to apk.
| sgarland wrote:
| Until someone decides to write something that's only
| available in X version of Python. While there are certainly
| v4 and v5 bash-isms, they are far and few between compared
| to most languages.
|
| ...that said, having to support bash 3.2 for MacOS is a
| horrible thing.
| ndsipa_pomu wrote:
| Which version of python though?
| kaba0 wrote:
| Add a flake.nix file and you get completely reproducible
| program versions if you really want.
|
| But I know that you meant it as a rhetoric, so my non-
| rhetorical answer would be that python3 is almost
| universally available on distros that are not minified
| deliberately (containers).
| ndsipa_pomu wrote:
| > python3 is almost universally available on distros that
| are not minified deliberately (containers)
|
| Writing control scripts for use inside containers is
| currently my biggest application of BASH scripts. What
| makes BASH (or other shells) handy is the lack of
| supporting files that are needed - just copy in the
| script and you're ready to go.
| time0ut wrote:
| I was going to say something similar. I try to avoid
| adding anything to my final images. Each extra dependency
| is something else to update, more surface areas for
| attacks, another thing to justify, etc. Much rather just
| use the slimmest base and the tools already available.
| paulddraper wrote:
| 3
|
| Which version of Bash?
| Izkata wrote:
| The various sub-versions of bash are a lot more
| compatible than the sub-versions of python 3. Just today
| stuff was breaking on me because of differences between
| python 3.6 and 3.8
| synergy20 wrote:
| I do small embedded systems with busybox, even that I can
| squeeze in bash when I need that, it's about 1MB in size and
| gives a lot more than busybox's sh. Another option is Lua
| which is also great.
| blueflow wrote:
| > is not that common nowadays
|
| Due to docker, minimalistic Linux'es have been more common,
| including trimmed-down versions of distros that would
| otherwise feature bash.
| synergy20 wrote:
| bash is rarely the focus though, it really just costs 1MB
| in storage, which is nothing comparing to python,etc.
| 9dev wrote:
| Well, usually I have to decide between ,,do I look up the
| magic incantation to install bash in this container and
| risk fucking up the layer cache" or ,,do I modify this
| script to not use bash-isms and feel like I'm a Unix
| purist in the process", and the answer is the latter
| usually
| paulddraper wrote:
| Nonetheless Bash is very frequently omitted in my
| experience.
| JdeBP wrote:
| All of this was covered in great detail in the 2000s, when
| Debian and Ubuntu switched /bin/sh to the Debian Almquist
| shell, which was basically POSIX-only with some 3 things that
| Debian people simply couldn't live without, and encouraged
| system scripts to use it. If you weren't around then, go and
| read the discussions. They're mostly still available, and
| they cover some important stuff that straw man
| counterarguments regularly miss.
|
| The Debian people were concerned, for starters, with how much
| time the Bourne Again shell spent, at process initialization,
| setting up things for extensions and interactive features
| that were never employed in non-interactive "sh" mode; a
| significant cause for concern given how much of the system
| was executable shell scripts.
| jmclnx wrote:
| >with some 3 things that Debian people simply couldn't live
| without
|
| Curious, what are the 3 things ?
|
| But yes, people should always use sh (or ksh) for scripting
| as opposed to bash, why, it is far more portable to other
| systems.
| JdeBP wrote:
| Originally it was echo -n, local, and logical operators
| in test. There was just so much Debian stuff that assumed
| these.
|
| * https://bugs.debian.org/cgi-
| bin/bugreport.cgi?bug=294962
|
| They've added 2 more since.
|
| * https://www.debian.org/doc/debian-policy/ch-
| files.html#scrip...
|
| Strictly speaking, there are other differences between
| the Debian Almquist shell and a truly SUS conformant sh.
|
| * https://unix.stackexchange.com/q/697007/5132
|
| But the aforementioned are what Debian people explicitly
| wanted and couldn't live without. Note that the
| StackExchange answer is a comparison of a 2022 dash to a
| 2017 standard, neither of which existed at the time.
| Debian Policy, the Debian Almquist shell, and the POSIX
| standard have all been revised since then.
| latexr wrote:
| macOS and plenty of popular Linux distributions symlink /bin/sh
| to /bin/bash. Some link it to /bin/dash. There may be different
| ones.
|
| Meaning /bin/sh is _not_ more portable because you can't be
| sure which shell will be used.
| jsyolo wrote:
| Bash is POSiX compatible.
| augustk wrote:
| ShellCheck can check for POSIX compliance with the option
| `--shell sh', e.g. shellcheck --shell sh
| myscript.sh
| VWWHFSfQ wrote:
| Not only is it not more portable, POSIX doesn't even require
| that it exists at all. Applications should
| note that the standard PATH to the shell cannot be assumed to
| be either /bin/sh or /usr/bin/sh, and should be determined by
| interrogation of the PATH returned by getconf PATH, ensuring
| that the returned pathname is an absolute pathname and not a
| shell built-in.
|
| I don't know how this trend started but now it's been cargo-
| culted to death. Same with the /usr/bin/env thing in
| shebangs.
| shawabawa3 wrote:
| One use-case for /bin/sh over /bin/bash these days is that
| the alpine docker image (base image for a lot of docker
| images) has /bin/sh but not /bin/bash
| rascul wrote:
| I recommend learning bash if you know that bash is available
| for all your targets, since bash brings many niceties that sh
| doesn't have.
| justaj wrote:
| Some may have different Bash versions installed though.
| rascul wrote:
| That's easy to check for. sh implementations can vary also.
| justaj wrote:
| Does the POSIX implementation vary for sh though? AFAIK
| some interpreters choose to add some extras (like
| `local`), but all of them at the very minimum must adhere
| to the POSIX spec from what I've understood.
| rascul wrote:
| There are a couple examples in this stack overflow
| answer:
|
| https://stackoverflow.com/questions/11376975/is-there-a-
| mini...
| myhf wrote:
| > not specifically about Bash, but about the shell command
| language sh
|
| or as I've taken to calling it, Ba + sh
| shmerl wrote:
| Good points. But I wish Bash had better syntax and built in
| support for basic concepts like boolean logic. Try to compose
| some complex boolean expression in Bash and you will quickly hit
| problems.
| DonHopkins wrote:
| The only thing you need Bash for is to install Python.
| BirAdam wrote:
| I've written a ridiculous number of shell scripts to automate
| many many things. It's great for doing something now, and it's
| great as a way to interact with a machine. It is not great in all
| cases. Particularly: array handling is bad, it's slow if you
| start using actual Bashisms, very few younger devs seem to know
| it.
|
| The shell is great cuz it's there and it can cover about 50% of
| use cases for server side automation, but it's bad for the
| reasons mentioned above.
|
| I love it and I hate it.
| 666satanhimself wrote:
| [dead]
| badrabbit wrote:
| I feel like zsh is for pros maybe. I use Linux daily and write
| python and shellscripts. Zsh has been defaulted all over the
| place but all that meant for me is I have to figure out how to
| get it to do things the bash way once in a while.
|
| I see no reason why distros like ubuntu or kali would default to
| zsh.I use the shell for sysadmin stuff, anything complex or app
| specific gets at least a python treatment.
|
| The whole thing reminds me of python 2->3 or sysv init to
| systemd. There must be people somewhere deeply invested in these
| changes and their voice is certainly much more valuable than the
| average opensource joe user. Defaults matter and the time I and
| millions had to spend learning to transition for no direct
| benefit to us has value. The whole distro model of everyone
| getting a distro they like falls apart when not enough people can
| fork.
|
| Overall, this devalues opensource as an investment. Because of
| unpredictable hidden costs like this.
| todd8 wrote:
| I'm a computer scientist/software engineer that has used
| primarily Unix or Linux systems since the 80's. I write shell
| scripts occasionally, but I just find them error prone enough
| that I'd rather use python than sh for complex scripts. Python
| has some packages that make working with files, directories, and
| processes tolerable and at least I can understand the string
| quoting rules in python.
|
| Generally my order of preference for shell scripting tasks is:
| python > bash > pearl > tcl > sh > anything > AppleTalk.
| faeriechangling wrote:
| The thing that makes me loathe Bash more than anything else is
| it's 3 types are string, int, and list and those are not the only
| types of data I work with day to day.
| majkinetor wrote:
| Quality of the articles on the front page seems to be rapidly
| declining...
| Gualdrapo wrote:
| Font alone is so thin is unreadable. It's funny to say that in
| HN where fonts are so small too.
| msoad wrote:
| I ask chatgpt for bash scripts. So useful and every time I'm
| learning something new
| BoxOfRain wrote:
| ChatGPT is great for quickly getting the bones of a script but
| you still need to know bash reasonably well, ChatGPT will
| sometimes merrily write stuff that looks correct but is
| actually a foot-gun and that's not great when things like `rm`
| are involved.
| msoad wrote:
| I know enough bash to be able to spot those things. but I
| might forget how exactly `awk` should be used to split a
| string or such. So asking ChatGPT is a quick way of getting
| those things working...
| Danjoe4 wrote:
| ChatGPT excels at regex, awk, grep, etc.
| SPBS wrote:
| So it's both ubiquitous and a terse DSL for managing and
| coordinating programs. Yeah I agree. Also if you're on Windows
| it's nice that PowerShell is always preinstalled and serves the
| same purpose.
| vram22 wrote:
| IMHO, the best resource to learn about both Unix shell usage at
| the command-line prompt, and shell programming in .sh script
| files, is still the book "The Unix Programming Environment" by
| Kernighan and Pike, except for shell gotchas and subtleties which
| were discovered later.
|
| Of course, they still would not have covered all possible issues
| known even at that time, because that was not the focus of the
| book, which was to be a Unix tutorial, not just on shell, but
| many other commands, general Unix usage, and the environment too
| (hence the title of the book).
|
| But they did cover and warn about some issues, including giving
| solutions.
| stanleydrew wrote:
| This argument isn't very compelling. Shell scripts are great at
| tricking you into believing you've got something 100% working
| when in fact you've only accounted for the happy path and maybe
| two or three failure cases. This is the primary reason shell
| scripts are so often broken. There are tons of assumptions baked
| in which are easily violated.
|
| If your shell script keeps breaking, and you keep fixing it by
| writing more shell, then you're in an abusive relationship with
| your programming environment.
| pgtan wrote:
| Well, Kornshell (ksh93) has some nice programming features, much
| better than bash.
| jquast wrote:
| We should have better local shells that "drive" remote sh/bash
| shells through transpilation, so that we can have modern shells
| anywhere without concern for remote install, access to install or
| compile, compatibility, carrying customizations, etc.
| BoardsOfCanada wrote:
| Maybe this already exists, but I imagine if someone wrote at
| library for interacting with gnu or posix commands from python
| (or ruby, or...) that built up the commands in a structured way
| and parsed the replies and put them in a dict, that would be very
| nice to use instead of bash-scripts. Every weird thing that you
| wanted to do would be a lot easier to do in python than in bash,
| and none of that looking out for spaces in strings and so on.
| throwaway858 wrote:
| There is this for Haskell, which automatically converts all
| shell commands (like "ls") to regular Haskell functions:
|
| https://chrisdone.com/posts/shell-conduit/
|
| It uses a Haskell streaming library so you can do stuff like
| shell pipelines and file redirection (but in a more structured,
| safer and more powerful way)
| meta-meta wrote:
| https://github.com/babashka/babashka comes to mind
| frumiousirc wrote:
| Am I missing something or is the article's central example using
| `tail` fundamentally broken?
|
| The `sort` blocks until input is closed yet `tail -f` never
| closes its output.
| [deleted]
| JdeBP wrote:
| You'll be pointing out that [ is a built-in command, next. (-:
| rascul wrote:
| It's also a binary in /bin (or a symlink because of /usr
| merge) and it's silly that the article tries to view [ in a
| pager.
| SomeCallMeTim wrote:
| Bash/Sh is an objectively awful programming language. You could
| likely fill an entire book with all of the design fails that is
| Bash script syntax. Only in a shell script would you ever need
| eight backslash characters in a row in order to accomplish
| something...and "space as delimiter" is awful in _so many ways_.
|
| But especially Sh runs everywhere, so it's good to know. This
| seems to be the article's point.
|
| Honestly, though? The right answer is to transpile a better
| language to Sh.
|
| Looking around, there have been several half-hearted, abandoned
| attempts. But apparently everyone is happy to just fall back on
| the "accidental syntax" of Bash that really doesn't make sense
| when compared to ... any other language.
|
| I put up with Bash because there's no better alternative. That
| doesn't mean we _should_ put up with Bash; just that we _must_
| put up with it at least to the point where it can run code
| written in a _real_ language.
| sgarland wrote:
| Shell is an objectively _difficult_ programming language. But
| difficult != awful. Pointy and ready to bite you if you make a
| tiny mistake? Yes. Ubiquitous and not going anywhere? Also yes.
|
| But given that *nix tooling output defaults to text, it's hard
| to argue against a universal language that talks to all of it.
| danielvaughn wrote:
| I'm not very knowledgeable in this area as I don't do much
| shell scripting, but isn't zsh supposed to be some kind of
| enhancement over bash? Does it suffer from the same issues?
|
| Regardless, the idea of a language that transpiles to bash is
| kinda interesting.
| marcosdumay wrote:
| > "space as delimiter" is awful in so many ways
|
| Yes. But it's also absolutely great in so many ways.
___________________________________________________________________
(page generated 2023-05-18 23:01 UTC)