将AWS环境变量保存到文件 - 如何处理特殊字符'&'

时间:2017-01-12 10:29:41

标签: bash perl sed

我正在尝试通过cron在AWS Elasticbeanstalk(EB)上运行django manage.py任务。

*/10 * * * * root /usr/local/bin/notification_cron.sh > /dev/null

notification_cron.sh脚本调用django manage.py任务。

Django需要EB的环境变量(如RDS_PORT,RDS_DB_NAME,RDS_PASSWORD等)。所以我在部署时将这些环境变量保存到文件中,并在bash脚本中重新加载那些也调用manage.py任务的文件。

这是.ebextensions中部署配置的一部分:

commands:
  001_envvars_to_bash_source_file:
    command: |
      # source our elastic beanstalk environment variables
      /opt/elasticbeanstalk/bin/get-config --output YAML environment|perl -ne "/^\w/ or next; s/: /=/; print qq|\$_|" > /usr/local/bin/envvars
      chmod 755 /usr/local/bin/envvars

files:
  "/usr/local/bin/notification_cron.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash

      AWS_CONFIG_FILE="/home/ec2-user/.aws/config"
      set -o allexport
      # Loading environment data
      source /usr/local/bin/envvars
      set +o allexport
      cd /opt/python/current/app/
      source /opt/python/run/venv/bin/activate
      python manage.py my_management_task

问题是由行

引起的
  /opt/elasticbeanstalk/bin/get-config --output YAML environment|perl -ne "/^\w/ or next; s/: /=/; print qq|\$_|" > /usr/local/bin/envvars

或备用sed等价物

  /opt/elasticbeanstalk/bin/get-config environment --output yaml | sed -n '1!p' | sed -e 's/^\(.*\): /\1=/g' > /usr/local/bin/envvars

/usr/local/bin/envvars的内容并不总是引号:

PYTHONPATH="/opt/python/current/app/mydjangoapp:$PYTHONPATH"
DJANGO_SETTINGS_MODULE=mydjangoapp.settings
AWS_ACTIVE='true'
RDS_PORT='5432'
RDS_HOSTNAME=hostname.host.us-east-1.rds.amazonaws.com
RDS_USERNAME=master
RDS_DB_NAME=ebdb
RDS_PASSWORD=My&Password

这会导致环境变量具有“&”的麻烦字符。

'RDS_PASSWORD': My&Password

Bash将其拆分为“&”我在调用django的manage.py之前将source /usr/local/bin/envvars导回到我的脚本中的字符。

呼。我的问题是:

如何在RDS_PASSWORD="My&Password"文件中获取/usr/local/bin/envvars(请注意所需的双引号),而不会破坏RDS_PORT='5432'等其他行?

1 个答案:

答案 0 :(得分:2)

使用GNU sed,您可以执行以下操作,

sed -r 's/RDS_PASSWORD=([[:graph:]]+)/RDS_PASSWORD="\1"/' /usr/local/bin/envvars
PYTHONPATH="/opt/python/current/app/mydjangoapp:$PYTHONPATH"
DJANGO_SETTINGS_MODULE=mydjangoapp.settings
AWS_ACTIVE='true'
RDS_PORT='5432'
RDS_HOSTNAME=hostname.host.us-east-1.rds.amazonaws.com
RDS_USERNAME=master
RDS_DB_NAME=ebdb
RDS_PASSWORD="My&Password"

然后,您可以将-i标记添加到sed以进行就地替换。我使用了

的字符类[[:graph:]]
‘[:graph:]’
Graphical characters: ‘[:alnum:]’ and ‘[:punct:]’.

[:punct:]中的特殊字符是

! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~

因此sed可以处理替换,如果上述任何字符构成RDS_PASSWORD变量。

您可以使用的语法是

 /opt/elasticbeanstalk/bin/get-config environment --output yaml | \
    sed -n '1!p' | sed -e 's/^\(.*\): /\1=/g' | \
    sed -r 's/RDS_PASSWORD=([[:graph:]]+)/RDS_PASSWORD="\1"/' > /usr/local/bin/envvars