lim it ed t o use in sit uat ions where youre t he only user on t he m achine or you t rust all ot her users.
The rest of t his sect ion shows how t o process com m and- line argum ent s t o get connect ion param et ers, and how t o read param et ers from opt ion files.
2.11.4 Getting Parameters from the Command Line
The usual MySQL convent ion for com m and- line argum ent s t hat is, t he convent ion followed by st andard MySQL client s such as m ysql is t o allow param et ers t o be specified using eit her a
short opt ion or a long opt ion. For exam ple, t he usernam e
cbuser
can be specified eit her as - u
cbuser
or - u
cbuser
or - - user
=cbuser
. I n addit ion, for t he opt ions t hat specify t he password -p or - - password , t he password value m ay be om it t ed aft er t he opt ion nam e t o
indicat e t hat t he program should prom pt for t he password int eract ively. The next set of exam ple program s shows how t o process com m and argum ent s t o obt ain t he
host nam e, usernam e, and password. The st andard flags for t hese are - h or - - host , - u or - - user, and - p or - - password. You can writ e your own code t o it erat e t hrough t he argum ent list ,
but in general, it s m uch easier t o use exist ing opt ion- processing m odules writ t en for t hat purpose. The program s present ed here are im plem ent ed using a
getopt
- st yle funct ion for each API , wit h t he except ion of PHP. I nsofar as possible, t he exam ples m im ic t he behavior of
t he st andard MySQL client s. No exam ple program is provided for PHP, because few PHP script s are writ t en for use from t he com m and line.
2 .1 1 .4 .1 Pe r l
Perl passes com m and- line argum ent s t o script s in t he
ARGV
array, which can be processed using t he
GetOptions
funct ion of t he Get opt : : Long m odule. The following program shows how t o parse t he com m and argum ent s for connect ion param et ers. I f a password opt ion is
specified wit h no following argum ent , t he script prom pt s t he user for t he password value. usrbinperl -w
cmdline.pl - demonstrate command-line option parsing in Perl use strict;
use DBI; use Getopt::Long;
Getopt::Long::ignorecase = 0; options are case sensitive Getopt::Long::bundling = 1; allow short options to be bundled
connection parameters - all missing undef by default my host_name, password, user_name;
GetOptions =s means a string argument is required after the option
:s means a string argument is optional after the option host|h=s = \host_name,
password|p:s = \password, user|u=s = \user_name
or exit 1; no error message needed; GetOptions prints its own solicit password if option specified without option value
if defined password password eq {
turn off echoing but dont interfere with STDIN open TTY, devtty or die Cannot open terminal\n;
system stty -echo devtty; print STDERR Enter password: ;
chomp password = TTY; system stty echo devtty;
close TTY; print STDERR \n;
} construct data source name
my dsn = DBI:mysql:database=cookbook; dsn .= ;host=host_name if defined host_name;
connect to server my dbh = DBI-connect dsn, user_name, password,
{PrintError = 0, RaiseError = 1}; print Connected\n;
dbh-disconnect ; print Disconnected\n;
exit 0;
The argum ent s t o
GetOptions
are pairs of opt ion specifiers and references t o t he script variables int o which opt ion values should be placed. An opt ion specifier list s bot h t he long and
short form s of t he opt ion wit hout leading dashes , followed by
=s
if t he opt ion requires a following argum ent or
:s
if it m ay be followed by an argum ent . For exam ple,
host|h=s
allows bot h - - host and - h and indicat es t hat a st ring argum ent is required following t he opt ion. You need not pass t he
ARGV
array because
GetOptions
uses it im plicit ly. When
GetOptions
ret urns,
ARGV
cont ains any rem aining argum ent s following t he last opt ion. The Get opt : : Long m odules
bundling
variable affect s t he int erpret at ion of argum ent s t hat begin wit h a single dash, such as - u. Norm ally, wed like t o accept bot h - u
cbuser
and - u
cbuser
as t he sam e t hing, because t hat s how t he st andard MySQL client s act . However, if
bundling
is zero t he default value ,
GetOptions
int erpret s - u
cbuser
as a single opt ion nam ed ucbuser . By set t ing
bundling
t o nonzero,
GetOptions
underst ands bot h - u
cbuser
and -u
cbuser
t he sam e way. This happens because it int erpret s an opt ion beginning wit h a single dash charact er by charact er, on t he basis t hat several single- charact er
opt ions m ay be bundled t oget her. For exam ple, when it sees - u
cbuser
, it looks at t he u, t hen checks whet her or not t he opt ion t akes a following argum ent . I f not , t he next charact er is
int erpret ed as anot her opt ion let t er. Ot herwise, t he rest of t he st ring is t aken as t he opt ions value. For - u
cbuser
, u does t ake an argum ent , so
GetOptions
int erpret s
cbuser
as t he opt ion value.
One problem w it h
GetOptions
is t hat it doesnt support -p wit hout a password t he sam e w ay as t he st andard MySQL client program s. I f -p is followed by anot her opt ion,
GetOptions
correct ly det erm ines t hat t here is no password value present . But if - p is followed by a non- opt ion argum ent , it m isint erpret s t hat argum ent as t he password. The
result is t hat t hese t wo invocat ions of cm dline.pl are not quit e equivalent :
cmdline.pl -h localhost -p -u cbuser xyz Enter password:
cmdline.pl -h localhost -u cbuser -p xyz DBI-connectdatabase=cookbook;host=localhost failed: Access denied for
user: cbuserlocalhost Using password: YES at .cmdline.pl line 40
For t he first com m and,
GetOptions
det erm ines t hat no password is present and t he script prom pt s for one. I n t he second com m and,
GetOptions
has t aken
xyz
as t he password value.
A second problem wit h cm dline.pl is t hat t he password- prom pt ing code is Unix specific and doesnt work under Windows. You could t ry using Term : : ReadKey, which is a st andard Perl
m odule, but it doesnt w ork under Windows, eit her. I f you have a good password prom pt er for Windows, you m ight consider sending it t o m e for inclusion in t he
recipes
dist ribut ion.
2 .1 1 .4 .2 PH P
PHP provides lit t le support for opt ion processing from t he com m and line because it is used predom inant ly in a web environm ent where com m and- line argum ent s are not widely used.
Hence, I m providing no
getopt
- st yle exam ple for PHP. I f you w ant t o go ahead and w rit e your own argum ent processing rout ine, use t he
argv
array cont aining t he argum ent s and t he
argc
variable indicat ing t he num ber of argum ent s.
argv[0]
is t he program nam e, and
argv[1]
t o
argv[argc-1]
are t he following argum ent s. The following code illust rat es how t o access t hese variables:
print Number of arguments: argc\n; print Program name: argv[0]\n;
print Arguments following program name:\n; if argc == 1
print None\n; else
{ for i = 1; i argc; i++
print i: argv[i]\n; }
2 .1 1 .4 .3 Pyt h on
Pyt hon passes com m and argum ent s t o script s as a list in t he
sys.argv
variable. You can access t his variable by im port ing t he
sys
m odule, t hen process it s cont ent s wit h
getopt
if you also im port t he
getopt
m odule. The following program illust rat es how t o get param et ers from t he com m and argum ent s and use t hem for est ablishing a connect ion t o t he
server:
usrbinpython cmdline.py - demonstrate command-line option parsing in Python
import sys import getopt
import MySQLdb try:
opts, args = getopt.getopt sys.argv[1:], h:p:u:,
[ host=, password=, user= ] except getopt.error, e:
print program name and text of error message print s: s sys.argv[0], e
sys.exit 1 default connection parameter values
host_name = password = user_name = iterate through options, extracting whatever values are present
for opt, arg in opts: if opt in -h, --host:
host_name = arg elif opt in -p, --password:
password = arg elif opt in -u, --user:
user_name = arg try:
conn = MySQLdb.connect db = cookbook, host = host_name,
user = user_name, passwd = password
print Connected except MySQLdb.Error, e:
print Cannot connect to server print Error:, e.args[1]
print Code:, e.args[0] sys.exit 1
conn.close print Disconnected
sys.exit 0
getopt
t akes eit her t wo or t hree argum ent s:
•
A list of com m and argum ent s. This should not include t he program nam e,
sys.argv[0]
. You can use
sys.argv[1:]
t o refer t o t he list of argum ent s t hat follow t he program nam e.
•
A st ring nam ing t he short opt ion let t ers. Any of t hese m ay be followed by a colon charact er
:
t o indicat e t hat t he opt ion requires a following argum ent t hat specifies t he opt ions value.
•
An opt ional list of long opt ion nam es. Each nam e m ay be followed by
=
t o indicat e t hat t he opt ion requires a following argum ent .
getopt
ret urns t wo values. The first is a list of opt ion value pairs, and t he second is a list of any rem aining argum ent s following t he last opt ion. cm dline.py it erat es t hrough t he opt ion
list t o det erm ine which opt ions are present and what t heir values are. Not e t hat alt hough you do not specify leading dashes in t he opt ion nam es passed t o
getopt
, t he nam es ret urned from t hat funct ion do include leading dashes.
cm dline.py doesnt prom pt for a m issing password, because t he
getopt
m odule doesnt provide any way t o specify t hat an opt ions argum ent is opt ional. Unfort unat ely, t his m eans
t he -p and - - password argum ent s cannot be specified wit hout a password value.
2 .1 1 .4 .4 Ja va
Java passes com m and- line argum ent s t o program s in t he array t hat you nam e in t he
main
declarat ion. The following declarat ion uses
args
for t hat array: public static void main String[ ] args
A
Getopt
class for parsing argum ent s in Java is available at ht t p: www.urbanophile.com arenn coding download.ht m l
I nst all t his class som ewhere and m ake sure it s inst allat ion direct ory is nam ed in t he value of your
CLASSPATH
environm ent variable. Then you can use
Getopt
as shown in t he following exam ple program : Cmdline.java - demonstrate command-line option parsing in Java
import java.io.; import java.sql.;
import gnu.getopt.; need this for the Getopt class public class Cmdline
{ public static void main String[ ] args
{ Connection conn = null;
String url = null; String hostName = null;
String password = null; String userName = null;
boolean promptForPassword = false; LongOpt[ ] longOpt = new LongOpt[3];
int c; longOpt[0] =
new LongOpt host, LongOpt.REQUIRED_ARGUMENT, null, h; longOpt[1] =
new LongOpt password, LongOpt.OPTIONAL_ARGUMENT, null, p; longOpt[2] =
new LongOpt user, LongOpt.REQUIRED_ARGUMENT, null, u; instantiate option-processing object, then
loop until there are no more options Getopt g = new Getopt Cmdline, args, h:p::u:, longOpt;
while c = g.getopt = -1
{ switch c
{ case h:
hostName = g.getOptarg ; break;
case p: if password option was given with no following
value, need to prompt for the password password = g.getOptarg ;
if password == null promptForPassword = true;
break; case u:
userName = g.getOptarg ; break;
case :: a required argument is missing case ?: some other error occurred
no error message needed; getopt prints its own System.exit 1;
} }
if password == null promptForPassword {
try {
DataInputStream s = new DataInputStream System.in; System.err.print Enter password: ;
really should turn off character echoing here... password = s.readLine ;
} catch Exception e
{ System.err.println Error reading password;
System.exit 1; }
} try
{ construct URL, noting whether or not hostName
was given; if not, MySQL will assume localhost if hostName == null
hostName = ; url = jdbc:mysql: + hostName + cookbook;
Class.forName com.mysql.jdbc.Driver.newInstance ; conn = DriverManager.getConnection url, userName, password;
System.out.println Connected; }
catch Exception e {
System.err.println Cannot connect to server; }
finally {
if conn = null {
try {
conn.close ; System.out.println Disconnected;
} catch Exception e { }
} }
} }
As t he exam ple program dem onst rat es, you prepare t o parse argum ent s by inst ant iat ing a new
Getopt
obj ect t o which you pass t he program s argum ent s and inform at ion describing t he opt ions t he program allows. Then you call
getopt
in a loop unt il it ret urns - 1 t o indicat e t hat no m ore opt ions are present . Each t im e t hrough t he loop,
getopt
ret urns a value indicat ing which opt ion it s seen, and
getOptarg
m ay be called t o obt ain t he opt ions argum ent , if necessary.
getOptarg
ret urns
null
if no following argum ent was provided.
When you creat e an inst ance of t he
Getopt
class, pass it eit her t hree or four argum ent s:
•
The program nam e; t his is used for error m essages.
•
The argum ent array nam ed in your
main
declarat ion.
•
A st ring list ing t he short opt ion let t ers wit hout leading dashes . Any of t hese m ay be followed by a colon
:
t o indicat e t hat t he opt ion requires a following argum ent , or by a double colon
::
t o indicat e t hat a following argum ent is opt ional.
•
An opt ional array t hat cont ains long opt ion inform at ion. To specify long opt ions, you m ust set up an array of
LongOpt
obj ect s. Each of t hese describes a single opt ion, using four param et ers:
o
The opt ion nam e as a st ring wit hout leading dashes .
o
A value indicat ing whet her t he opt ion t akes a following argum ent . This value m ay be
LongOpt.NO_ARGUMENT
,
LongOpt.REQUIRED_ARGUMENT
, or
LongOpt.OPTIONAL_ARGUMENT
.
o
A
StringBuffer
obj ect or
null
.
getopt
det erm ines how t o use t his value based on t he fourt h param et er of t he
LongOpt
obj ect .
o
A value t o be used when t he opt ion is encount ered. This value becom es t he ret urn value of
getopt
if t he
StringBuffer
obj ect nam ed in t he t hird param et er is
null
. I f t he buffer is non-
null
,
getopt
ret urns zero aft er placing a st ring represent at ion of t he fourt h param et er int o t he buffer.
The exam ple program uses
null
as t he
StringBuffer
param et er for each long opt ion obj ect and t he corresponding short opt ion let t er as t he fourt h param et er. This is an easy way t o
cause
getopt
t o ret urn t he short opt ion let t er for bot h t he short and long opt ions, so t hat you can handle t hem wit h t he sam e
case
st at em ent .
Aft er
getopt
ret urns - 1 t o indicat e t hat no m ore opt ions were found in t he argum ent array,
getOptind
ret urns t he index of t he first argum ent following t he last opt ion. The following code fragm ent shows one way t o access t he rem aining argum ent s:
for int i = g.getOptind ; i args.length; i++ System.out.println args[i];
The
Getopt
class offers ot her opt ion-processing behavior in addit ion t o what I ve described here. Read t he docum ent at ion included wit h t he class for m ore inform at ion.
One deficiency of Cm dline.j ava t hat you m ay want t o address is t hat it doesnt disable charact er echoing while it s reading t he password.
2.11.5 Getting Parameters from Option Files