rgrau

Joined 14 years ago

Karma
524
Submissions
126
Member since
Jun 11
- https://github.com/kidd/Me

- https://puntoblogspot.blogspot.com

View on Hacker News

Recent submissions

Comment · 3 months ago
So true. I think most of us who learned "advanced" bash is after being tired of feeling like an idiot looking at long bash scripts.

Usually, those scripts are written by people who didn't learn the "weird tricks", and use global variables (they didn't learn that `local` creates local variables), for example.

In bash, many times the "dumb way" takes 10 times more lines, and it's probably buggier than the "smart tricky way". So, in the end it's your choice what side you pick, and when to stop. Or, use a "real programming language" (I hate when people say this LOL)

After a while, you get a bit of stockholm syndrome, and you're just fine with bash as an orchestration language, and lean into unix principles. I accept its limitations, and I think it keeps me on my toes as it repels bloat.

idk if you were expecting an answer, but bash lives in this liminal space in the tower of languages that is worth a thought.

Comment · 3 months ago
Nice one! I love those weird bash tricks.

Some of the examples here are interesting, but they show parameter substitution more than colon itself: https://tldp.org/LDP/abs/html/parameter-substitution.html

In small scopes, I tend to inline the `:?` validation inside the arg of the command. `echo "${1:? first param required}"`

Another usecase is to use colon in the body of a while loop, while doing work in the condition of the loop.

    while rlwrap -o -S'>> ' tr a-z A-Z ; do :; done
Gives you the "do X while it succeeds. stop when it returns non-0" semantics.

I've also written about this and other bash tricks over the years in https://github.com/kidd/scripting-field-guide/blob/master/bo.... You might like them :)

Comment · 7 months ago
aha! I see what you mean, it's indeed a nice option, yep.

Using brackets like this is something I never thought of, and it's probably why it's hard for me to process it, but I can see it provides nice annotation capabilities, and it's a more self-contained style.

Thx for sharing!

Comment · 7 months ago
That's very cool!

To take advantage of the "leading space" one, I have this, to mark some commands that I never want to record:

       unhist () {
         alias $1=" $1"
       }
       unhist unhist
       unhist fzf
       unhist rghist     #custom command that greps .zhistory,...
Comment · 7 months ago
Comment · 7 months ago
A similar trick:

    #!/bin/sh
    $*
that's my `~/bin/noglob` file, so when I call a zsh script from bash that uses `noglob`, it doesn't blow up.
Comment · 1 year ago
I use a variant with ssh and some compression:

    docker save $image | bzip2 | ssh "$host" 'bunzip2 | docker load'
Comment · 3 years ago
You can also nest those, so this way you can get a value from an argument, or an env var, and if none is set, error.

    echo "${1:-${env_var:?I need a value for that!}}"
Comment · 3 years ago
Comment · 3 years ago
I couldn't find a way to have more than one callback per signal, and created a system to have an array of callbacks:

https://github.com/kidd/scripting-field-guide/blob/master/bo...

A nice bonus is that it also keeps the return value of the last non-callback function, so your script behaves better when called from other scripts.

Comment · 3 years ago
Yep, good point. They are useful when you want to change the whole text inside the delimiters (and IME, it's most of the times), but they do different things than cf( because they also change/delete text behind the cursor.

The % approach works only on one direction.

Comment · 3 years ago
I have 2 use cases for cf), but I don't use it a lot in the end:

One is when inside a parenthesis, and wanting to really delete till the closing parenthesis. But that would leave an unbalanced open paren. So in this case, I use ct) most of the times.

The other is when the cursor is before the opening parenthesis, and I want to delete the whole block. In that case, I found c% to be easier to me. The advantage being that it works with other delimiters ({[]}) handles nesting better, and it's multiline friendly.

If instead of c%, we speak about d%, another plus is that dot (.) will repeat the generic command, so

    if (is_foo()) {

      return 1;
    }
can be cleared with `d%.` from the beginning of the first line.
Comment · 3 years ago
Comment · 3 years ago
Comment · 4 years ago
Oh, I hadn't noticed that links are not highlighted as such (unless already visited).

Fixed, thanks!

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton