Question for you all.

I was working on a bash script and working out some logic for command chaining and grouping for executing different functions in my script based on the return status of other functions.

I know you can group commands with (), which spawns a subshell, and within the grouping you can chain with ;, &&, and ||.

I also know that you can group commands with {}, but, within the curly braces you can only separate commands with ;.

EDIT: the above statement of the curly braces only allowing ; is incorrect. I misunderstood what I had read. @SheeEttin@lemmy.zip pointed out my mistake.

The requirement is that the list of commands in the curly braces needs to be terminated with a semicolon or a newline character, and in the script, I unknowingly was meeting the rules by using the newlines to make the code easier to read for myself.

END EDIT:

In the script, for readability I did group the commands across lines kind of like a function.

The script is pretty simple. I created a few functions with echo commands to test the logic. the script asks for input of foo or bar. The first function has an if, and if the input is foo, it executes. If it’s bar it returns 1.

The return of 1 triggers the or (||) and executes the second command group.

The idea was, if the user inputs foo, the first group triggers printing foo baz to stdout. If the user inputs bar, the foo function returns 1, the baz function does not execute, the or is triggered, and bar but is printed to stdout

Here’s the script (which executes as described):

Can anyone explain why I’m able to group with curly braces and still use && inside them?

(Also, the reason I want to use the curly braces is I don’t want to spawn a subshell. I want variable persistence in the current shell)

#! /usr/bin/bash

# BEGIN FUNCTIONS #

foo () {

    if [[ "${input}" = foo ]]; then
        echo "foo"
        return 0
    else
        return 1
    fi

}

bar () {

    echo "bar"

}

baz () {

    echo "baz"

}

but () {

    echo "but"

}

# END FUNCTIONS #

read -p "foo or bar? " input

{
    foo && 
    baz
} ||

    {
        bar &&
        but
    }
    • harsh3466@lemmy.mlOP
      link
      fedilink
      arrow-up
      1
      ·
      20 hours ago

      My environment is just my homelab. Ubuntu server on my server, Arch (btw) on my laptop. So I could go with any language , but right now I’m choosing Bash. I know stuff I’m doing would probably be easier in a different language, and maybe I’m a glutton for punishment. I just want to get really good with Bash.

      The logic is Bash is gonna be available on just about any computing environment I encounter (linux especially, but even Windows with WSL and zsh on macOS (which I know is different, but still very similar). But really, I am just enjoying the hell out of learning and scripting with Bash. I’ll move on to Python or something someday.

    • harsh3466@lemmy.mlOP
      link
      fedilink
      arrow-up
      1
      ·
      20 hours ago

      Ah! I misinterpreted what I read! I found that exact same reference link when looking into this and I misinterpreted this:

      The semicolon (or newline) following list is required

      to mean that it required the semicolon as the command separator. That explains why my script works. The newline closes each group, and the other operators are allowed, the list just needs to be closed. Thank you!

  • just_another_person@lemmy.world
    link
    fedilink
    arrow-up
    2
    arrow-down
    1
    ·
    21 hours ago

    You’re confusing a lot of things here. The operators you’re referring to all do different things, not just “chaining” commands together. They are used to do basic logic operations based on the preceding conditions or comparisons.

    For example: || does an OR operation, while && does an AND operation.

    Using { } is an operative grouping or something in bash. It’s used to make arrays, group function commands, and iterate on lists as well. In this case you’ve created a group of commands that will execute in order, then give an output result. Everything inside the curly braces is treated as one command, essentially.

    Practical explanation here

    • harsh3466@lemmy.mlOP
      link
      fedilink
      arrow-up
      1
      ·
      20 hours ago

      Thank you for the link!

      I do understand the logic and the difference between ;, &&, and `||. What was confusing me was the command grouping and my misunderstanding of the curly brace grouping rule that the command list has to END with a semicolon. @SheeEttin@lemmy.zip pointed out to me with the link in the comment they left.

      I had read that same link and misunderstood it. On second read I got it, and see now why my script is working, as the newlines serve the same purpose as the semicolon, so the curly braced groups are terminated correctly.