Moreshell tricks: first class lists, jq, and the es shell

(alurm.github.io)

22 points | by alurm 4 hours ago ago

11 comments

  • chubot an hour ago ago

    let’s implement split-by-double-dash, a function (or a program) that would return two lists: args that come before -- and ones that come after.

    split-by-double-dash a b c -- d e f should return the lists [a, b, c] and [d, e, f]

    FWIW in YSH (https://oils.pub/ysh.html), you can do this in a style that's like Python and JavaScript, but you can also combine it with shell idioms.

    First create it and pretty print it:

        ysh-0.34$ var li = :| a b c -- d e f |  # shell word style, ['a', 'b'] style is also accepted
    
        ysh-0.34$ = li  # pretty print with =
        (List)  ['a', 'b', 'c', '--', 'd', 'e', 'f']
    
    Then test out the indexOf() method on strings:

        ysh-0.34$ = li.indexOf('--')
        (Int)   3
    
    Then write the function:

        ysh-0.34$ func splitBy(li) {
                >   var i = li.indexOf('--')
                >   assert [i !== -1]
                >   return ( [li[ : i], li[i+1 : ]] )  # same slicing as Python
                > }
    
    Call it and unpack it

        ysh-0.34$ var front, back = splitBy(li)
    
        ysh-0.34$ = front
        (List)  ['a', 'b', 'c']
    
    Use it in shell argv, with @myarray as splicing:

        ysh-0.34$ write -- @back
        d
        e
        f
  • delta_p_delta_x 2 hours ago ago

    I was about to comment with my usual 'why not PowerShell', but it seems the author acknowledges this anyway at the end:

    > I’ll quote Rich’s sh (POSIX shell) tricks to end this:

    > I am a strong believer that Bourne-derived languages are extremely bad, on the same order of badness as Perl, for programming, and consider programming sh for any purpose other than as a super-portable, lowest-common-denominator platform for build or bootstrap scripts and the like, as an extremely misguided endeavor

    • packetlost 10 minutes ago ago

      This is why I use Plan9's rc shell for a lot of my scripting needs. It's dramatically nicer to write but even more nice to read.

    • alurm 2 hours ago ago

      Yeah, PowerShell and nushell are pretty cool, I hope they gain more adoption.

      • stouset an hour ago ago

        I keep intending to give nushell a serious try, but I'm too set in my ways :(

  • its-summertime an hour ago ago

    with bash namerefs, having a function like

        split-on-ddash outputa outputb a b c -- x y z
        for x in "${outputa[@]}"; do # ...
    
    becomes feasible. Of course, don't do it.
    • alurm an hour ago ago

      Sure.

      I have tried Bash namerefs. I found them to be kinda awkward, since you need to name them uniquely. So, you have to pretend that they are global variables, even though they are declared inside a function, which makes their usage verbose.

      Here, this could look like:

        split_by_double_dash() {
          declare -n split_by_double_dash_before=$1
          declare -n split_by_double_dash_after=$2
          
          split_by_double_dash_before=()
          split_by_double_dash_after=()
      
          ...
        }
  • jeffrallen 3 hours ago ago

    I review shell scripts from beginner ops people. I would not approve any of this stuff. Once you need this complexity in shell, you need other things you should be getting from the language's stdlib. So I'd ask them to switch to Python or Go.

    Do not fall into the trap of big complex shell scripts.

    • calmbonsai 5 minutes ago ago

      I'll go further.

      Shell is great for personal or local-group/team automation, but outside of a bootstrap, it should _never_ be used for anything in deployed production.

      The 3 main issues are hidden deps, error handling, and performance.

    • SoftTalker 2 hours ago ago

      There's a point where what you say is true but I would not view using 'jq' to tease a list out of some JSON data to be it. Isn't that what your python or go code is going to do? All jq is is a packaged set of calls to stdlib stuff.

      Systems admins are generally not Python or Go experts. And those are two dependencies which may not be available anyway (or will require installation, and maintenancee, may introduce new vulns, etc.). You could say the same about 'jq' though.

    • zhouzhao 2 hours ago ago

      >Do not fall into the trap of big complex shell scripts

      This so much.