0

The below while loop exists within a shell of mine called test.sh

I want to run the following command

ksh -x test.sh -c -e file1 file2

I want the while loop to perform both the c) case first then e) case within the loop, however at the moment it is only performing the c) case

Can someone advise how to get it to perform both? First c) then e)

while getopts ":c:e:" opt; do
    case $opt in
        c)
            gzip -9 archivedfile
            ;;
        e)
            ksh test2.sh archivedfile
            ;;
    esac
    shift
done
DaveMac001
  • 155
  • 3
  • 13

2 Answers2

3

Based on your example script invocation:

ksh -x test.sh -c -e file1 file2
  • the '-c' option does not have an argument
  • the '-e' option does have an argument (ie, 'file1')

If this is the case, try removing the colon (:) after the letter 'c' in your getopts option string, eg:

while getopts ":ce:" opt; do

If this fixes your issue ... keep reading for more details ...


When a colon (:) follows a letter in the getopts option string, this signifies that the option has an argument, which in turn means OPTARG will be set to the next item read from the command line.

When there is no colon following a letter in the getopts option string, this signifies the option does not have an argument, which in turn means OPTARG will be unset.


We can see this behavior with the following sample scripts:

For this first script we're expecting an argument after each of our options (c,e) - notice the colon (:) after each letter (c,e) in the getopts option string:

$ cat test1.sh
#!/bin/ksh

while getopts :c:e: opt
do
        case $opt in
                c)      echo "c: OPTARG='${OPTARG:-undefined}'" ;;
                e)      echo "e: OPTARG='${OPTARG:-undefined}'" ;;
                *)      echo "invalid flag" ;;
        esac
done

A couple test runs:

$ test1.sh -c -e file1
c: OPTARG='-e'
  • because our 'c' option/flag is followed by a colon (c:), the '-e' is treated as the argument to the '-c' option; since the '-e' is consumed on this pass through getopts ...
  • there are no more option flags to process and therefore the getopts case for the 'e' option is never accessed
$ test1.sh -c filex -e file1
c: OPTARG='filex'
e: OPTARG='file1'
  • because we've provided an argument for both of our options/flags (c,e), we see that both getopts cases are processed as desired

Now, if we don't want the '-c' option to have an argument, then we need to remove the colon (:) that follows the letter 'c' in our getopts option string:

$ cat test2.sh
#!/bin/ksh

while getopts :ce: opt
do
        case $opt in
                c)      echo "c: OPTARG='${OPTARG:-undefined}'" ;;
                e)      echo "e: OPTARG='${OPTARG:-undefined}'" ;;
                *)      echo "invalid flag" ;;
        esac
done

$ test2.sh -c -e file1
c: OPTARG='undefined'
e: OPTARG='file1'
  • because our 'c' option/flag is not followed by a colon, getopts does not read any more items from the command line, which means ...
  • for the next pass through getopts the '-e' option/flag is processed and OPTARG is set to 'file1'
markp-fuso
  • 28,790
  • 4
  • 16
  • 36
0

Use ;&

case c in
       c)
           echo got c
            ;&
       c|e)
           echo got c or e
             ;;
esac

See man ksh

If ;& is used in place of ;; the next subsequent list, if any, is executed.

toting
  • 629
  • 3
  • 14