期望失败,但我不明白为什么



我有一个bash脚本,它从Heroku获取信息,这样我就可以提取数据库的副本。这个剧本在cygwin中很好用。但要在cron中运行它,它会停止,因为它使用的shell会停止作为Heroku通过Heroku Toolbelt的身份验证。

这是我的crontab:

SHELL=/usr/bin/bash
5 8-18 * * 1-5 /cygdrive/c/Users/sam/work/push_db.sh >>/cygdrive/c/Users/sam/work/output.txt

我已经阅读了谷歌和cygwin内的手册页,想出了这个补充:

#!/usr/bin/bash
. /home/sam.walton/.profile
echo $SHELL
curl -H "Accept: application/vnd.heroku+json; version=3" -n https://api.heroku.com/
#. $HOME/.bash_profile
echo `heroku.bat pgbackups:capture --expire`
#spawn heroku.bat pgbackups:capture --expire
expect {
  "Email:" { send -- "$($HEROKU_LOGIN)r"}
  "Password (typing will be hidden):" { send -- "$HEROKU_PWr" }
  timeout  { echo "timed out during login"; exit 1 }
}
 sleep 2
 echo "first"
 curl -o latest.dump -L "$(heroku.bat pgbackups:url | dos2unix)"

这是output.txt 的输出

/usr/bin/bash
{
  "links":[
    {
      "rel":"schema",
      "href":"https://api.heroku.com/schema"
    }
  ]
}
Enter your Heroku credentials. Email: Password (typing will be hidden): Authentication failed. Enter your Heroku credentials. Email: Password (typing will be hidden): Authentication failed. Enter your Heroku credentials. Email: Password (typing will be hidden): Authentication failed.

正如您所看到的,输出似乎没有得到send命令的结果,因为它似乎在等待。我已经用凭证和期望语句做了很多实验。一切到此为止。我看过一些例子,并试图尝试一下,但我的眼睛越来越模糊,这就是我在这里发帖的原因。我有什么不明白的?

感谢您的评论,我被提醒将我的env变量明确地放在.bashrc:中

[[ -s $USERPROFILE/.pik/.pikrc ]] && source "$USERPROFILE/.pik/.pikrc"
export HEROKU_LOGIN=myEmailHere
export HEROKU_PW=myPWhere

根据@Dinesh的优秀例子,我修改过的脚本如下:

. /home/sam.walton/.bashrc echo $SHELL echo $HEROKU_LOGIN curl -H "Accept: application/vnd.heroku+json; version=3" -n https://api.heroku.com/
expect -d -c "   spawn heroku.bat pgbackups:capture --expire --app gw-inspector   expect {
    "Email:" { send -- "myEmailHerer"; exp_continue}
    "Password (typing will be hidden):" { send -- "myPWherer" }
    timeout  { puts "timed out during login"; exit 1 }   } " sleep 2 echo "first"

这应该是有效的,但当变量的echo失败时,给了我一个线索,表明变量没有被调用,我正在测试直接对变量进行硬编码,以将其作为变量消除。但是,正如你从我的输出中看到的那样,回声不仅没有产生任何结果,而且没有任何迹象表明正在传递任何诊断,这让我怀疑脚本是否被调用以从预期运行,以及生成命令的结果。需要重申的是,heroku.bat命令在expect闭包之外工作,但结果高于预期。直接在上面的命令的结果是:

/usr/bin/bash
{
  "links":[
    {
      "rel":"schema",
      "href":"https://api.heroku.com/schema"
    }
  ]
} 

我做错了什么,会显示诊断笔记?

如果您要在bash脚本中使用expect代码,而不是单独调用它,那么您应该使用-c标志选项。

根据您的代码,我假设您在bashrc文件中声明了环境变量HEROKU_LOGIN和HEROKU_PW。

#!/usr/bin/bash
#Your code here
expect -c "
           spawn <your-executable-process-here>
           expect {
                    # HEROKU_LOGIN & HEROKU_PW will be replaced with variable values.
                   "Email:"   { send -- "$HEROKU_LOGINr";exp_continue}
                   "Password (typing will be hidden):" { send "$HEROKU_PWr" }
                    timeout  { puts"timed out during login"; exit 1 }
           }
 "
 #Your further bash code here

您不应该在expect代码中使用echo命令。请改用puts。在expect代码内部生成进程的选项将比在外部生成进程更健壮。

注意在expect -c标志中使用了双引号。若使用单引号,那个么bash脚本就不会进行任何形式的替换。因此,如果您需要bash变量替换,那么应该对带有-c标志的expect使用双引号。

要了解-c标志的用法,请查看此处的

如果您仍然有任何问题,可以通过以下方式附加-d进行调试。

expect -d -c "
              our code here
       "

最新更新