0

I want to write one script something like below with the long option to be provided by user in cmd line argument.

example:

./script.sh --user username --branch branchname --start_time yyy-mm-dd

If possible ignore the order. Not sure if we can apply the logic to ignore the order. Also, force user to provide the value otherwise throw error message that missing value.

Pasting code block

script_name=$(basename "$0")
short=u:c:e:p:b:t:n:
long=user:,component:,engagement:,product:,branch:,tag:,name:,help

TEMP=$(getopt -o $short --long $long --name "$script_name" -- "$@")

eval set -- "${TEMP}"
while :; do
    case "${1}" in
        -u | --user         ) user="$2";            shift 2 ;;
        -c | --component    ) comp="$2"; COMP=$(echo $comp | tr [:upper:] [:lower:]) ;               shift 2 ;;
        -e | --engagement   ) eng="$2"; ENG=$(echo $eng | tr [:lower:] [:upper:]) ;                  shift 2 ;;
        -p | --product      ) product="$2"; PRODUCT=$(echo $product | tr [:lower:] [:upper:]) ;      shift 2 ;;
        -b | --branch       ) branch="$2";          shift 2 ;;
        -t | --tag          ) tag="$2";             shift 2 ;;
        -n | --name         ) name="$2";            shift 2 ;;
        --help              ) usage;                exit 0 ;;
        --                  ) shift;               break  ;;
        *                   ) echo "invalid option"; exit 1 ;;
    esac
done
dell xps
  • 41
  • 5
  • 2
    See https://stackoverflow.com/questions/402377/using-getopts-to-process-long-and-short-command-line-options – Diego Torres Milano Feb 02 '22 at 06:20
  • 1
    Welcome to Stackoverflow. Yes, `getopt` can do that. Did you try already? – Dima Chubarov Feb 02 '22 at 06:21
  • The reference is quite confusing for me. Better if someone can write simple and straight forward as per my use case. Pretty new to Bash script. Thanks – dell xps Feb 02 '22 at 07:13
  • 1
    Welcome on StackOverflow. StackOverflow is not a free coding service. You are supposed to show what you tried up to now and explain why it did not work as expected. As you are new here you could also take a look at the [help center](https://stackoverflow.com/help) and especially at the [asking section](https://stackoverflow.com/help/asking). – Renaud Pacalet Feb 02 '22 at 08:32
  • See [here](https://stackoverflow.com/a/70595823/402322) for an example. The example shows both: short options with `getopts` and long options with `getopt`. – ceving Feb 02 '22 at 11:09

1 Answers1

1
script_name=$(basename "$0")
short=u:b:s:
long=user:,branch:,start_time:,help

read -r -d '' usage <<EOF
Manually written help section here
EOF

TEMP=$(getopt -o $short --long $long --name "$script_name" -- "$@")

eval set -- "${TEMP}"

while :; do
    case "${1}" in
        -u | --user       ) user=$2;             shift 2 ;;
        -b | --branch     ) branch=$2;           shift 2 ;;
        -s | --start_time ) start_time=$2;       shift 2 ;;
        --help            ) echo "${usage}" 1>&2;   exit ;;
        --                ) shift;                 break ;;
        *                 ) echo "Error parsing"; exit 1 ;;
    esac
done

Set your short and long options. A colon implies it needs an option argument. Short options are written with no delimiter, long options are comma delimited.

The getopt command makes sure items come in an easily parsable order. In this example, we use a case statement to parse each option. All options are parsed first and then removed from $@.

What's left are the passed arguments that is not part of any defined option.

Kaffe Myers
  • 424
  • 3
  • 9
  • Thanks you .Make sense – dell xps Feb 02 '22 at 11:44
  • I used the above script. However, while providing other thing .Script is not exiting. Example: ./test.sh 9 should exit the script as this is not valid option – dell xps Feb 03 '22 at 11:24
  • 1
    Hard time seeing my code being an issue. Gonna guess you added an option and forgot a `shift` somewhere. – Kaffe Myers Feb 04 '22 at 18:07
  • I have added the image above and modifed the code .Please have a look – dell xps Feb 04 '22 at 18:54
  • 1
    Post it as a code block and I can look at it when I have time. I don't feel like transcribing that. :) – Kaffe Myers Feb 04 '22 at 19:30
  • Done added code block – dell xps Feb 07 '22 at 08:05
  • 1
    I missread your comment at first... Oh well. To quote myself "What's left are the passed arguments that is not part of any defined option.". This means you have to handle that situation. If you don't accept any other input than options and their arguments, you could just add `(( ${#@} == 0 )) || { echo 'Input not allowed' ; exit 1 ;}` or something of the like. Same goes with any other prereqs. Need a user to run script? Then you must handle that. `getopt` deals with options, but conditionals you have to write. – Kaffe Myers Feb 09 '22 at 14:48
  • 1
    Also wish to add that the `echo ... | tr` routine you are doing is unnecessary. To get lower case into a var: `var=${2,,}` and to get upper case: `var=${2^^}` – Kaffe Myers Feb 09 '22 at 14:53
  • 1
    Glad I could help! Please accept the answer if you are satisfied with it. :) – Kaffe Myers Feb 12 '22 at 15:24