Home > Back-end >  Call a bash function with random positional and more readable arguments
Call a bash function with random positional and more readable arguments

Time:12-30

To demonstrate this question, this is a simple example how can we call a function in bash and the arguments need to be passed in fixed order:

sample.sh


#!/bin/bash

# function
service() {

 local service="$1" price="$2" level="$3"

 echo "The service: $service"
 echo "The price: $price"
 echo "The level: $level"
 
}


# function call

service "repair" "10" "high"

The above will output:

The service: repair
The price: 10
The level: high

The issue with the above function call is that I cannot pass the arguments in random order but I can create a getop inside the function service() for workaround:

sample.sh

#!/bin/bash

# function
service() {
  local service price level short_opts long_opts options
  service=""
  price=""
  level=""
  short_opts=""
  long_opts="service:,price:,level:"

  options=$(getopt -o "${short_opts}" --long "${long_opts}" -n "example" -- "$@")
  eval set -- "${options}"
  while true; do
    case "${1}" in
    --service)
      service="${2}"
      shift 2
      ;;
    --price)
      price="${2}"
      shift 2
      ;;
    --level)
      level="${2}"
      shift 2
      ;;
    --)
      shift
      break
      ;;
    *)
      echo "Invalid option: ${1}"
      exit 1
      ;;
    esac
  done

  echo "The service: $service"
  echo "The price: $price"
  echo "The level: $level"
}

# function call with random positional parameters

service --service "repair" --price "10" --level "high"
echo ""
service --price "5" --service "computer" --level "medium"

The above will output this:

The service: repair
The price: 10
The level: high

The service: computer
The price: 5
The level: medium

As you can see I have to use getopt to make make this function call more flexible and it is more readable. Is there any other method that I can use instead of getopt above? Having a dozen functions and it's going to be a long codes if I use this way.

CodePudding user response:

Pass everything in the environment:

#!/bin/bash

service() {

        : ${service="default service"}
        : ${price="default price"}
        : ${level="default level"}

        echo "The service: $service"
        echo "The price: $price"
        echo "The level: $level"
}

service=repair price=15 service
service=install level=5 service
service=install price=10 level=5 service

This will produce:

The service: repair
The price: 15
The level: default level
The service: install
The price: default price
The level: 5
The service: install
The price: 10
The level: 5

You can mix positional parameters with something like:

#!/bin/bash

service() {
    : ${service=${1-"default service"}}
    : ${price=${2-"default price"}}
    : ${level=${3="default level"}}
    echo "The service: $service"
    echo "The price: $price"
    echo "The level: $level"
}

level=supreme service install 15
  •  Tags:  
  • bash
  • Related