Невозможно использовать исходный код для выполнения сценария Bash на Zsh. - PullRequest
0 голосов
/ 30 октября 2019

У меня есть Mac, на котором я установил и настроил zsh в качестве оболочки по умолчанию. Он очень хорошо работал с простыми скриптами Bash. До сегодняшнего дня.

Я пытался настроить свой доступ к CLI AWS с помощью MFA и использовал сценарий, чтобы сделать то же самое. Поскольку у меня несколько учетных записей, я использовал файл aws_accounts для хранения номеров учетных записей с разрешениями 400. (Никакой реальной причины, почему, просто захотелось, и это работает).

Я затем source этот файл и попадаю в ту часть, где мне нужно предоставить свой ключ MFA, и они тоже работают. Последний шаг, где я export ключ доступа, секретный ключ и токен сеанса, работает до тех пор, пока сценарий выполняется, но после его выполнения echo показывает пустое значение, поскольку теперь он больше не задантекущая оболочка.

Я знаю, что обходной путь должен сделать source aws_mfa_access default для запуска скрипта, но он не работает, и я получаю ошибку bad substitution. Я пробовал различные комбинации #!/usr/bin/env bash, #!/bin/bash и #!/usr/bin/env zsh, но безрезультатно. Что происходит?

[aws_account_numbers]

default_account_number=<number>
sandbox_account_number=<number>
production_account_number=<number>

[aws_mfa_access]

#!/usr/bin/env bash

source aws_account_numbers

AWS_ENV="${1}"
AWS_ACCT_NBR="${AWS_ENV}"_account_number

#export your aws access key that matches with your account, username
export AWS_PROFILE="${AWS_ENV}"

#If there are existing environment variables set, this can cause issues so we unset them first
unset AWS_SESSION_TOKEN
unset AWS_SECRET_ACCESS_KEY
unset AWS_ACCESS_KEY_ID

#Set the serial number of your MFA token
MFA="arn:aws:iam::${!AWS_ACCT_NBR}:mfa/codingincircles"

#Get the code from the MFA device
echo "Please enter the MFA code for the ${AWS_ENV} account: "
read -r code

#Get the credentials from AWS and store the response in a variable
creds="$( aws sts get-session-token --serial-number "${MFA}" --token-code "${code}" )"

#Parse the response into separate variables
AWS_ACCESS_KEY_ID="$( echo "${creds}" | jq -r .Credentials.AccessKeyId )"
AWS_SECRET_ACCESS_KEY="$( echo "${creds}" | jq -r .Credentials.SecretAccessKey )"
AWS_SESSION_TOKEN="$( echo "${creds}" | jq -r .Credentials.SessionToken )"

#Display the keys to the user for reference/confirm proper working
echo "${access_key}"
echo "${secret_key}"
echo "${session_token}"

#Set the appropriate environment variables
export AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID}"
export AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY}"
export AWS_SESSION_TOKEN="${AWS_SESSION_TOKEN}"

РЕДАКТИРОВАТЬ: Два примечание:

  1. Замена параметров не является проблемой вообще. Он работает просто отлично, как есть, хотя другие методы, предложенные в комментариях и ответах, тоже работают. (Я использовал подсказку jq -r, и она работает как шарм! Спасибо!)
  2. Я удалил команду source в своем скрипте (в строке 3) и затем смог, без каких-либо ошибоклюбой вид, способный вызвать мой скрипт как source aws_mfa_access default. Переменные export сохранились, и я могу без проблем использовать CLI.

Так почему же мне не нравится использование source в моем скрипте? Я также отредактировал скрипт, чтобы отразить некоторые изменения.

1 Ответ

1 голос
/ 30 октября 2019

Косвенное расширение параметров отличается в zsh, чем в bash

MFA="arn:aws:iam::${(P)AWS_ACCT_NBR}:mfa/codingincircles"

Однако вы можете избежать косвенного расширения параметров, в первую очередь, используя ассоциативный массив для хранения номеров счетов.

typeset -A account_numbers
account_numbers[default]=...
account_numbers[sandbox]=...
account_numbers[production]=...

Тогда

MFA="arn:aws:iam::${account_numbers[$1]}:mfa/codingincircles"

Наконец, source не является внешней командой, которая означает «выполнить скрипт bash здесь». Это встроенная оболочка, которая выполняет файл в текущей оболочке . Если текущая оболочка bash, она попытается выполнить содержимое файла как сценарий bash;если это zsh, как zsh скрипт;если это dash, как dash скрипт.

...