5

Is it possible to use the "@" symbol as a function name in a bash script? The following does not work:

function @() {
  echo hello
}
3
  • 2
    Works for me, under both recent and ancient versions of bash. What version of bash are you using? Feb 20, 2016 at 1:27
  • @Gilles on4.3.42(1)-release (Arch Linux, package 4.3.042-4), the function definition as given in the question doesn't give an error, but running @ gives @: command not found. Ditto on 4.3.11(1)-release (Ubuntu 14.04, bash package 4.3-7ubuntu1.5). export -f @ gives export: @: not a function.
    – muru
    Feb 20, 2016 at 3:44
  • @Gilles ah, it's due to extglob. Never mind.
    – muru
    Feb 20, 2016 at 4:12

3 Answers 3

4

From man bash

   name   A word consisting only of alphanumeric characters and underscores, 
          and beginning with an  alphabetic character or an underscore.  Also 
          referred to as an identifier.

Shell functions are declared as follows:
          name () compound-command [redirection]
          function name [()] compound-command [redirection]
1
  • 1
    That's what the documentation says, but in fact bash is more liberal, and does accept a function called @. Feb 20, 2016 at 1:27
4

EDIT 2: While @ is unproblematic in vanilla bash, it is used as a pattern grouping operator when the extglob shell option is set, a simple echo @() can hang your shell under certain conditions. All the more reason to not use @ as an identifier`.

EDIT 1: To clarify, it is not allowed per the definition of an identifier. I'm not recommending it. I'm just saying that for backwards compatibility, it is possible in bash to use @ as an identifier.

@() { echo "$1 world"; }
@ hello
alias @="echo hello"
@ world

@ is used as a special parameter ($@) and for arrays (${arr[@]}) but nowhere else. Bash won't stop you using it for identifiers like aliases and functions but not variable names.

Some people alias @ to sudo, so they can execute commands as @ apt-get install.

The main reason why I would not use @ as a shell identifier is that I'm so used to the semantics of @ in Makefiles which silences commands without any side effects.

BTW: Works the same in zsh.

7
  • 1
    Doesn't work for me on 4.3.11. In fact, I had to nuke the shell process.
    – Jon Carter
    Feb 19, 2016 at 0:02
  • 1
    I forgot the semicolon. Why did you nuke the shell process?
    – kba
    Feb 19, 2016 at 0:05
  • It went almost totally unresponsive -- no prompt, no reaction on ^C,^D, or entering 'exit', 'quit'.. Still didn't seem to work for me, even escaping the @. :-/
    – Jon Carter
    Feb 19, 2016 at 0:11
  • Weird, I just tested it in a 4.3.11 as well, works fine for me.
    – kba
    Feb 19, 2016 at 0:15
  • I got the same effect as @JonCarter on 4.3.11(1)-release (Ubuntu 14.04, bash package 4.3-7ubuntu1.5) and on 4.3.42(1)-release (Arch Linux, package 4.3.042-4), after entering @() { echo "$1 world" and pressing enter, I get {: command not found.
    – muru
    Feb 20, 2016 at 3:40
3

The naming of functions is quite similar to the allowed characters for alias:
From man bash:

The characters /, $, `, and = and any of the shell metacharacters or quoting characters listed above may not appear in an alias name.

metacharacter
One of the following: | & ; ( ) < > space tab

So, except for: / $ ` = | & ; ( ) < > space tab

any other character should be valid for alias and function names.

However, the character @ is also used for @(pattern-list) when extglob is active. By default extglob is active in interactive shells.

So, this should fail:

$ @(){ echo "hello"; }
bash: syntax error near unexpected token `}'

However, this works:

$  bash -c '@(){ echo "hello"; }; @'
hello

And this should work as well:

$ shopt -u extglob                 ### keep this as an independent line.
$ @(){ echo "hello"; }             
$ @
hello

It is also possible to do this:

$ f(){ echo "yes"; }
$ alias @=f
$ @
yes

An alias is flexible in what symbols it accepts.

You must log in to answer this question.

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