0

I'm trying to create a shell script which logs in to Gmail at a set interval of time and then delete some files. I'm able to do it via terminal using openssl but not via shell script file.

Here is my shell file

openssl s_client -connect imap.gmail.com:993 -crlf
a001 login USER_NAME PASSWORD
a002 SELECT [Gmail]/Trash
a003 STORE 1:* +FLAGS (\Deleted)
a004 EXPUNGE
a005 logout

Now the problem here is after first command executes shell connects to the server and second command does not get executed (which makes sense).

How can i make shell script run command for connected server?

PS: I think pipeline is not the correct word here, but i'm not aware of the jargon that will be used here so please feel free to edit the question.

a1626
  • 2,953
  • 1
  • 19
  • 34
  • 1
    Using Bash and `openssl` to script IMAP is going to be extremely complex and brittle. Are you *really really* sure you *have* to use Bash for this? There are good IMAP libraries for a number of other scripting languages; I like Python, but whatever you are already familiar with is probably better than Bash for this particular task. – tripleee Dec 20 '17 at 07:43
  • @tripleee as this is for my personal use i've no such restriction. But can you please explain why will it be complex and brittle? – a1626 Dec 20 '17 at 07:46
  • 1
    There is no good way to establish an SSL session in one process, then do some Bash logic, then continue the same SSL session in another process. Once you log in, what mechanism do you have to decide which messages to fetch or etc? If you can do it all in one go before connecting, and pipe a set of commands into `openssl`, that will be feasible; but very often, that will be unsatisfactory. – tripleee Dec 20 '17 at 07:47
  • @tripleee, Thanks for the suggestion. In that case i'll explore some other option. – a1626 Dec 20 '17 at 07:49
  • Stack Overflow is a site for programming and development questions. This question appears to be off-topic because it is not about programming or development. See [What topics can I ask about here](http://stackoverflow.com/help/on-topic) in the Help Center. Perhaps [Super User](http://superuser.com/) or [Unix & Linux Stack Exchange](http://unix.stackexchange.com/) would be a better place to ask. – jww Dec 22 '17 at 06:03
  • Also see [GMAIL: EXPUNGE items in Trash](https://stackoverflow.com/q/47864732/608639). Adding "in a script" to the original question is not very compelling. A [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) reduces to a command or two, not a script. – jww Dec 22 '17 at 06:04
  • @jww these two are different questions altogether. [First](https://stackoverflow.com/questions/47864732/gmail-expunge-items-in-trash) one was about how to `EXPUNGE` using terminal, which was answered [here](https://superuser.com/questions/1278077/gmail-expunge-items-in-trash) and this question is asking how to code it in shell script as after logging in shell changes as commands in script file do not execute. – a1626 Dec 22 '17 at 06:29
  • @jww just to add more clarity this question is about how to handle shell change through script file, especially for `openssl` command. And the reason why i added my complete code instead of minimum viable one is in comments after [this](https://stackoverflow.com/questions/47900642/pipeline-openssl-commands/47900873?noredirect=1#comment82769195_47900873). – a1626 Dec 22 '17 at 06:38

1 Answers1

2

The confusion here is in how input to the shell and the openssl program are handled. When you do this interactively, the shell is reading commands from the terminal (i.e. you), and openssl also reads from the terminal, so whatever you type goes to whatever' listening at the time: the openssl ... command is read by the shell, and then openssl starts reading from the terminal, so when you type a001 login ..., that gets read by the openssl program and sent to the remote server.

In a script, it's different. The shell reads commands from the script, but other programs (like openssl) read from what's called standard input (or stdin), which is usually still the terminal. So the shell reads the line openssl ..., runs the openssl program, which tries to read input from your terminal. If and when openssl exits, the shell will then read a001 login ... and try to execute it as a shell command.

What you could to do is supply that a001 login ... as input to the openssl program. The easiest way to do that is usually with a here-doument, introduced by <<somedelimiter:

openssl s_client -connect imap.gmail.com:993 -crlf <<EOF
a001 login USER_NAME PASSWORD
EOF

That essentially tells the shell "run this openssl ... command, and feed the following lines (up to 'EOF') into its stdin".

[EDIT] But that doesn't solve a deeper problem, because all it does is send the login command, then run out of input, and close the connection. You'd have to include additional commands within the here-document to get it to actually do anything:

openssl s_client -connect imap.gmail.com:993 -crlf <<EOF
a001 login USER_NAME PASSWORD
a001 STATUS INBOX (MESSAGES UNSEEN RECENT)
a001 LIST "INBOX" "*"
EOF

...and then capture the output from it (probably by adding >sometempfile to the command line), and parse through the output to figure out what's on the server. But what you probably really want to do is to be able to interact with the server (e.g. get a list of new messages and then FETCH them), and this doesn't really allow that -- your script is sending a fixed command list, rather than sending commands one at a time, looking at the results, and sending more commands based on what it gets back. And that really requires something other than a shell script and openssl -- something with a decent IMAP library (as triplee suggested in a comment).

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
  • Now instead of saying `OK Gimap ready for requests from...` it prints `DONE` after printing `ssl-session` details, closes the session and finishes the script. – a1626 Dec 20 '17 at 07:40
  • This answer is basically the same as https://stackoverflow.com/questions/37586811/pass-commands-as-input-to-another-command-su-ssh-sh-etc – tripleee Dec 20 '17 at 07:42
  • @a1626 if you want to send additional commands to the gmail server, you need to include them in the here-document (i.e. before the EOF). – Gordon Davisson Dec 20 '17 at 08:03
  • @tripleee True; I should've looked for a good dupe before answering. – Gordon Davisson Dec 20 '17 at 08:07
  • @GordonDavisson i did enter them before `EOF` like `openssl s_client -connect imap.gmail.com:993 -crlf < – a1626 Dec 20 '17 at 08:16
  • Right, but the problem then is that `openssl` simply logs in, runs out of standard input, and finishes. – tripleee Dec 20 '17 at 08:19
  • @GordonDavisson That's exactly what i've been doing (except for catching it in output file). I already tried and added commands to `expunge` everything in `Trash`, but it did not work. – a1626 Dec 20 '17 at 09:20
  • I've updated my question with all the commands that i added b/w 2 EOFs for your reference. – a1626 Dec 20 '17 at 09:22