Live data from Hacker News

Shell script best practices, from a decade of scripting things

sharats.me

341–350 of 500 posts

Re: Shell script best practices, from a decade of scripting things

#341

Instead of implementing a -h or --help, consider using some code like "if nothing else matches, display the help". The asterisk is for this purpose. while getopts :hvr:e: opt do case $opt in v) verbose=true ;; e) option_e="$OPTARG" ;; r) option_r="$option_r $OPTARG" ;; h) usage exit 1 ;; \*) echo "Invalid option: -$OPTARG" >&2 usage # call some echos to display docs or something... exit 2 ;; esac done

Why not both (or all three)? That's what I do.

When I get to a new command I find it a bit anti-social when it takes effort to find the help.

Re: Shell script best practices, from a decade of scripting things

#342

Earlier quoted context omitted.

> "If you have to write more than 10 lines, then use a real language" I swear, there should be a HN rule against those. It pollutes every single Shell discussions, bringing nothing to them and making it hard for others do discuss the real topic.

There are three numbers in this industry: 0, 1 and infinity. Any other number - especially when stated as a rule, limitation, or law - is highly suspect.

Are you one of those people who take everything literally, so any and all jokes fly far over their heads?

This rule of ten lines or less is clearly meant as an illustrative guideline. Obviously if you have a shell script that has 11 lines, but does what it has to do reliably, nobody will be bothered.

The idea that the rule is trying to convey is "don't write long, complex programs in shell". Arguing about exact numbers or wording here is detracting from the topic at hand.

Re: Shell script best practices, from a decade of scripting things

#343
post #256

Earlier quoted context omitted.

Now do an associative array containing another associative array.

Sometimes a you just have to accept a language's limitations. Try in Python to make a nested defaultdict you can access like the following. d = d["a"]["b"]["c"] # --> 42 Can't be done because it's impossible for user code to detect what the last __getitem__ call is and return the default. Edit: Dang it, I mean arbitrary depth.

In this case you're chaining discreet lookup operations where it sounds like you really want a composite key. You could easily implement this if you accepted the syntax of it as d["a.b.c"] or d["a", "b", "c"] or d.query("a", "b", "c")

Otherwise I'm not sure of a mainstream language that would let you do a.get(x).get(y) == 42 but a.get(x).get(y).get(z) == 42, unless you resorted to monkey patching the number type, as it implies 42.get(z) == 42, which seems.. silly

Re: Shell script best practices, from a decade of scripting things

#344

I'm not convinced about having shell scripts end with ".sh" as you may be writing a simple command style script and shouldn't have to know or worry about what language it's using. I'm a fan of using BASH3 boilerplate: https://bash3boilerplate.sh/ It's standalone, so you just start a script using it as a template and delete bits that you don't want. To my mind, the best feature is having consistent logging functions,…

This is fantastic! I'm going to start using this as the baee for all my scripts, and will also start using shellcheck (on CI as well.)

It makes things so much easier. I end up putting in loads of debug statements as I'm writing the script and it just saves time in the long run.

Re: Shell script best practices, from a decade of scripting things

#345

As someone who used to have to write a lot of shellscripts because I worked at a company that believed in files and not databases, if you want to get funky use: shellcheck It's like pylint for your shellscripts.

A thousand times this. Shellcheck is a godsend that will save you tons of headaches if you have to deal with longer shell scripts - whether you are writing new scripts or maintaining old ones.

Re: Shell script best practices, from a decade of scripting things

#346
post #165

> Use bash. Using zsh or fish or any other, will make it hard for others to understand / collaborate. Among all shells, bash strikes a good balance between portability and DX. I think fish is quite a bit different in terms of syntax and semantics (I'm not very familiar with it), but zsh is essentially the same as bash except without most of the needless footguns and awkwardness. zsh also has many more advanced featur…

I can't really stand Bash's arcane syntax, it drains my brain power (and time of consulting manual) every time I have to work with it. Switching to Fish has been a breath of fresh air for me. I think some people who want to use only Bash need to open their conservative mind. All of my personal shell scripts now are converted to Fish. If I want to run some POSIX-compatible script then I just use `bash scripts.sh` Of c…

I use fish as an interactive shell but I don't write fish scripts. Once you accept a script has dependency there seems little reason not to go all the way to python (or usually I just go all the way to rust now, but I suspect others may disagree with me more on that than python)

Re: Shell script best practices, from a decade of scripting things

#347

Naming your executable shell scripts with .sh has similar problems to Hungarian notation. If your ~/.local/bin shell script ends up useful in a lot of places, you may want to re-write it in something less crap (and I say that as an experienced bash abuser who knows it quite well and uses it a lot more than he should) than bash. When you do that, your python/nim/lua/whatever script now has .sh at the end. What was the…

Superb comment. It's rare that I agree with so many words as-is.

I might add only a minor note that his construct for h/help breaks globbing in a directory that happens to contain a file named "h" or "help" (even without a leading dash '-'), but only if that happens to be first alphabetically. No footgun there..Lol. He also does no "--" support, about the only convention to make globbing work reliably.

Re: Shell script best practices, from a decade of scripting things

#348

Earlier quoted context omitted.

zsh is not a "cleaned-up bash"; it's more of a clone of ksh (closed source at the time), with some csh features added in, as well as their own inventions. bash and zsh appeared at roughly the same time, many features were added in zsh first and added to bash later (sometimes much later, and often never). This is kind of a good example of what I meant when people conflate "bash" with "shell". As for your larger point:…

The verbosity of PowerShell is overstated I think. You easily make POSH look as gnarly and esoteric as Bash if you so desire. That said, the majority of heavy lifting in POSH is done via methods these days (vs cmdlets). Your initial API query to snag the JSON might be via a cmdlet, but after that, you're slicing and dicing with real data structures. You can interact with them without having worry about whitespace or…

+1 for the Powershell ISE/Repl - its by far the most user friendly entry to administrative scripting I've ever run into.

Re: Shell script best practices, from a decade of scripting things

#349

Earlier quoted context omitted.

"You have much less options when you are processing PowerShell objects." There is simply no need for the kind of extensive text processing common in Linux because every command returns an object whose fields can be directly referenced. Combined with the ConvertTo-Json command this is incredibly powerful. Honestly it seems like you are attempting to do things in PowerShell the bash way instead of the PowerShell way. "…

I tried to write a PowerShell script to recursively scan and find files/folders older than a certain date, but kept hitting problems with the length of the path/filenames. As a complete PowerShell noob, I'm sure I was trying to do it the wrong way, but after a few attempts, I gave up and install cygwin instead.

Your problem here is with win32 not powershell I suspect. Your script would probably have worked with powershell on Linux, but windows you need to use UNC paths to get a 2^16 - ~20 character path limit rather than the 256 character path limit of regular paths.

Or there's some registry hacks to remove the limit from regular paths.

Re: Shell script best practices, from a decade of scripting things

#350

Earlier quoted context omitted.

> getting the shell quoting hell right Shameless plug coming, it this has been a pain point for me too. I found the issue with quotes (in most languages, but particularly in Bash et al) is that the same character is used to close the quote as is used to open it.m. So in my own shell I added support to use parentheses as quotes in addition to the single and double quotation ASCII symbols. This then allows you to nest…

One of my favorite Perl features that has been disappointingly under-appropriated by other languages is quoting with q(...).

This means that you can even quote the delimiter in the string as long as it's balanced.

    $X=q( foo() )
Should work if it's balanced. If you choose a different pair like []{} then you can avoid hitting collisions. It also means that you can trivially nest quotations.

I agree that this qualified quotation is really underutilized.

Post reply on HN