0

There are a few other posts related, but they didn't help solve my problem.

I have the script below that has an optional parameter for an aws profile -p What I would like to do is save the profile configurations into environmental variables in the current shell.

#!/bin/bash

# This script is used to set an AWS profile for the current shell session.
# It is intended to be used with the AWS CLI and the AWS CLI v2.

usage() { echo "Usage: $0 [-p <string>]"; exit 1; }

while getopts "p:" options; do
    case "${options}" in
        p)
            p=${OPTARG}
            ;;

    esac
done

if [ -z "${p}" ]; then
  export AWS_ACCESS_KEY_ID=$(aws configure get default.aws_access_key_id)
  export AWS_SECRET_ACCESS_KEY=$(aws configure get default.aws_secret_access_key)
  export AWS_DEFAULT_REGION=$(aws configure get default.region)
  echo "Default profile set"
else
  aws configure list-profiles | grep -q "${p}"
  if [ $? -ne 0 ]; then
    echo "Profile ${p} not found"
    exit 1
  else
    export AWS_ACCESS_KEY_ID=$(aws configure get "${p}".aws_access_key_id)
    export AWS_SECRET_ACCESS_KEY=$(aws configure get "${p}".aws_secret_access_key)
    export AWS_DEFAULT_REGION=$(aws configure get "${p}".region)
  fi
fi

I call the script like this

source ./set-aws-profile

However, when I look for environmental variables, I just get a new line

source ./set-aws-profile
Default profile set
% echo $AWS_ACCESS_KEY_ID    

%

Probably something obvious, but any idea of what is wrong here?

  • 1
    `set -x; . ./set-aws-profile; set +x` is your friend here, to get a log of what's happening at runtime. That should allow you to build a more focused question. (I wouldn't be surprised if `aws configure get default.aws_access_key_id` were coming back empty, but we'd know for sure rather than needing to guess given the trace log). – Charles Duffy Mar 02 '23 at 16:30
  • 1
    It's not your immediate problem, btw, but for something that's being `source`d you probably want to make it `return 1` rather than `exit 1` on errors: `exit` causes the shell you sourced it from to stop running. – Charles Duffy Mar 02 '23 at 16:30
  • Another not-your-immediate-problem aside: Better to use `if ! foo; then` instead of `foo; if [ $? -ne 0 ]; then`; see [Why is checking $? to see if a command succeeded or not an antipattern?](https://stackoverflow.com/questions/36313216/why-is-testing-to-see-if-a-command-succeeded-or-not-an-anti-pattern) – Charles Duffy Mar 02 '23 at 16:31
  • (And another not-the-immediate-problem aside: Diagnostic information should go to stderr, not stdout, so `echo`s meant for human consumption should have `>&2` on them; even things like status, informational logs, prompts, &c are diagnostic, if they're not content that your program was run _in order to generate_, it's not standard output, so it belongs on stderr; that way content intended for human operators doesn't get redirected into pipelines). – Charles Duffy Mar 02 '23 at 16:34
  • Thanks for all the info. A little new to all of this magic of bash scripting. Looks like you were right, the aws configure is returning nothing – A Simple Programmer Mar 02 '23 at 16:54
  • ```+./set-aws-profile:8> getopts p: options +./set-aws-profile:17> [ -z '' ']' +./set-aws-profile:18> aws configure get default.aws_access_key_id +./set-aws-profile:18> export AWS_ACCESS_KEY_ID='' +./set-aws-profile:19> aws configure get default.aws_secret_access_key +./set-aws-profile:19> export AWS_SECRET_ACCESS_KEY='' +./set-aws-profile:20> aws configure get default.region +./set-aws-profile:20> export AWS_DEFAULT_REGION=''``` +./set-aws-profile:21> echo 'Default profile set' – A Simple Programmer Mar 02 '23 at 16:54
  • (Not related to the problem, but as an aside: That doesn't look like a real bash PS4; is your shell really zsh? Because `source` runs code inside the existing shell, the shebang isn't honored, so it basically ends up just being an editor hint) – Charles Duffy Mar 02 '23 at 16:59
  • ...as for the problem, though, at this point it _looks_ like an AWS tool-configuration question; unless there's reason to believe shell expertise is required, this seems like a good point in time for me to bow out. :) – Charles Duffy Mar 02 '23 at 17:02
  • You might check your `~/.aws` directory to see if there is either a `credentials` file or `config` file present. The contents of those files should contain the values you set via the `aws configure` commands. – j_b Mar 02 '23 at 17:08
  • It was a problem with the call to `aws configure` it looks like you can't call `profile_name.` you instead do `configure get --profile ` – A Simple Programmer Mar 02 '23 at 17:51
  • @CharlesDuffy I got it to work, but it looks like I can't pass variables when I source the script, which is kinda the entire point of the script. `. ./set-aws-profile -p profile_name` will not set the value of `$p` unless I just call it using a subshell `./set-aws-profile -p profile name` I know it's kind of a different question, but would be really helpful if you knew why. – A Simple Programmer Mar 02 '23 at 17:54
  • Put `: "$@"` inside your script, before the `while getopts` loop; when you're running it with `set -x`, do you see the `-p profile_name` expanded as arguments to the `:` command? (In bash, you would; but if you're really running zsh, that's a language I don't know so well). – Charles Duffy Mar 02 '23 at 17:59
  • Anyhow -- assuming that `"$@"` is being correctly populated, I'd ditch getopts in favor of following [BashFAQ #35](https://mywiki.wooledge.org/BashFAQ/035) – Charles Duffy Mar 02 '23 at 18:00
  • yeah looks like it isn't `+./set-aws-profile:10> getopts p: options +./set-aws-profile:24> [ -z '' ']' `. I didn't know the difference between bash and zsh would affect something like this. – A Simple Programmer Mar 02 '23 at 18:06
  • Figured it out. If you source the script, the `OPTIND` variable needs to be reset to grab new things passed into it. Adding `OPTIND=1` fixed the issue. – A Simple Programmer Mar 03 '23 at 16:45

0 Answers0