在 bash 脚本中执行 gcloud 命令

Execute gcloud commands in a bash script

gcloud init 命令在 bash 脚本执行期间不提供登录提示。

但是在脚本结束后我手动输入 exit 命令后它提供了登录。

vagrant@vagrant-ubuntu-trusty-64:~$ exit
logout
Welcome! This command will take you through the configuration of gcloud.

Settings from your current configuration [default] are:
Your active configuration is: [default]


Pick configuration to use:
 [1] Re-initialize this configuration [default] with new settings 
 [2] Create a new configuration
Please enter your numeric choice:  1

Your current configuration has been set to: [default]

To continue, you must log in. Would you like to log in (Y/n)?  

我的 bash 脚本:

#!/usr/bin/env bash

OS=`cat /proc/version`

function setupGCE() {
curl https://sdk.cloud.google.com | bash
`exec -l $SHELL`
`gcloud init --console-only`
`chown -R $USER:$USER ~/`
}


if [[ $OS == *"Ubuntu"* || $OS == *"Debian"*  ]]
then
sudo apt-get -y install build-essential python-pip python-dev curl
sudo pip install apache-libcloud
setupGCE
fi

如何在 bash 脚本执行期间获得登录提示?

不知何故 exec -l $SHELL 弄得一团糟。我将其更改为 source ~/.bashrc,现在可以使用了。

发布的代码段存在一些问题。

正确的片段是(可能):

function setupGCE() {
    curl https://sdk.cloud.google.com | bash
    gcloud init --console-only
    chown -R $USER:$USER ~/
}

您自己发现的原始版本的第一个错误(至少是什么而不是为什么)是 exec -l $SHELL 阻碍了进度。这样做是因为您 运行 一个交互式 shell 现在正在等待您输入并且该函数正在等待该进程退出然后继续。

此外,exec 将当前进程替换为派生进程。实际上你在这里很幸运。如果您没有将对 exec 的调用用单引号引起来,您的函数将在您退出 $SHELL 脚本时完全退出 shell 脚本。但是,实际上,exec 只是替换了反引号添加的子 shell,因此您留下了一个可以安全退出的子进程,return 您进入了 parent/main 脚本.

第二个问题是反引号 运行 它们包围的命令,然后用输出替换它们自己。这就是为什么

echo "bar `echo foo` baz"

输出 bar foo baz,等等(运行 set -x 在 运行 之前查看实际执行的是什么命令 运行。)所以当你写

`gcloud init --console-only`

你说的是 "run gcloud init --console-only then take its output and replace the command with that" 然后它将尝试 运行 作为命令本身的输出(这可能不是你想要的)。其他线路也是如此。

这里碰巧没有问题,因为 chown 并且可能 gcloud init 没有 return 任何东西,因此生成的命令行是空的。