Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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

function @() {
  echo hello
}
share|improve this question
2  
Works for me, under both recent and ancient versions of bash. What version of bash are you using? – Gilles Feb 20 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 at 3:44
    
@Gilles ah, it's due to extglob. Never mind. – muru Feb 20 at 4:12

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.

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

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]
share|improve this answer
1  
That's what the documentation says, but in fact bash is more liberal, and does accept a function called @. – Gilles Feb 20 at 1:27

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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