0

I desire some kind of data structure that looks similarly to a Bash function but isn't a function. A named structure to organize commands by context, that should also allow leading tabs.

This is nice when you have a file with say 20 Bash functions but have no necessity for 20 lines of function calls.

Comparison:

Bash function:

x() {
    echo "x"
}
x

The data structure I seek:

context {
    echo "x"
}

I organize the commands in such data cell similarly to how I would organize it with a function but without parameter parenthesis () and without a function call.

What is the name of such structure and how would you do it?

Notes

  • The name of the structure should always come before it, in the same line, just as with a function.

  • An here-document is not a solution, in this case, I desire something more minimal by means of syntax.

3
  • You mention that the structure should be named ; should you be able to later refer to that structure by its name? Or would a plain comment for instance be enough?
    – Aaron
    Feb 16, 2018 at 10:43
  • This shouldn't be referred by the name from anywhere. Feb 16, 2018 at 10:44
  • The name should come before the block. Feb 16, 2018 at 10:46

2 Answers 2

3

It's called a compound command and the syntax is

{ compound-list; }

(this is an example of a compound command, other things like for loops etc. are also compound commands)

For example:

{
    echo 'hello'
    echo 'world'
}

The ; is only needed if there's no newline before the final }:

{ echo 'hello'; echo 'world'; }

The commands in the { ...; } construct are executed in the current environment, just as for a function.

More information about this is available in the POSIX standard's description of compound commands.

There is no reason (or possibility) to name these sections as naming such a section is more or less equivalent to creating a shell function anyway. Naming a compound command would furthermore only be necessary if it's to be referred to later, which is what functions are used for.

Comments may obviously be used:

# my hello world thing
{
    echo 'hello'; echo 'world'
}

In a similar manner, a subshell may be had with

(
    echo 'hello'
    echo 'world'
)

This executes in a child environment to the current shell, and changes to variables etc. will not be reflected in the current shell.

The general syntax is

( compound-list )

Here, there is no need for a final ; before ).


As a curiosity, shell functions may use (...) in place of {...;} to execute their code in a local environment:

helloworld () (
    echo 'hello'
    echo 'world'
)

This may be useful to know if one is writing a function in a sh language that does not support local variables (local or typeset in bash) and that does not need to modify the script's environment.

1

Are comments enough?

You could use them as follows to regroup commands and provide a name to those groups, and nothing forbids you from using indentation :

#context1
    echo "I'm in context1"
#end of context1

#context2
    echo "I'm in context2"
#end of context2

You could also regroup commands with {...}, which wouldn't have any other effect in this context AFAIK :

#context1
{
    echo "I'm in context1"
}
#end of context1


{ #context2
    echo "I'm in context2"
} #end of context2

If you want in addition to associate these contexts with a local scope, you could use subshells :

#context1
(
    context="context1"
    echo "I'm in $context"
)
#end of context1

( #context2
    echo "I'm in $context" #context is undefined there
    context=context2
    echo "I'm in $context"
) #end of context2

try it here

0

Not the answer you're looking for? Browse other questions tagged .