0

I'm writing a bash script that performs a number of common functions in AWS.

When I run the script the functions I'm trying to call are not run, and the script ends with the message "Your work in AWS is done":

These are the AWS Accounts:
1 Lab
2 Billing

Please enter a number for the account you want to work in.
Account Number: 
1
These are the actions possible in AWS: 
1 Add User and Access Keys
2 Delete Snapshots
Enter an action in AWS: 
1

Your work in AWS is done.
Your work in AWS is done.

The two functions in my script that lay the ground work for the rest of the script are called:

  • choose_account
  • choose_action

choose_account sets the AWS account you will work in. choose_action sets a variable called user_action that contains the name of a function.

But when I try to call the function in the if/else statements at the end of the script no function gets called and the script ends with "Your work is done in AWS."

Here is my script:

#!/usr/bin/env bash

PATH=/home/myuser/.local/bin:$PATH

choose_account(){

echo "These are the KPMG AWS Accounts:"
  echo "1 Lab"
  echo "2 Billing"
  echo
  echo "Please enter a number for the account you want to work in."
  echo "Account Number: "
  read -r aws_account_number

if [ "$aws_account_number" -eq 1 ]; then
     declare -i accountnumber=423214542344
     return
  elif [ "$aws_account_number" -eq 2 ]; then
     declare -i accountnumber=188523423411
     return
  else
     echo "Unkown account"
  fi

  echo
  echo
}

choose_action(){

  echo "These are the actions possible in AWS: "
  echo "1 Add User and Access Keys"
  echo "2 Delete Snapshots"
  echo "Enter an action in AWS: "
  read -r action
  echo
  echo
  if [ "$action" -eq "1" ]; then
     user_action=add_user
     aws_file="source_files/aws_environments_nonprod.txt"
     return
  elif [ "$action" = ="2" ]; then
     user_action=add_user
     aws_file="source_files/aws_snapshots_prod.tx"
     return
  else
     echo "Action Not Chosen"
  fi
}

add_user(){
aws_user="us-svc-food"
aws_group1="grp-read-only"
aws_group2="grp-food-read-only"

IFS=$'\n'
set -f
for i in $aws_file
do
    echo "adding user: $aws_user to account: $i"
    aws iam create-user --user-name $aws_user --output=json --profile="$i"
        echo
        sleep 5
        echo "add user: $aws_user to group: $aws_group1"
        aws iam add-user-to-group --user-name $aws_user --group-name $aws_group1 --output=json --profile="$i"
        sleep 5
        echo "add user: $aws_user to group: $aws_group2"
        aws iam add-user-to-group --user-name $aws_user --group-name $aws_group2 --output=json --profile="$i"
        sleep 5
        echo
        echo "verify the user $aws_user is there in: $i"
        aws iam get-user --user-name $aws_user --output=json  --profile="$i"
        sleep 5
        echo
        echo "*************************************************"
        echo "creating the access key for $aws_user to account: $i"
        aws iam create-access-key --user-name $aws_user --output=json --profile="$i"
        echo "**************************************************"
        sleep 30
        echo
        echo "verify the user access keys for $aws_user on account: $i"
        aws iam list-access-keys --user-name $aws_user --output=json --profile="$i"
        echo
        echo "***************************************************"
        echo
    sleep 5
done
set +f
unset IFS
}

delete_snapshots(){
IFS=$'\n'
set -f
for i in $aws_file
do
  echo "*****************************************************************"
  echo "Deleting snapshot: $i:"
  aws ec2 delete-snapshot --snapshot-id="$i" --profile="$aws_key" 2>&1 | sed -e 's/^An error occurred.*when calling the DeleteSnapshot operation: //'
  echo "*****************************************************************"
  echo; echo; echo; echo; echo
  sleep 5
  echo "*****************************************************************"
  echo "Verify that snapshot: $i is gone:"
  aws ec2 describe-snapshots --snapshot-ids="$i" --profile="$aws_key" 2>&1 | sed -e 's/^An error occurred.*when calling the DescribeSnapshots operation: //g'
  echo "*****************************************************************"
  echo; echo; echo; echo; echo
done
set +f
unset IFS
}

choose_account
choose_action

declare -a arr=("423214542344" "188523423411")
for i in "${arr[@]}"
do
  if [ "$accountnumber" == 423214542344 ]; then
     aws_account="AWS Lab"
     aws_key="kpmg-lab"
     echo "$user_action in account: $aws_account"
     "$user_action"
     return
  elif [ "$accountnumber" == 188523423411 ]; then
     aws_account="AWS Billing"
     aws_key="kpmg-bill"
     echo "$user_action in account: $aws_account"
     "$user_action"
     return
  else
     echo "Your work in AWS is done."
  fi
