build argument lists containing whitespace

In bash one can escape arguments that contain whitespace.

foo "a string"

This also works for arguments to a command or function:

bar() {
    foo "$@"
}

bar "a string"

So far so good, but what if I want to manipulate the arguments before calling foo?

This does not work:

bar() {
    for arg in "$@"
    do
        args="$args \"prefix $arg\""
    done

    # Everything looks good ...
    echo $args

    # ... but it isn't.
    foo $args

    # foo "$args" would just be silly
}

bar a b c

So how do you build argument lists when the arguments contain whitespace?

There are (at least) two ways to do this:

  1. Use an array and expand it using "${array[@]}":

    bar() {
        local i=0 args=()
        for arg in "$@"
        do
            args[$i]="prefix $arg"
            ((++i))
        done
    
        foo "${args[@]}"
    }
    

    So, what have we learned? "${array[@]}" is to ${array[*]} what "$@" is to $*.

  2. Or if you do not want to use arrays you need to use eval:

    bar() {
        local args=()
        for arg in "$@"
        do
            args="$args \"prefix $arg\""
        done
    
        eval foo $args
    }
    

Unix shell script, parameters with spaces, If you don't quote the file name, the shell has no way of knowing that foo bar.txt is one parameter and not two ( foo and bar.txt ). You therefore need to call your  With the Fall Creators Update I can't figure out a way to pass arguments with spaces to a process running under cmd.exe. Consider the following program compiled to args.exe: #include <stdio.h> int main(int argc, char **argv) { int i; pri

Here is a shorter version which does not require the use of a numeric index:

(example: building arguments to a find command)

dir=$1
shift
for f in "$@" ; do
    args+=(-iname "*$f*")
done
find "$dir" "${args[@]}"

Using a generated list of filenames as argument list -- with spaces , The ability to do what we're doing with xargs is literally built into find . So find will find a list of files and then pass that list as as many arguments as can fit to the  again. You can then safely manipulate lists of file names using all the GNU Make functions. Just be sure to remove the +'s before using these names in a rule. s+ = $(subst \\ ,+,$1) +s = $(subst +,\\ ,$1) Here's a fuller example where a list of source files that contain escaped spaces is

Use arrays (one of the hidden features in Bash).

problem passing arguments with spaces to a process running under , Consider the following program compiled to args.exe: #include int to host and review code, manage projects, and build software together. bash - build argument lists containing whitespace - Stack Overflow In bash one can escape arguments that contain whitespace. foo "a string" This also works for arguments to a command or function: bar() { foo "$@" } bar "a string" So far so good, but what

You can use the arrays just as you suggest, with a small detail changed. The line calling foo should read

 foo "${args[@]}"

api.run() does not support arguments containing whitespace · Issue , There is no mechanism for quoting spaces, so e.g. a file or directory with a to host and review code, manage projects, and build software together. Issues #​2727 #2728: api.run now accepts a list of command args and  List operations. Some functions are flagged as not tail-recursive. A tail-recursive function uses constant stack space, while a non-tail-recursive function uses stack space proportional to the length of its list argument, which can be a problem with very long lists.

I had a problem with this too as well. I was writing a bash script to backup the important files on my windows computer (cygwin). I tried the array approach too, and still had some issues. Not sure exactly how I fixed it, but here's the parts of my code that are important in case it will help you.

WORK="d:\Work Documents\*"
#   prompt and 7zip each file
for x in $SVN $WEB1 $WEB2 "$WORK" $GRAPHICS $W_SQL
do
    echo "Add $x to archive? (y/n)"
    read DO
    if [ "$DO" == "y" ]; then
        echo "compressing $x"
        7zip a $W_OUTPUT "$x"
    fi
    echo ""
done

Arguments, An array of arguments: A list of strings that tell the program what to do. There is no more whitespace left after word splitting is done with your line. The shell now uses these chunks to build its execve(2) system call. If the argument is a string, it must contain a possibly signed decimal number of arbitrary size, possibly embedded in whitespace; this behaves identical to string.atol(x). Otherwise, the argument may be a plain or long integer or a floating point number, and a long integer with the same value is returned.

Python 3 Notes: Split and Join, This list contains 5 items as the len() function demonstrates. len() on mary, hi.​split() # no parameter given: splits on whitespace ['Hello', 'mother,', 'Hello', More generally, list() is a built-in function that turns a Python data object into a list. If the build was triggered by another build, then this variable is set to ID of the project that contains the triggering build. This variable is agent-scoped. It can be used as an environment variable in a script and as a parameter in a build task, but not as part of the build number or as a version control tag.

Arguments with whitespace, include a way to escape spaces if someone comes up with a way to do > it that is cross http://groups.google.com/group/simple-build-tool?hl=en. > > > Sign in to command as an arg, so I don't think that would work either. {} as the argument list marker {} is the default argument list marker. You need to use {} this with various command which take more than two arguments at a time. For example mv command need to know the file name. The following will find all .bak files in or below the current directory and move them to ~/.old.files directory:

Nodes, Normally any whitespace/comments are assigned to the next node visited, Dotted variable names ( a.b.c ) are represented with Attribute nodes, and The expression that should be transformed (e.g. negated) by the operator to create a new value. These are not the parenthesis before and after the list of args , but rather 

Comments
  • damn, should have gotten here earlier -- could have spared you the work :)
  • shift doesn't work like that in Bash. It should be dir=$1; shift instead.
  • Indeed, fixed it.
  • how exactly? I have updated my question with an attempt to use an array - which didn't work.
  • There does not seem to be an easy way to pass arrays to functions (which really are subshells). You'd need to quote them and pass them as regular argument (as you would to any other command).