11 ms·
My rule of thumb: if the script needs argument parsing or any sort of error handling/cleanup, I’ll write it in Python 3.5 instead of bash.
by abiro 6y ago
My rule of thumb: if the script needs argument parsing or any sort of error handling/cleanup, I’ll write it in Python 3.5 instead of bash.
- quyleanh 6y agoSo true. In my case, if my script has loop, I will use python or perl instead of bash.
- aduitsis 6y agoIf the script must iterate over the lines of its input, I've found perl -nlE to be a godsend. Basically it is equivalent to while(<>){ chomp; <insert your -E code here> }
- emptyparadise 6y agoOnce I type a square bracket in a shell script, I know it's time to bring out Python. I don't think it's humanely possible to write a test command without shooting yourself in the foot in an exciting new way.
- usr1106 6y ago> don't think it's humanely possible to write a test command without shooting yourself in the foot in an exciting new way That's a weird claim. Could it be that you have never really learned shell programming or read the man pages? Or can you give an example? We have lot of production code with many test statements and I don't remember when we were bitten last time by some "surprising feature" of test. I agree that test works differently than comparisions in many programming languages. So you need to understand how it is different. And you need to be disciplined about quoting, otherwise surprises will happen when you have user-controlled input and the shell starts to do word-splitting. But if you use shellcheck you will be reminded of quoting everywhere. It's not a problem specific to test anyway.
- imtringued 6y agoI have written dozens of of bash utilities at a single company. Probably 5000 lines of bash in total. I still don't know the whole syntax for if/for/case and have to look it up every single time.
- zimpenfish 6y agoI've written hundreds (if not thousands) of bash utilities over 20+ years and I still occasionally have to check the syntax for various bits.
- kristaps 6y ago> So you need to understand how it is different. And you need to be disciplined about quoting Or I can use a sane language that let's me get my stuff done faster and with less opportunities to shoot myself in the foot.
- meowface 6y agoIf I'm modifying an existing script, I generally have no problem doing that. But the tweet quoted in the article rings very true to me: >The opposite of "it's like riding a bike" is "it's like programming in bash". >A phrase which means that no matter how many times you do something, you will have to re-learn it every single time. I and probably a lot of programmers write bash scripts just enough to remember the vague shape of what we want to do, yet still infrequently enough to require looking up the exact characters every single time (-z? ! -z? one bracket? two brackets? quotes? no quotes? something about a semicolon and "then", right? where can you add newlines, again? oh yeah, it's not "end" like Ruby/Lua but "fi" right? what's "else if", again?). I'm sure if we were working with bash scripts daily, we'd memorize it, but it's just rare and just different enough that it's basically day 1 all over again every time. Shellcheck helps as a safety net, but it doesn't necessarily save me a lot of time and cognitive load. If I'm writing a new script from scratch and I realize there's going to be some branching or prompts or complex argument handling, I just write it in Python. It saves time and effort, it lets other people on my team more quickly modify and debug it, and it's more predictably portable ("oops, only sh, no bash"). And if it ever needs to do something more advanced in the future, it's way easier to extend. Or put much more succinctly, by 'kristaps in another comment: >Or I can use a sane language that let's me get my stuff done faster and with less opportunities to shoot myself in the foot. It's nice for quickly writing something that's just wrapping multiple commands, though.
- dexen 6y agoAwk is a viable replacement for Bash for scripting. A long established standard and installed on pretty much every POSIX system. It has more robust facilities for handling variables, arrays, regex search & substitution, etc.
- usr1106 6y agoawk is a full programming language. But it has gotten little attention in the last 20 years. If you expect that someone else can read and maintain your code with minimal learning I don't think it's the tool of choice.
- jrochkind1 6y agoBut... neither is bash. I am sympathetic to the argument that awk is theoretically superior to bash in almost all ways (and it is of course nearly as available as bash). But... something still makes me reluctant to switch to using it in the cases I write a bash script (which I'm already trying to minimize, as is the OP). I'm not really sure why though. (Fun-for-mostly-me fact, my very first programming job ever was writing awk. It was a while ago. I certainly don't remember any awk now).
- alexhutcheson 6y agoAwk is great for snippets that are meant to be copy+pasted into a shell, and is the only reasonable option sometimes if you're stuck in a Busybox environment, but for almost everything else you'd be better off with Python. This previous comment of mine goes into a bit more detail: https://news.ycombinator.com/item?id=23242753 https://news.ycombinator.com/item?id=23242753
- fomine3 6y agoAgreed but I point that not all awks are gawk.
- vlowther 6y agoOr better yet, condition yourself to hit [ a second time and use Bash's built-in conditionals instead of test and [
- usr1106 6y agoDepends. In an embedded system I prefer not to have to install Python at all.
- franga2000 6y agoIn an embedded system (== very limited resources), wouldn't you want to avoid any interpreted language, even shell? We have some very nice languages that compile to machine code these days
- im3w1l 6y agoBASIC is 56 years old. Computers back then were not very fast, but interpretation was still viable.
- usr1106 6y agoHave used it on 7KB RAM :) But to be fair the interpreter was in ROM, no idea how big that was.
- teddyh 6y agoROM was usually very slow, so all ROM content was usually copied to RAM before execution. RAM size was therefore still an issue.
- usr1106 6y agoI am pretty sure the PET-2001 didn't do that. 8 KB was all it had, about 1 KB was used by the operating system and 7 KB where available for programming. Actually something you would call byte code today, every basic command was 1 Byte. Just don't use labels with 4 or 5 characters, that wastes a lot of space! The first models came even with 4 KB RAM / 3 KB usable. Have never seen one of those, though.
- colonwqbang 6y agoIf we're talking Linux embedded and not something like an MCU, then you already likely have a shell installed. So you might as well use it for the things which shell excels at. Shell scripts are much smaller in size than the equivalent C code, for those things that shell is typically used for.
- dxdm 6y agoWhy Python version 3.5 specifically?
- abiro 6y agoI work on Debian or derivatives mostly and the oldest Debian LTS has 3.5.
- loudmax 6y agoI agree with the general sentiment, though I set the bar a bit higher (or lower, depending on your perspective). Bash does okay with positional arguments, error handing, and even loops. You can get a lot done with that, and there are a lot of circumstances where a little bash script is just what you need. Where I draw the line is at arrays. If you're starting to think about data structures, bash isn't the right tool for the job.
- dvfjsdhgfv 6y agoWell, it depends. I had a co-admin who used to rewrite all my Bash scripts in Python. Most of them were a bunch of os.system() calls. He was a bit upset when I pointed out they are actually buggier than their Bash originals and noticeably slower.
- Silhouette 6y agoIndeed. Shell scripting can easily get overcomplicated and I agree that moving to a real programming language is better at that point. However, Python isn't necessarily the ideal language for it either, because managing child processes with its standard library functionality can get overcomplicated and verbose, particularly once you start dealing with functionality like pipes. So people often resort to generic os.system calls instead and then you get a strange hybrid style.
- fillest 6y agoExactly. Or even stricter. I've finally made a self-contained helper for that: https://gist.github.com/fillest/8d64f8fa0cdb1745bfc9c683cf39d453 https://gist.github.com/fillest/8d64f8fa0cdb1745bfc9c683cf39... Pure Bash is really not needed since we have Python 3.
- enw 6y agoAssuming you can afford introducing the Python dependency. Also pipe/subprocess heavy scripts often become sad complex monstrosities in non-shell languages.
- FriedrichN 6y agoAgreed. Not with the programming language per se, but I agree with the general premise. However, in cases where portability is important, bash is would be my choice. If I can pass someone a bash script and not ask them to also install Python and whatever libs I used, it makes my life so much easier.
- jonfw 6y agoContainers work great for me if the target users are also familiar with them
- kps 6y agoIt's too bad (for bash users) that bash never bothered to embrace ksh getopts. The equivalent of the article's two pages is roughly, usage=$' [-1][+NAME?script - Script synopsis here] [f:flag?Some flag description] [p:param?Some param description]:[string?description] ' while getopts "$usage" opt do typeset opt_${opt}=${OPTARG:-1} done
- ben11kehoe 6y agoAgreed about arg parsing. One day I decided to figure out how to get Python arg parsing in a bash script. The horrifying result: https://gist.github.com/benkehoe/c469ebb76ad80d45405077e109352380 https://gist.github.com/benkehoe/c469ebb76ad80d45405077e1093...