5

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

function @() {
  echo hello
}
  • 2
    Works for me, under both recent and ancient versions of bash. What version of bash are you using? – Gilles Feb 20 '16 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 '16 at 3:44
  • @Gilles ah, it's due to extglob. Never mind. – muru Feb 20 '16 at 4:12
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
    That's what the documentation says, but in fact bash is more liberal, and does accept a function called @. – Gilles Feb 20 '16 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.

  • 1
    Doesn't work for me on 4.3.11. In fact, I had to nuke the shell process. – Jon Carter Feb 19 '16 at 0:02
  • I forgot the semicolon. Why did you nuke the shell process? – kba Feb 19 '16 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 '16 at 0:11
  • Weird, I just tested it in a 4.3.11 as well, works fine for me. – kba Feb 19 '16 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 '16 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.