1

The script below prints positional parameters. The idea is to skip some optional arguments (where the number of optional args is given by SKIP), and then get the last two arguments. For the last arg, for example, I use an arithmetic expansion to get V2, and then indirect expansion of V2 to get A2. Running test a b c, for example, prints b and c.

Question: the two-step expansion is clunky. Is there a one-liner that will derive the value of a given arg?

#!/bin/bash

SKIP=1

# get second-from-last arg
V1=$(( SKIP+1 ))
A1=${!V1}

# get last arg
V2=$(( SKIP+2 ))
A2=${!V2}

echo A1 is $A1
echo A2 is $A2
EML
  • 9,619
  • 6
  • 46
  • 78

3 Answers3

1

$@ and bash arrays could be what you're looking for:

$ cat foo
#!/usr/bin/env bash

declare -a args=( "$@" )
declare -i skip=1
for (( i = skip; i < ${#args[@]}; i++ )); do
    printf '%d: %s\n' "$i" "${args[i]}"
done

$./foo b c d
1: b
2: c
3: d
Renaud Pacalet
  • 25,260
  • 3
  • 34
  • 51
1

If you create an array from the positional parameters, you can use array indexing to get the desired values.

args=( "$@" )
echo "${args[-1]}"  # Last argument
echo "${args[-2]}"  # Next to last argument

echo "${args[4]}"  # Get the 5th argument (zero-based indexing)
echo ${args[SKIP+3]}  # If SKIP=1, same as above.

Array indices are evaluated in an arithmetic context, the same as if you used $((...)).

chepner
  • 497,756
  • 71
  • 530
  • 681
1

Try

#! /bin/bash -p

skip=1

a1=${@:skip+1:1}
a2=${@:skip+2:1}

declare -p a1 a2

To explicitly get the values of the last two positional parameters try:

a1=${@: -2:1}
a2=${@: -1:1}
  • See the description of "Substring Expansion" (${parameter:offset:Length}) in the Shell Parameter Expansion section of the Bash Reference Manual for an explanation of ${@:skip+1:1} etc.
  • The spaces are required before -2 and -1 in the expressions that get the last two parameters. (:- does something different).
  • declare -p shows the values of variables in unambiguous ways. It's generally better than using echo (or even the generally better printf).
  • See Correct Bash and shell script variable capitalization for an explanation of why I changed the variable names to skip, a1, and a2.
pjh
  • 6,388
  • 2
  • 16
  • 17