How to check GMail messages with prompt for password from a script

curlpasswordzsh

I'm using zsh on Ubuntu 14.04 over SSH using Putty and I'm setting up the key bindings for my keyboard. Because zsh doesn't seem to make use of my function keys I thought I'd setup scripts to do operations similar to what the pictures on the keys represent. I'm working on the email button and I have it working pretty well but I would like it to be better. This is what I have in ~/.zshrc:

# Ensure we are in emacs mode
bindkey -e

# This requires you to enable the ATOM feed in Gmail. If you don't know what that is then
# go ahead and try this and let it fail. There will then be a message in your inbox you
# can read with instruction on how to enable it. Username below should be replaced with 
# your email id (the portion of your email before the @ sign).
_check-gmail() {
    echo
    curl -u username:password --silent "https://mail.google.com/mail/feed/atom" | tr -d '\n' | awk -F '<entry>' '{for (i=2; i<=NF; i++) {print $i}}' | sed -n "s/<title>\(.*\)<\/title.*name>\(.*\)<\/name>.*/\2 - \1/p"
    echo
    exit
}
zle -N _check-gmail


# F2 - Display Unread Email
bindkey "^[[12~" _check-gmail

When used like above it works. I'm having two problems.

First and foremost, I would rather have it ask me for a password instead of leaving it in the script like this. This can easily be done by removing :password from the curl command at the command line but when used within this file it causes problems. Specifically, it appears to accept the first key press but the rest drop out to another shell which is not the password input.

Second, the first time I run this in a shell it works perfect. After that it doesn't return to the prompt correctly. I need to press Enter to get another prompt. Is there a way to fix that?

I've put the complete key bindings section of my .zshrc file on GitHub.

Best Answer

The problem is that curl expects some normal terminal settings and zle doesn't expect you change the terminal settings. So you can write it instead:

_check-gmail() {
  zle -I
  (
    s=$(stty -g)  # safe zle's terminal setting
    stty sane     # sane settings for curl
    curl -u username --silent "https://mail.google.com/mail/feed/atom" |
     tr -d '\n' | awk -F '<entry>' '{for (i=2; i<=NF; i++) {print $i}}' |
     sed -n "s/<title>\(.*\)<\/title.*name>\(.*\)<\/name>.*/\2 - \1/p"
    stty $s       # restore zle's terminal settings
  ) < /dev/tty
}