AppleScript & interactive shell-script sessions

I thought I should share the brief research I finished yesterday.

Being AppleScript (as the main language to drive apple-events in the mac) the mother of the automation since MacOS 7 days, I was still missing the path to automate interactive shell scripting sessions, such as ssh, telnet, mail, etc., without the need of scripting the Terminal app, which is ugly.

Yesterday I found info about “expect” (google for it and click the first search result if you use english as your main language). It’s kind of a pseudo-terminal which you can invoke just like bash or sh, and it accepts a serie of special commands, being “expect” the killer one.

I’m working in a top-secret project with gnuchess (an app which acts as interface for UCI chess engines => well, the app which in fact was used to determine how UCI chess engines should communicate with UIs) and I needed grabbing input from it. But gnuchess must be launched in interactive mode, etc. And AS’s “do shell script” doesn’t work like that.

So, I wrote my first “expect” script, which works like this:

(“sample.sh” invoked from AS «do shell script “cd xxx; ./sample.sh ‘file.pgn'”»)

#!/usr/bin/expect
# this is how you read passed arguments (index-based)
set pgnName [lindex $argv 0]

cd /path/to/gnuchess-6.0.2/src/;
# start listening
spawn ./gnuchess

expect “White (1) : “
send “pgnload $pgnName\n”

expect “White (1) : “
send “book on\n”

expect “White (1) : “
send “hard\n”

expect “White (1) : “
send “go\n”

expect “) : “
send “quit\n”

close

Basically:

  • spawn: launches and starts listening a process.
  • expect: listens the process to output the given string (such as “White (1) : “).
  • send: upon that string being sent by the process, enter the given string (such as “book on”).
  • close: that is.

I invite you to fire the Terminal and type “man expect”. You will find more options and ways to write more compact code.

Green fields in front of me 😉

This one and the new features in Adobe AIR will keep me busy for the next two years (appart from that damn mobile devices and the html5 headache everyone loves).

Be good.

Advertisement

MySQL remove duplicates (large database + fast)

In the end, this was for me the fastest method to remove dups from the big db I’m working on:

  1. Duplicate the structure of the database (ie, “db”) to a new database (ie, “db2”, setting the fields you don’t want to be dups to UNIQUE.
  2. Copy db to db2 using INSERT IGNORE:

INSERT IGNORE INTO
db2
(`xxx`,`yyy`,`zzz`)
SELECT `xxx`,`yyy`,`zzz`
FROM `db`

This reduced the amount of time to minutes, while any other method could take many hours, appart from creating large temporary files which could fill the disk holding the temp dir and finally abort the process.

If you don’t need in the end to have those UNIQUE fields (the indexes takes many HD), you should re-dump db2 to a new db without that UNIQUE fields => again some more minutes, but still worth against 12 hours of CPU/RAM intensive working (in a highly mysql responsive profile) with other kind of filtering methods, such as DISTINCT or GROUP BY.