Live data from Hacker News

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

nochlin.com

171–180 of 281 posts

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

#172
post #154
post #60

Earlier quoted context omitted.

There should just be a command for this. Like echo with a color flag that does something if you’re in a tty.

Why? Benefit? 10% of people hace problemas with colors. Depending on the terminal/background, you will produce bad/invisible output. Any good typesetting book will tell you not to use colors.

I have problems with non-colored output because it makes it harder to distinguish important from less important stuff.

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

#173

Earlier quoted context omitted.

What? How are typed objects files? What I’m saying is that in *nix tooling, things are typically designed to do one thing well. So no, I don’t want my shell to also have to talk MySQL, Postgres, SQL Server, DB2, HTTP, FTP, SMTP…

> "So no, I don’t want my shell to also have to talk..." What's the point of the shell, if not to manage your databases, your REST APIs, files, and mail? Is it something you use for playing games on, or just for fun? > designed to do one thing well. Eeexcept that this is not actually true in practice, because the abstraction was set at a level that's too low . Shoving everything into a character (or byte) stream turn…

> What's the point of the shell, if not to manage your databases, your REST APIs, files, and mail? Is it something you use for playing games on, or just for fun?

To call other programs to do those things. Why on earth would I want my shell to directly manage any of those things?

I think you're forgetting something: *nix tools are built by a community, PowerShell is built by a company. Much like Apple, Microsoft can insist on and guarantee that their internal API is consistent. *nix tooling cannot (nor would it ever try to) do the same.

> It means that "ps" has a built-in sort command, as do most other UNIX standard utilities, but they all do it differently.

I haven't done an exhaustive search, but I doubt that most *nix tooling has a built-in sort. Generally speaking, they're built on the assumption that you'll pipe output as necessary to other tools.

> This also means that you just "need to know" how to convince each and every command to output machine-readable formats that other tools on the pipeline can pick up safely.

No, you don't, because plaintext output is the lingua franca of *nix tooling. If you build a tool intended for public consumption and it _doesn't_ output in plaintext by default, you're doing it wrong.

Here's a one-liner with GNU awk; you can elide the first `printf` if you don't want headers. Similarly, you can change the output formatting however you want. Or, you could skip that altogether, and pipe the output to `column -t` to let it handle alignment.

    netstat -nA inet | gawk -F':' 'NR > 2 { split($2, a, / /); pc[a[1]]++ } END { printf "%-5s     %s\n", "PORT", "COUNT"; PROCINFO["sorted_in"]="@val_num_desc"; c=0; for(i in pc) if (c++ 
Example output:

    PORT      COUNT
    6808      16
    3300      8
    6800      6
    6802      2
    6804      2
    6806      2
    60190     1
    34362     1
    34872     1
    38716     1

Obviously this is not as immediately straight-forward for the specific task, though if you already know awk, it kind of is:

    Set the field separator to `:`
    Skip the first two lines (because they're informational headers)
    Split the 2nd column on space to skip the foreign IP
    Store that result in variable `a`
    Create and increment array `pc` keyed on the port
    When done, do the following
    Print a header
    Sort numerically, descending
    Initialize a counter at 0
    For every element in the pc array, until count hits 10, print the value and key
You can also chain together various `grep`, `sort`, and `uniq` calls as a sibling comment did. And if your distro doesn't include GNU awk, then you probably _would_ have to do this.

You may look at this and scoff, but really, what is the difference? With yours, I have to learn a bunch of commands, predicates, options, and syntax. With mine, I have to... learn a bunch of commands, predicates, options, and syntax (or just awk ;-)).

> This kind of thing is a challenge with UNIX tools

It's only a challenge if you don't know how to use the tools.

> Any change to the output format of netstat breaks scripts in fun and create ways

The last release of `netstat` was in 2014. *nix tools aren't like JavaScript land; they tend to be extremely stable. Even if they _do_ get releases, if you're using a safe distro in prod (i.e. Debian, RedHat), you're not going to get a surprise update. Finally, the authors and maintainers of such tools are painfully aware that tons of scripts around the world depend on them being consistent, and as such, are highly unlikely to break that.

> Silently. In production.

If you aren't thoroughly testing and validating changes in prod, that's not the fault of the tooling.

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

#174
post #139

Earlier quoted context omitted.

I think it’s because: > If ShellCheck is spitting out lots of warnings, then it'd be worth changing your shell writing style to be more compliant with it. Is just a very roundabout way of saying ‘If you get a lot of errors using shellcheck you are doing it wrong’, which may or may not be true, but it’d make anyone defensive.

