1

I have to check if particular argument lets say 'java8' is present in my shell arguments to script and if it is present remove it . Also I want it to be stored in some other variable , but want it to be removed from my $*.

One option I Trie checking if arg is present using getopts but I dont know how to remove argument .

Please note - the position of arg to check 'java8' is not known I can be at any place

while getopts "f:" flag
do
     case $flag in
         f)
           echo $OPTARG
           ;;
     esac
done
echo $*
~

So basically when I invoke -

./test.sh arg1 arg2 -f java8 arg3

after execution of getopts block the remaining args will be

arg1 , arg2 , arg3

3
  • Which one do you want to remove, just java8 or the two back-to-back arguments -f and java8? At first you only mention java8, but the code you have looks for the -f option, and your example involves -f and java8. I suppose you don't want to remove -f if it's followed by any other argument?
    – ilkkachu
    Jul 12, 2022 at 18:03
  • getopts can be used to process options passed the standard way as in cmd -f java8 arg1 arg2 arg3, cmd -fjava8 -- arg1 arg2 arg3. In standard option processing, you can't have options after non-options, so you can't use getopts to parse the options as seen in your example script invocation (unless you first remove those 2 arg1 arg2 before the first options before processing the first invocation of getopts). Jul 12, 2022 at 18:06
  • Do you want the arguments removed so later code in the script will not see them, or do you also want the arguments to no longer be visible in process listings ps?
    – Sotto Voce
    Jul 12, 2022 at 19:39

2 Answers 2

1

For any POSIX shell (without using a temporary array): Dropping any instance of -f followed by java8, or of -fjava8, from the list of positional parameters, while counting the number of such dropped options-with arguments in the variable found.

skip=0 found=0
for arg do
    case $1 in
        -f)
            if [ "$2" = java8 ]; then
                skip=2
                found=$(( found + 1 ))
            fi
            ;;
        -f*)
            if [ "$1" = -fjava8 ]; then
                skip=1
                found=$(( found + 1 ))
            fi
    esac

    if [ "$skip" -eq 0 ]; then
        set -- "$@" "$1"
    else
        skip=$(( skip - 1 ))
    fi
    shift
done

if [ "$skip" -eq 1 ]; then
    set -- "$@" -f
    found=$(( found - 1 ))
fi

printf 'Args: %s\n' "$*"
printf 'Found = %d\n' "$found"

The above loop iterates as often as the initial number of positional parameters.

If the first positional parameter is -f, the second positional parameter is tested to see whether it's java8. If the test is true, then we need to skip these two arguments, so the skip counter is set to 2. We also increment found to indicate that we've found one more instance of -f java8.

If the first positional parameter is -fjava8, then we need to skip this single argument, so the skip counter is set to 1. We also increment found to indicate that we've found one more instance of -fjava8 (the same as finding -f java8).

After the case statement, we don't do anything other than decrement the skip counter and shift off the first positional parameter if skip is non-zero. If skip is zero, we move the first positional parameter to the end of the list before calling shift, effectively allowing the arguments we keep to cycle back through the list while dropping the unwanted arguments.

Since we're using the list of positional parameters in a cyclic way, we would lose the last argument if it was -f and the first argument was java8. This is what the last if statement protects against.

0

Maybe something like this? I'm assuming you want to remove -f java8...

#!/bin/bash

while (( $# )); do
    if [[ $1 = "-f" ]] && [[ $2 = "java8" ]]; then
        shift 2
        continue
    fi

    args+=( "$1" )
    shift
done

echo "${args[*]}"

Example usage:

$ ./argtest.sh one two three
one two three
$ ./argtest.sh one two -f java8 three four
one two three four
$ ./argtest.sh -f java8 -f foo -f bar
-f foo -f bar
1
  • This works but i want to retain $* which is very critical for script to take on rest of parameters Jul 15, 2022 at 15:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .