Live data from Hacker News

Techniques I use to create a great user experience for shell scripts

nochlin.com

111–120 of 281 posts

Re: Techniques I use to create a great user experience for shell scripts

#111
post #106

A tip: sh -x $SCRIPT shows a debugging trace on the script in a verbose way, it's unvaluable on errors. You can use it as a shebang too: #!/bin/sh -x

Thanks! I've always edited the script adding a `set -x` at the top. Never occurred to me that I the shell of course had a similar startup flag.

Re: Techniques I use to create a great user experience for shell scripts

#112
post #35

Every time I see a “good” bash script it reminds me of how incredibly primitive every shell is other than PowerShell. Validating parameters - a built in declarative feature! E.g.: ValidateNotNullOrEmpty. Showing progress — also built in, and doesn’t pollute the output stream so you can process returned text AND see progress at the same time. (Write-Progress) Error handling — Try { } Catch { } Finally { } works just l…

I also hate bash scripting, and as far as Unix shell go, bash is among the best. So many footguns... Dealing with filenames with spaces is a pain, and files that start with a '-', "rm -rf" in a script is a disaster waiting to happen unless you triple check everything (empty strings, are you in the correct directory, etc...), globs that don't match anything, etc... But interactively, I much prefer Unix shells over Pow…

> What you are saying essentially is that PowerShell is a better programming language than bash

In some sense, yes, but there is no distinct boundary. Or at least, there ought not to be one!

A criticism a lot of people (including me) had of Windows in the NT4 and 2000 days was that there was an enormous gap between click-ops and heavyweight automation using C++ and COM objects (or even VBScript or VB6 for that matter). There wasn't an interactive shell that smoothly bridged these worlds.

That's why many Linux users just assumed that Windows has no automation capability at all: They started with click-ops, never got past the gaping chasm, and just weren't aware that there was anything on the other side. There was, it just wasn't discoverable unless you were already an experienced developer.

PowerShell bridges that gap, extending quite a bit in both directions.

For example, I can use C# to write a PowerShell module that has the full power of a "proper" programming language, IDE with debug, etc... but still inherits the PS pipeline scaffolding so I don't have to reinvent the wheel for parameter parsing, tab-complete, output formatting, etc...

Re: Techniques I use to create a great user experience for shell scripts

#113
> This matches the output format of Bash's builtin set -x tracing, but gives the script author more granular control of what is printed.

I get and love the idea but I'd consider this implementation an anti-pattern. If the output mimics set -x but isn't doing what that is doing, it can mislead users of the script.

Re: Techniques I use to create a great user experience for shell scripts

#114
post #85

Earlier quoted context omitted.

> why not also "bye" or "leave" or "close" or "end" or "terminate". We can include these as well, but each keyword that you include brings diminishing returns at the cost of clutter and inconsistence in the API. Python problematically decides that returns diminish after the first --- “first” according to developers, that is --- possibility in all cases . Ruby anticipates that everyone's first choice will be different…

>Python problematically decides that returns diminish after the first --- “first” according to developers, that is --- possibility in all cases Eh, that feels pretty arbitrary to me. `quit()` and `exit()` both work, and looking at other languages, `exit()` should almost certainly be your first choice C: exit(int) Java: System.exit(int) SBCL: (quit)/(exit) C#: Environment.Exit(int) PHP: exit(int)/exit(string) Rust: st…

> Having `exit` or `quit` without the parens work might accommodate some people whose first choice isn't to call a function (I guess because they're thinking of the REPL as a shell?),

In ruby, parentheses are optional for function calls. `exit` is a regular call, not some REPL peculiarity.

EDIT: Nevermind. Just found that despite the `exit` method being already defined, both irb and pry overshadow that with a repl command that does the same thing. Maybe it's so that it can't be redefined.

Re: Techniques I use to create a great user experience for shell scripts

#115

