Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass $@ to a function in a shellscript

Problem description

In a shell script, I want to iterate over all command line arguments ("$@") from inside a function. However, inside a function, $@ refers to the function arguments, not the command line arguments. I tried passing the arguments to the function using a variable, but that doesn't help, since it breaks arguments with whitespaces.

How can I pass $@ to a function in such a way that it does not break whitespace? I am sorry if this has been asked before, I tried searching for this question and there are a lot similar ones, but I didn't find an answer nevertheless.

Illustration

I made a shell script to illustrate the problem.

print_args.sh source listing

#!/bin/sh
echo 'Main scope'
for arg in "$@"
do
    echo "    $arg"
done

function print_args1() {
    echo 'print_args1()'
    for arg in "$@"
    do
        echo "    $arg"
    done
}

function print_args2() {
    echo 'print_args2()'
    for arg in $ARGS
    do
        echo "    $arg"
    done
}

function print_args3() {
    echo 'print_args3()'
    for arg in "$ARGS"
    do
        echo "    $arg"
    done
}

ARGS="$@"

print_args1
print_args2
print_args3

print_args.sh execution

$ ./print_args.sh foo bar 'foo bar'
Main scope
    foo
    bar
    foo bar
print_args1()
print_args2()
    foo
    bar
    foo
    bar
print_args3()
    foo bar foo bar

As you can see, I can't get the last foo bar to appear as a single argument. I want a function that gives the same output as the main scope.

like image 791
jornane Avatar asked Jul 20 '15 14:07

jornane


1 Answers

You can use this BASH function:

#!/bin/bash

echo 'Main scope'
for arg in "$@"
do
    echo "    $arg"
done

function print_args1() {
    echo 'print_args1()'
    for arg in "$@"; do
        echo "    $arg"
    done
}

function print_args3() {
    echo 'print_args3()'
    for arg in "${ARGS[@]}"; do
        echo "    $arg"
    done
}

ARGS=( "$@" )

print_args1 "$@"
print_args3

You can see use of bash shebang at top:

#!/bin/bash

required be able to use BASH arrays.

Output:

bash ./print_args.sh foo bar 'foo bar'
Main scope
    foo
    bar
    foo bar
print_args1()
    foo
    bar
    foo bar
print_args3()
    foo
    bar
    foo bar
like image 188
anubhava Avatar answered Oct 11 '22 01:10

anubhava