1

I want to do a argument parser inside one argument.

Here is my launcher ./bin/kube/launch_market_quality_job.sh -e staging -j job_example

And here my script.

while [ ${#} -ne 0 ]; do
  case "${1}" in
    --environment | -e)
      shift;
      export ONE_ENVIRON=${1};
      case $ONE_ENVIRON in
        staging)
          export REPOSITORY=<DTR>
          ;;
        production)
          export REPOSITORY=<DTR>
          ;;
        *)
          fail "You must provide the environment [staging|production]"
          ;;
      esac
      ;;
    --job | -j )
      shift;
      export JOB=${1}
      case $JOB in
          job_example_extra_args)
          case "${1}" in
          --name | -n )
          export $NAME=${1}
      [... extra args]
      ;;
    *)
      help
      exit
      ;;
  esac
  shift
done

What I want to do is depending on "--j | -job" option, is to parse two more options depending if the jobs if one or another.

For example a normal job , called 'job_example' with the previous launcher it works correctly.

But if my job is 'job_example_extra_args' I need a new argument called 'name'.

`./bin/kube/launch_market_quality_job.sh -e staging -j job_example_extra_args --name "Jesus"`

I dont know how is the correct way, if this 'job_example_extra_args' is called, I want to obtain the flag correctly, and if its not included the script should fail or stop. I want to add the flags options inside the --job flag, for activating it if the job is the one I want to.

fiticida
  • 664
  • 1
  • 10
  • 24

2 Answers2

1

I would catch all arguments and perform a check after all arguments are parsed, e.g.:

unset ONE_ENVIRON JOB NAME
while [ ${#} -ne 0 ]; do
  case "${1}" in
    --job | -j )
      shift;
      export JOB=${1}
      ;;
  case "${1}" in
    --name | -n )
      shift
      export NAME=${1}
      ;;
  esac
  shift
done

if [ "$JOB" = job_example_extra_args ] && [ -z "$NAME" ]; then
  fail "You must provide a name for this job"
fi

This way, it does not matter if the user passes the --name NAME argument before or after the --job JOBNAME argument. All that matters is that the complete list of necessary arguments have been given at some point.

You could also report an error if the --name must be passed exclusively with the job_example_extra_args job:

if [ "$JOB" != job_example_extra_args ] && [ -n "$NAME" ]; then
  fail "You must NOT provide a name for this job"
fi

PS. I am not showing --environment|-e nor * for clarity but there’s nothing wrong with them.

vdavid
  • 2,434
  • 1
  • 14
  • 15
1

You could embed the secondary argument parsing inside the primary ("job") parse by inserting a complete parse loop inside each alternative job. But that's going to be hard to maintain, because the job-related logic becomes divorced from the job implementation.

Perhaps a better solution is to create an argument-parser+launcher for each job. Since you have already shifted the parsed arguments out of the way, you can just source an appropriate script using the . command. (Many shells allow source as a synonym for ..) Note that if you don't specify arguments after the filename in the . command, the existing arguments will not be altered so your unprocessed arguments will just get passed through. (For Posix shells, . might not even accept arguments following the filename.)

rici
  • 234,347
  • 28
  • 237
  • 341