LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Bash Script Read Output of One Function In Another Function (https://www.linuxquestions.org/questions/linux-newbie-8/bash-script-read-output-of-one-function-in-another-function-4175636897/)

bluethundr 08-22-2018 02:56 PM

Bash Script Read Output of One Function In Another Function
 
Hello,

I have two functions in my bash script. One creates AWS EC2 instances and the other creates EBS volumes.

In the create_instance function I ask the user if he wants to create a volume and how many. The create_volume function also has user prompts.

I want to read the user prompts from the pipeline to create_volume in the create_instances function.

This is an example of the create_instances function:

Code:

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
}

If I use read -rp I can see the variables appear when I invoke create_volume from the create_instances.

For example in these lines from create_volume:

Code:

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

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

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

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

When I invoke the create_volume function from create_instances I see the variable, but not the user prompt.

For example, when I invoke this pipeline in create_instances:
Code:

volumes[$i]="$(create_volume)"
Of these lines in create_volume that get called:
Code:

printf "Enter a volume name: "
    read -r volume_name

I see only the variable name from the create_instances function:
Code:

volume_name
But how do I see the user prompt from create_volume from the create_instances function? Is there a way to see only the user prompt (Enter a volume name: ) and NOT the variable (volume_name)?
Code:

printf "Enter a volume name: "
Thanks

lougavulin 08-22-2018 05:13 PM

I did not try to simulate your case, but if I understood, I guess this will work.

You have to call create_volume outside of a subshell. So in create_instances :
Replace :
Code:

volumes[$i]="$(create_volume)"
By
Code:

CURID=''
create_volume 'CURID'
volumes[$i]=${CURID}

And in create_volume
Replace :
Code:

echo "$volume_id"
By
Code:

local VOLID=$1
eval $VOLID="$volume_id"

In some way, CURID is a reference paramter for create_volume function. :)

bluethundr 08-23-2018 10:02 AM

Thanks
 
Quote:

Originally Posted by lougavulin (Post 5894607)
I did not try to simulate your case, but if I understood, I guess this will work.

You have to call create_volume outside of a subshell. So in create_instances :
Replace :
Code:

volumes[$i]="$(create_volume)"
By
Code:

CURID=''
create_volume 'CURID'
volumes[$i]=${CURID}

And in create_volume
Replace :
Code:

echo "$volume_id"
By
Code:

local VOLID=$1
eval $VOLID="$volume_id"

In some way, CURID is a reference paramter for create_volume function. :)


Thank you very much! That worked absolutely perfectly. I would love to understand how you figured that out, if you would like to share. If not or too busy all good! Still really appreciate the advice.

lougavulin 08-25-2018 07:45 AM

Sorry if I am not clear...

I suppose it is how you look at a problem. And once understood, try to figure out how to fix it. I guess bash script experience helps. :) Because you know what works or not.

Lets take an example, here is a script :
Code:

function A
{
  echo 'I am function A'
}

function B
{
  echo 'I am function B, I am calling function A'
  RA=$(A)
}

echo 'I am main, I am calling function B'
B

If you run it, it returns :
Quote:

I am main, I am calling function B
I am function B, I am calling function A
A and B are both functions, we can see B's echo and not A's echo.
This was your problem, as simple as it is when you throw away everything else.

So what is the difference ? The ways A and B are called.
Calling A in a subshell :
Code:

  RA=$(A)
and everything that A echoes (on the standard output) is into RA.

Add :
Code:

  echo "RA = ${RA}"
at the end of B function, it returns :
Quote:

I am main, I am calling function B
I am function B, I am calling function A
RA = I am function A
So we understand the problem. And thanks to my bash script experience, I know that RA store every A's echoes. So I did not need to try it.

Now how to fix it ? I guess there is several ways.
You can probably play with standard and error outputs. But the main idea for me was to call A as B, meaning outside of a subshell.
But doing this means to find a new way to get the result of A, what we really want.
'return' can not be apply because it has to be integer.
So, it was using either global variable, either parameter's function by reference. Both works. I just went with the sexier. :redface:


All times are GMT -5. The time now is 03:57 AM.