Eugeniu Rosca
Eugeniu Rosca

Reputation: 5305

Why bash functions use round brackets, if those are never filled with arguments?

The function definition syntax for various languages is:

C (the godfather of all scripting languages):

func_type myfunc_c (arg_type arg_name , ...)
{
    /* arguments explicitly specified */
}

TCL:

proc myfunc_tcl {arg1 arg2 args} {
    # arguments explicitly specified
}

Perl:

sub myfunc_perl {
    # no arguments explicitly specified && no round brackets used
}

Python:

def myfunc_python(arg1, arg2):
    # arguments explicitly specified

Bash:

function myfunc_bash () {
    # arguments NEVER explicitly specified
    # WHY using round brackets?
}

Why using round brackets in bash?

Upvotes: 2

Views: 1767

Answers (2)

ikegami
ikegami

Reputation: 385506

Why using round brackets in bash?

Actually, they're not needed, at least not in my version.

$ foo() { echo 'foo!' ; }

$ foo
foo!

$ function bar { echo 'bar!' ; }

$ bar
bar!

$ function baz() { echo 'baz!' ; }

$ baz
baz!

$ bash --version | head -n 1
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)

man bash:

 Shell Function Definitions
   A shell function is an object that is called like a simple command and executes a compound
   command with a new set of positional parameters.  Shell functions are declared as follows:

   name () compound-command [redirection]
   function name [()] compound-command [redirection]
          This defines a function named name.  The reserved word function  is  optional.   If
          the  function reserved word is supplied, the parentheses are optional.  The body of
          the function is  the  compound  command  compound-command  (see  Compound  Commands
          above).  That command is usually a list of commands between { and }, but may be any
          command listed under Compound Commands above.  compound-command is  executed  when-
          ever  name is specified as the name of a simple command.  Any redirections (see RE-
          DIRECTION below) specified when a function is defined are performed when the  func-
          tion is executed.  The exit status of a function definition is zero unless a syntax
          error occurs or a readonly function with the same name already exists.   When  exe-
          cuted,  the  exit  status of a function is the exit status of the last command exe-
          cuted in the body.  (See FUNCTIONS below.)

Upvotes: 6

fedorqui
fedorqui

Reputation: 289495

Parentheses are optional. From Bash Reference Manual --> 3.3 Shell Functions:

Functions are declared using this syntax:

name () compound-command [ redirections ]

or

function name [()] compound-command [ redirections ]

This defines a shell function named name. The reserved word function is optional. If the function reserved word is supplied, the parentheses are optional. The body of the function is the compound command compound-command (see Compound Commands). That command is usually a list enclosed between { and }, but may be any compound command listed above. compound-command is executed whenever name is specified as the name of a command. When the shell is in POSIX mode (see Bash POSIX Mode), name may not be the same as one of the special builtins (see Special Builtins). Any redirections (see Redirections) associated with the shell function are performed when the function is executed.

So these are equivalent:

function hello {
    echo "hello there"
}

hello () {
    echo "hello there"
}

In Bash, functions can access global variables normally, so that the approach is slightly different from other languages. Normally, there is no need to use return because there is no value to catch.

See an example. Here, we have a global variable myvar containing a value. In the functions mytest and mytest_inner we are changing its value. However, in one case the value affects the global environment, whereas in the other does not.

In mytest we change the value and it affects the main block. In mytest_inner we do the same, but the value is just changed locally, in the sub-shell running in the function.

#!/bin/bash

function mytest {
   echo "mytest -> myvar: $myvar"
   ((myvar++))
}

function mytest_inner () {
   (
   echo "mytest_inner -> myvar: $myvar"
   ((myvar++))
   )
}

myvar=$1
mytest
echo "main -> myvar: $myvar"
mytest_inner
echo "main -> myvar: $myvar"

Let's run it:

$ ./myscript.sh 20
mytest -> myvar: 20
main -> myvar: 21
mytest_inner -> myvar: 21
main -> myvar: 21

Upvotes: 11

Related Questions