bluethundr
bluethundr

Reputation: 1325

invoke bash function with user prompts from another function

I have a bash script with a function that creates AWS instances. It calls another function that creates volumes and captures the output of that function in the calling function. The create volume function has user prompts.

In the create_instances function I has these lines that captures the output of create_volume:

create_instances() {
  ...lines to create the instance...
  printf "Number of volumes to add: "
  read -r num_volumes
  volumes=()
  for (( i=0; i < num_volumes; i++ )); do
    volumes[$i]="$(create_volume)"
      .... lines to attach volume...
   done

}

And no prompt appears on the screen like it would if you invoked create_volume separately.

In the create_volume function I have user prompts that asks for volume size, availability zone, volume name etc. When create_instances calls this function to get the output, create_instances hangs and waits for user input. And you see nothing on the screen while this happens.

create_volume() {
    printf "Enter a volume name: "
    read -r volume_name

    #Availability Zones
    printf "Enter availability zone\\nExample. Type out: us-east-1a\\n"
    printf "AZ: "
    read -r availability_zone
    echo

    # Volume Size
    printf "Enter size: "
    read -r volume_size
    echo

    ...lines that create the volume...
    echo "$volume_id"
}

How can I capture the output of create_volume in the create_instances function and allow for the prompts that are needed in the create_volume function?

I need the prompts to appear when I use this pipeline: volumes[$i]="$(create_volume)"

Upvotes: 0

Views: 50

Answers (1)

glenn jackman
glenn jackman

Reputation: 246799

use the -p option for read to set the prompt. That takes care of the rest:

create_volume() {
    local volume_name availability_zone volume_size
    read -rp "Enter a volume name: " volume_name
    read -rp $'Enter availability zone\nExample. Type out: us-east-1a\nAZ: ' availability_zone
    read -rp "Enter size: " volume_size

    # ...lines that create the volume...
    local volume_id="$volume_name,$availability_zone,$volume_size"
    echo ">>> $volume_id"
}

Interactively, the prompts are visible

$ create_volume
Enter a volume name: a
Enter availability zone
Example. Type out: us-east-1a
AZ: b
Enter size: c
>>> a,b,c

In a pipeline, they are not:

$ volume_id=$( printf '%s\n' foo bar baz | create_volume )
$ echo "$volume_id"
>>> foo,bar,baz

Upvotes: 3

Related Questions