1

How can I pass below 2 variables and the array (the dimensions will vary each time) from a linux shell script to another shell script?

logfolder=mylogfolder
processname=myname

script=(\
[1]="1 MyScript1" \
[2]="2 MyScript2 MyScript3 MyScript4 MyScript5 MyScript6 MyScript7 MyScript8 MyScript9 MyScript10 MyScript11" \
[3]="2 MyScript12 MyScript13" \
[4]="2 MyScript14 MyScript15" \
[5]="1 MyScript16" \
[6]="1 MyScript17")

1 Answer 1

1

Do you need to pass just the array's elements, or the specific index->element mappings? The reason I ask is that the example array you give has indexes 1-6, but by default a bash array would have indexes 0-5. I'm going to assume the indexes aren't important (other than order); if they need to be passed, things get a bit more complicated.

There are two fairly standardish ways to do this; you can either pass the two fixed arguments as the first two positional parameters ($1 and $2), and the array as the third on, like this:

#!/bin/bash
# Usage example:
#    ./scriptname "mylogfolder" "myname" "1 MyScript1" \
#        "2 MyScript2 MyScript3 MyScript4 MyScript5 MyScript6 MyScript7 MyScript8 MyScript9 MyScript10 MyScript11" \
#        "2 MyScript12 MyScript13" ...
logfolder=$1
processname=$2
script=("${@:3}")

Or, if the two values are optional, you could make them options that take parameters, like this:

#!/bin/bash
# Usage example:
#    ./scriptname -l "mylogfolder" -p "myname" "1 MyScript1" \
#        "2 MyScript2 MyScript3 MyScript4 MyScript5 MyScript6 MyScript7 MyScript8 MyScript9 MyScript10 MyScript11" \
#        "2 MyScript12 MyScript13" ...

while getopts "l:p:" o; do
    case "${o}" in
        l)
            logfolder =${OPTARG} ;;
        p)
            processname =${OPTARG} ;;
        *)
            echo "Usage: $0 [-l logfolder] [-p processname] script [script...]" >&2
            exit 1
            ;;
    esac
done
shift $((OPTIND-1))

script=("${@}")

In either case, to pass an array, you'd use "${arrayname[@]}" to pass each element as a separate argument to the script.

[EDIT] Passing the array indexes with the elements is more complicated, since the arg list is basically just a list of strings. You need to somehow encode the indexes along with the elements, and then parse them out in the script. Here's one way to do it, using index=element for each thing in the array:

#!/bin/bash
# Usage example:
#    ./scriptname "mylogfolder" "myname" "1=1 MyScript1" \
#        "2=2 MyScript2 MyScript3 MyScript4 MyScript5 MyScript6 MyScript7 MyScript8 MyScript9 MyScript10 MyScript11" \
#        "3=2 MyScript12 MyScript13" ...

logfolder=$1
processname=$2
# Parse arguments 3 on as index=element pairs:
declare -a script=()
for scriptarg in "${@:3}"; do
    index=${scriptarg%%=*}
    if [[ "$index" = "$scriptarg" || -z "$index" || "$index" = *[^0-9]* ]]; then
        echo "$0: invalid script array index in '$scriptarg'" >&2
        exit 1
    fi
    script[$index]=${scriptarg#*=}
done

And to call it, you'd need to package up the script array in the appropriate format something like this:

# Convert the normal script array to a version that has "index=" prefixes
scriptargs=()
for index in "${!script[@]}"; do    # iterate over the array _indexes_
    scriptargs+=("${index}=${script[$index]}")
done

./script.sh "$logfolder" "$processname" "${scriptargs[@]}"
Sign up to request clarification or add additional context in comments.

1 Comment

I am using the script array actually as a two dimensional array therefore [1] through [6] and their values is necessary to be unpacked at the receiving script in the right order. That will be the only array passed to the script and it can be the starting third and the last parameter but it's both dimensions will be variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.