You could be right - I certainly didn't intend my comment to be antagonistic. My experience of ShellCheck is that you only get loads of warnings when you first start out using it and it finds all of your unquoted variables. Once you get more experienced with writing scripts and linting them with ShellCheck, the number of warnings should dramatically reduce, so it seems odd that an experienced script writer would be f…

> it seems odd that an experienced script writer would be falling foul of shellcheck being pedantic about what you're writing.

It's not simply being pedantic, it is wrong. Your writing gives the impression that the tool is infallible.

If I was new to writing shell scripts, shellcheck is clearly a wise choice. The language is loaded with footguns. But as someone who has been writing scripts for decades, I already know about all the footguns. My experience with shellcheck is that it mostly finds false positives that waste my time.

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

#175
post #139

Earlier quoted context omitted.

I think it’s because: > If ShellCheck is spitting out lots of warnings, then it'd be worth changing your shell writing style to be more compliant with it. Is just a very roundabout way of saying ‘If you get a lot of errors using shellcheck you are doing it wrong’, which may or may not be true, but it’d make anyone defensive.

People should learn to take constructive criticism and harsh truths better. I saw nothing unkind with that comment.

I wouldn't say it's unkind, but I do take issue with "it's worth changing how you write scripts" because, at least for me, it isn't.

If it's useful for you, then wonderful!

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

#176

Earlier quoted context omitted.

I had some similar thoughts when seeing the script. For better user friendliness, I prefer to have the logging level determined by the value of a variable (e.g. LOG_LEVEL) and then the user can decide whether they want to see every single variable assignment or just a broad outline of what the script is doing. I was taken back by the "print_and_execute" function - if you want to make a wrapper like that, then maybe a…

What's so bad in using echo?

Well, strokes beard, funny you should ask.

Have a look at https://mywiki.wooledge.org/BashPitfalls#echo_.24foo

Most of the time, "echo" works as you'd expect, but as it doesn't accept "--" to signify the end of options (which is worth using wherever you can in scripts), it'll have problems with variables that start with a dash as it'll interpret it as an option to "echo" instead.

It's a niche problem, but replacing it with "printf" is so much more flexible, useful and robust. (My favourite trick is using "printf" to also replace the "date" command).

Also, here's some more info on subtle differences between "echo" on different platforms: https://unix.stackexchange.com/questions/65803/why-is-printf...

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

#177

Earlier quoted context omitted.

If you just want to move some files around and do basic text substitution, turning to Python or another other "full fledged programming language" is a mistake. There is so much boiler plate involved just to do something simple like rename a file.

You mean import os os.rename(“src.txt”, “dest.txt”) ?

Yes. And it is only downhill from there.

Now, show us `mycommand | sed 's/ugly/beautiful/g' | awk -F: '{print $2,$4}' 1> something.report 2> err.log` in Python.

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

#178
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…

[dead]

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

#179

This reads like what I've named as "consultantware" which is a type of software developed by security consultants who are eager to write helpful utilities but have no idea about the standards for how command line software behaves on Linux. It ticks so many boxes: * Printing non-output information to stdout (usage information is not normal program output, use stderr instead) * Using copious amounts of colours everywhe…

Addendum after reading the script: * #!/bin/bash instead of #!/usr/bin/env bash * [ instead of [[ * -z instead of actually checking how many arguments you got passed and trusting the end user if they do something weird like pass an empty string to your program * echo instead of printf * `print_and_execute sdk install java $DEFAULT_JAVA_VERSION` who asked you to install things? * `grep -h "^sdk use" "./prepare_$fork.s…

As far as quick and dirty scripts go, I wouldn’t care about most of the minor detail. It’s no different to something you’d slap together in Ruby, Python, or JS for a bit of automation.

It’s only when things are intended to be reused or have a more generic purpose as a tool that you need them to behave better and in a more standard way.

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

#180

Earlier quoted context omitted.

What's so bad in using echo?

Well, strokes beard , funny you should ask. Have a look at https://mywiki.wooledge.org/BashPitfalls#echo_.24foo Most of the time, "echo" works as you'd expect, but as it doesn't accept "--" to signify the end of options (which is worth using wherever you can in scripts), it'll have problems with variables that start with a dash as it'll interpret it as an option to "echo" instead. It's a niche problem, but replacing…

Thank you!
Post reply on HN