我有一个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
"