Define function in unix/linux command line (e.g. BASH)

16,052

Solution 1

Quoting my answer for a similar question on Ask Ubuntu:

Functions in bash are essentially named compound commands (or code blocks). From man bash:

Compound Commands
   A compound command is one of the following:
   ...
   { list; }
          list  is simply executed in the current shell environment.  list
          must be terminated with a newline or semicolon.  This  is  known
          as  a  group  command. 

...
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.
   ... [C]ommand is usually a list of commands between { and },  but
   may  be  any command listed under Compound Commands above.

There's no reason given, it's just the syntax.

Try with a semicolon after wc -l:

numresults(){ ls "$1"/RealignerTargetCreator | wc -l; }

Solution 2

Don't use ls | wc -l as it may give you wrong results if file names have newlines in it. You can use this function instead:

numresults() { find "$1" -mindepth 1 -printf '.' | wc -c; }

Solution 3

You can also count files without find. Using arrays,

numresults () { local files=( "$1"/* ); echo "${#files[@]}"; }

or using positional parameters

numresults () { set -- "$1"/*; echo "$#"; }

To match hidden files as well,

numresults () { local files=( "$1"/* "$1"/.* ); echo $(("${#files[@]}" - 2)); }
numresults () { set -- "$1"/* "$1"/.*; echo $(("$#" - 2)); }

(Subtracting 2 from the result compensates for . and ...)

Solution 4

You can get a

bash: syntax error near unexpected token `('

error if you already have an alias with the same name as the function you're trying to define.

Share:
16,052

Related videos on Youtube

abalter
Author by

abalter

Updated on September 19, 2022

Comments

  • abalter
    abalter over 1 year

    Sometimes I have a one-liner that I am repeating many times for a particular task, but will likely never use again in the exact same form. It includes a file name that I am pasting in from a directory listing. Somewhere in between and creating a bash script I thought maybe I could just create a one-liner function at the command line like:

    numresults(){ ls "$1"/RealignerTargetCreator | wc -l }
    

    I've tried a few things like using eval, using numresults=function..., but haven't stumbled on the right syntax, and haven't found anything on the web so far. (Everything coming up is just tutorials on bash functions).

    • abalter
      abalter about 8 years
      tell me the number of files in the directory $1/RealignerTargetCreator.
    • sjas
      sjas about 6 years
      you re missing the semicolon at the end. ... ; }
  • abalter
    abalter about 8 years
    Thanks. It's always good to deepen one's bash skills! Just curious, how could a file name have a newline in it?
  • anubhava
    anubhava about 8 years
    You can use touch $'file\nwith\nline' to create a filename with newlines
  • abalter
    abalter about 8 years
    Well, that was simple! (I mean the semicolon). Again, its always good to get a deeper understanding of how the shell works.
  • muru
    muru about 8 years
    @abalter Yep. That's why it's a mantra: Don't parse ls output.
  • chepner
    chepner about 8 years
    The semicolon is necessary because } is not a control character and does not terminate a command. Notice echo } simply outputs the literal string.
  • muru
    muru about 8 years
    @chepner That's just pushing the question one level down. Those who created the grammar could make } special for functions. zsh, for example, has no problems with foo () {echo foo}.
  • chepner
    chepner about 8 years
    I'm describing what is, not what could be.
  • muru
    muru about 8 years
    The first of the hidden files functions could use dotglob, since it's using arrays anyway.
  • muru
    muru about 8 years
    @chepner And I'm saying it isn't necessary, it's just the way the syntax is.
  • chepner
    chepner about 8 years
    Hm, for some reason I remembered dotglob matching . and .. as well, but it doesn't.
  • ArunMKumar
    ArunMKumar about 7 years
    great that it worked for you guys, for me it just gives "bash: syntax error near unexpected token `(' ". >> bash 4.1.2 on RHEL <<