用于更新 docker 登录的 Bash 脚本无法正常运行



我正在尝试将登录密钥更新到 CoreOS 实例上的 AWS docker ECR。

如果我运行:

docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws ecr get-login

我得到作为输出:

docker login -u AWS -p CiBwm0YaISJeRtJ ... -e none https://123456789012.us-east-1.amazonaws.com

如果我复制并运行它,它可以完美运行。 如果我不这样做,而是使用这种形式:

$(docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws ecr get-login)

它失败并显示错误。

/v0/: unable to ping registry endpoint https://123456789012.us-east-1.amazonaws.com 

如果我尝试将其分配给变量,事情会变得奇怪。

var=$(docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws ecr get-login)
echo "'$var' string"

奇怪的是,当我尝试引用字符串并回显它时,最后一个引用出现在一个意想不到的地方。

docker login -u AWS -p CiBwmEwHgYJ ... YIZIAWUDBAEuMisGdv0KB' stringivOyPO+qNJ3zo87RXwWlOW8TnCtGRd6k6tb0Z35xL2IKMO194+1va56lH0am -e none https://123456789012.dkr.ecr.us-east-1.amazonaws.com

这是一个很长的字符串,这里可能存在某种缓冲区溢出问题吗?

我该如何解决它?

我以前使用过aws ecr get-login作为eval完成实际登录的输入。 在我的 CoreOS 机器上使用像您这样的命令执行相同的操作失败,并出现与您的类似问题:

$ eval $(docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws --region=us-east-1 ecr get-login)
/v0/: unable to ping registry endpoint https://123456789012.dkr.ecr.us-east-1.amazonaws.com1.amazonaws.com
: no such host: lookup 123456789012.dkr.ecr.us-east-1.amazonaws.com.us-east-1.amazonaws.com
/ca.crte daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/123456789012.dkr.ecr.us-east-1.amazonaws.com

我使用良好的 ol' set -x 来打开调试,这样我就可以准确地看到正在执行的命令:

$ docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws --region=us-east-1 ecr get-login
+ docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws --region=us-east-1 ecr get-login
docker login -u AWS -p CiBwm...hb9E= -e none https://123456789012.dkr.ecr.us-east-1.amazonaws.com
$ eval $(docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws --region=us-east-1 ecr get-login)
++ docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws --region=us-east-1 ecr get-login
+ eval docker login -u AWS -p CiBwm...DES0= -e none $'https://123456789012.dkr.ecr.us-east-1.amazonaws.comr'
++ docker login -u AWS -p CiBwm...DES0= -e none $'https://123456789012.dkr.ecr.us-east-1.amazonaws.comr'
/v0/: unable to ping registry endpoint https://123456789012.dkr.ecr.us-east-1.amazonaws.com1.amazonaws.com
: no such host: lookup 123456789012.dkr.ecr.us-east-1.amazonaws.com.us-east-1.amazonaws.com
/ca.crte daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/123456789012.dkr.ecr.us-east-1.amazonaws.com

等等,什么? 当命令被输入eval时,存储库URL被转换为$'https://123456789012.dkr.ecr.us-east-1.amazonaws.comr',这导致它以一种非常奇怪的方式被评估。 这r似乎是问题所在,所以我将 docker 命令的输出输入到一个文本文件中,然后使用 Vim 以二进制模式打开它进行检查。 果然,这是一个讨厌的马车返回角色。 用sed删除该字符对我来说起到了作用:

$ eval $(docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws --region=us-east-1 ecr get-login | sed -e 's/^M//')
++ sed -e $'s/r//'
++ docker run --rm --env-file=/etc/aws/environment -ti xueshanf/awscli:latest aws --region=us-east-1 ecr get-login
+ eval docker login -u AWS -p CiBwm...88A8= -e none https://123456789012.dkr.ecr.us-east-1.amazonaws.com
++ docker login -u AWS -p CiBwm...88A8= -e none https://123456789012.dkr.ecr.us-east-1.amazonaws.com
WARNING: login credentials saved in /home/core/.docker/config.json
Login Succeeded

注意:要删除回车符,您需要键入 Ctrl+VCtrl+M 以正确插入^M字符。

希望这有帮助! =]

Docker 正在插入额外的回车符,因为您已经告诉它分配一个伪 tty(带有选项 -t )。如果删除-ti,则无需使用 sed。

eval $(docker run --rm --env-file=/etc/aws/environment 
    xueshanf/awscli:latest aws ecr get-login)

最新更新