done

I want $user_action to be a function invocation.

EDIT:

I've created some verbose output.

PS4=':$BASH_SOURCE:$LINENO+' bash -x aws_tools_test.sh 
    :aws_tools_test.sh:3+PATH=/home/myuser/.local/bin:/home/myuser/bin:/home/myuser/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
    :aws_tools_test.sh:113+choose_account
    :aws_tools_test.sh:7+echo 'These are the KPMG AWS Accounts:'
    These are the KPMG AWS Accounts:
    :aws_tools_test.sh:8+echo '1 Lab'
    1 Lab
    :aws_tools_test.sh:9+echo '2 Billing'
    2 Billing
    :aws_tools_test.sh:10+echo

    :aws_tools_test.sh:11+echo 'Please enter a number for the account you want to work in.'
    Please enter a number for the account you want to work in.
    :aws_tools_test.sh:12+echo 'Account Number: '
    Account Number: 
    :aws_tools_test.sh:13+read -r aws_account_number
    1
    :aws_tools_test.sh:15+'[' 1 -eq 1 ']'
    :aws_tools_test.sh:16+declare -i accountnumber=423214542344
    :aws_tools_test.sh:17+return
    :aws_tools_test.sh:114+choose_action
    :aws_tools_test.sh:31+echo 'These are the actions possible in AWS: '
    These are the actions possible in AWS: 
    :aws_tools_test.sh:32+echo '1 Add User and Access Keys'
    1 Add User and Access Keys
    :aws_tools_test.sh:33+echo '2 Delete Snapshots'
    2 Delete Snapshots
    :aws_tools_test.sh:34+echo 'Enter an action in AWS: '
    Enter an action in AWS: 
    :aws_tools_test.sh:35+read -r action
    1
    :aws_tools_test.sh:36+echo

    :aws_tools_test.sh:37+echo

    :aws_tools_test.sh:38+'[' 1 -eq 1 ']'
    :aws_tools_test.sh:39+user_action=add_user
    :aws_tools_test.sh:40+aws_file=source_files/aws_environments_nonprod.txt
    :aws_tools_test.sh:41+return
    :aws_tools_test.sh:116+arr=("423214542344" "188523423411")
    :aws_tools_test.sh:116+declare -a arr
    :aws_tools_test.sh:117+for i in '"${arr[@]}"'
    :aws_tools_test.sh:119+'[' '' == 423214542344 ']'
    :aws_tools_test.sh:125+'[' '' == 188523423411 ']'
    :aws_tools_test.sh:132+echo 'Your work in AWS is done.'
    Your work in AWS is done.
    :aws_tools_test.sh:117+for i in '"${arr[@]}"'
    :aws_tools_test.sh:119+'[' '' == 423214542344 ']'
    :aws_tools_test.sh:125+'[' '' == 188523423411 ']'
    :aws_tools_test.sh:132+echo 'Your work in AWS is done.'
    Your work in AWS is done.

It looks like the $accountnumber variable isn't getting set. So the functions are not getting called. Why is that?

12
  • 3
    Please consider building a minimal reproducible example -- the shortest possible code that lets someone see your problem when they run it themselves (meaning it should, whenever at all possible, not require an AWS account, precreated files, or anything else external to the script itself). Commented May 18, 2018 at 20:07
  • ...and btw, see Don't Read Lines With for re: the for line in $(cat file) idiom. BashFAQ #1 discusses more robust approaches (do note the need to use a non-stdin file handle if you want to be able to read from the user within such a loop). Commented May 18, 2018 at 20:08
  • As another aside, storing a command name in a variable is generally bad form. Consider defining a proper function instead: aws() { /home/tdunphy/.local/bin/aws "$@"; } -- or just running PATH=/home/tdunphy/.local/bin:$PATH once at the top of the script. Commented May 18, 2018 at 20:11
  • ...okay, the edited-in clarification helps a little. Notice the typo in [ "$action" = ="2" ]? You're looking for =2, not 2. Commented May 18, 2018 at 20:13
  • With the PATH change, btw, you can change all the $aws references to just aws. Commented May 18, 2018 at 20:14

1 Answer 1

1

When used in a function, the declare built-in makes the variable local to that function. So when you declare accountnumber in choose_account, the value isn't visible at the top-level of the script.

It doesn't look like there's a real need to declare the type of this variable, so declare -i is unnecessary. Just do an ordinary variable assignment. If you really feel the need to make it an integer variable, put the declaration in the top-level script rather than in the function, and just assign it in the function. Or avoid accessing the global variable entirely, and have the function echo the result:

declare -i accountnumber=$(choose_account)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. Switching the delare statement to regular variable assignment fixed the problem!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.