Nowhere in this list did I see “use shellcheck.” On the scale of care, “the script can blow up in surprising ways” severely outweighs “error messages are in red.” Also, as someone else pointed out, what if I’m redirecting to a file?

I find shellcheck to be a bit of a nuisance. For simple one-shot scripts, like cron jobs or wrappers, it's fine. But for more complicated scripts or command line tools, it can have a pretty poor signal-to-noise ratio. Not universally, but often enough that I don't really reach for it anymore. In truth when I find myself writing a large "program" in Bash such that shellcheck is cumbersome it's a good indication that i…

It doesn’t already need to be a compiled language, that’s kind of like noticing you’re not going to walk down a mile to the pharmacy and decide to take a Learjet instead. The gradient should include Python or similar scripting languages before you reach for the big guns :-)

Re: Techniques I use to create a great user experience for shell scripts

#116
I can highly recommend using bash3boilerplate (https://github.com/kvz/bash3boilerplate) if you're writing BASH scripts and don't care about them running on systems that don't use BASH.

It provides logging facilities with colour usage for the terminal (not for redirecting out to a file) and also decent command line parsing. It uses a great idea to specify the calling parameters in the help/usage information, so it's quick and easy to use and ensures that you have meaningful information about what parameters the script accepts.

Also, please don't write shell scripts without running them through ShellCheck. The shell has so many footguns that can be avoided by correctly following its recommendations.

Re: Techniques I use to create a great user experience for shell scripts

#117

Nowhere in this list did I see “use shellcheck.” On the scale of care, “the script can blow up in surprising ways” severely outweighs “error messages are in red.” Also, as someone else pointed out, what if I’m redirecting to a file?

I find shellcheck to be a bit of a nuisance. For simple one-shot scripts, like cron jobs or wrappers, it's fine. But for more complicated scripts or command line tools, it can have a pretty poor signal-to-noise ratio. Not universally, but often enough that I don't really reach for it anymore. In truth when I find myself writing a large "program" in Bash such that shellcheck is cumbersome it's a good indication that i…

If ShellCheck is spitting out lots of warnings, then it'd be worth changing your shell writing style to be more compliant with it. Simple things like always putting variables in quotes should prevent most of the warnings. If anything, long scripts benefit far more from using ShellCheck as you're more likely to make mistakes and are less likely to spot them.

For the false positives, just put in the appropriate comment to disable ShellCheck's error ahead of that line e.g.

# shellcheck disable=SC2034,SC2015

That stops the warning and also documents that you've used ShellCheck, seen the specific warning and know that it's not relevant to you.

Re: Techniques I use to create a great user experience for shell scripts

#118
post #18

Don't output ANSI colour codes directly - your output could redirect to a file, or perhaps the user simply prefers no colour. Use tput instead, and add a little snippet like this to the top of your script: command -v tput &>/dev/null && [ -t 1 ] && [ -z "${NO_COLOR:-}" ] || tput() { true; } This checks that the tput command exists (using the bash 'command' builtin rather than which(1) - surprisingly, which can't alwa…

[deleted]

Re: Techniques I use to create a great user experience for shell scripts

#119
I ask LLMs to modify the shell script to strictly follow Google’s Bash scripting guidelines[^1]. It adds niceties like `set -euo pipefail`, uses `[[…]]` instead of `[…]` in conditionals, and fences all but numeric variables with curly braces. Works great.

[^1]: https://google.github.io/styleguide/shellguide.html

Re: Techniques I use to create a great user experience for shell scripts

#120
post #113

> This matches the output format of Bash's builtin set -x tracing, but gives the script author more granular control of what is printed. I get and love the idea but I'd consider this implementation an anti-pattern. If the output mimics set -x but isn't doing what that is doing, it can mislead users of the script.

Even worse, it mimics it poorly, hardcoding the PS4 to the default.

The author could also consider trapping debug to maybe be selective while also making it a little more automatic.

Post reply on HN