Perl Command-Line Options

文章推薦指數: 80 %
投票人數:10人

Perl has a large number of command-line options that can help to make your programs more concise and open up many new possibilities for ... MORE: Togglenavigation Perl.com   ABOUT   AUTHORS   CATEGORIES #   TAGS PerlCommand-LineOptions Aug10,2004by DaveCross Perlhasalargenumberofcommand-lineoptionsthatcanhelptomakeyourprogramsmoreconciseandopenupmanynewpossibilitiesforone-offcommand-linescriptsusingPerl.Inthisarticlewe’lllookatsomeofthemostusefulofthese. SafetyNetOptions TherearethreeoptionsIliketothinkofasa“safetynet,”astheycanstopyoufrommakingafoolofyourselfwhenyou’redoingsomethingparticularlyclever(orstupid!).Andwhiletheyaren’tevernecessary,it’srarethatyou’llfindanexperiencedPerlprogrammerworkingwithoutthem. Thefirstoftheseis-c.Thisoptioncompilesyourprogramwithoutrunningit.Thisisagreatwaytoensurethatyouhaven’tintroducedanysyntaxerrorswhileyou’vebeeneditingaprogram.WhenI’mworkingonaprogramInevergomorethanafewminuteswithoutsavingthefileandrunning: $perl-c Thismakessurethattheprogramstillcompiles.It’sfareasiertofixproblemswhenyou’veonlymadeafewchangesthanitistotypeinacoupleofhundredoflinesofcodeandthentrytodebugthat. Thenextsafetynetisthe-woption.ThisturnsonwarningsthatPerlwillthengiveyouifitfindsanyofanumberofproblemsinyourcode.Eachofthesewarningsisapotentialbuginyourprogramandshouldbeinvestigated.InmodernversionsofPerl(since5.6.0)the-woptionhasbeenreplacedbytheusewarningspragma,whichismoreflexiblethanthecommand-lineoptionsoyoushouldn’tuse-winnewcode. Thefinalsafetynetisthe-Toption.ThisoptionputsPerlinto“taintmode.”Inthismode,Perlinherentlydistrustsanydatathatitreceivesfromoutsidetheprogram’ssource–forexample,datapassedinonthecommandline,readfromafile,ortakenfromCGIparameters. Tainteddatacannotbeusedinanexpressionthatinteractswiththeoutsideworld–forexample,youcan’tuseitinacalltosystemorasthenameofafiletoopen.Thefulllistofrestrictionsisgivenintheperlsecmanualpage. Inordertousethisdatainanyofthesepotentiallydangerousoperationsyouneedtountaintit.Youdothisbycheckingitagainstaregularexpression.AdetaileddiscussionoftaintmodewouldfillanarticleallbyitselfsoIwon’tgointoanymoredetailshere,butusingtaintmodeisaverygoodhabittogetinto–particularlyifyouarewritingprograms(likeCGIprograms)thattakeunknowninputfromusers. Actuallythere’soneotheroptionthatbelongsinthissetandthat’s-d.ThisoptionputsyouintothePerldebugger.Thisisalsoasubjectthat’stoobigforthisarticle,butIrecommendyoulookat“perldocperldebug”orRichardFoley’sPerlDebuggerPocketReference. Command-LinePrograms ThenextfewoptionsIwanttolookatmakeiteasytorunshortPerlprogramsonthecommandline.Thefirstone,-e,allowsyoutodefinePerlcodetobeexecutedbythecompiler.Forexample,it’snotnecessarytowritea“HelloWorld”programinPerlwhenyoucanjusttypethisatthecommandline. $perl-e'print"HelloWorld\n"' Youcanhaveasmany-eoptionsasyoulikeandtheywillberunintheorderthattheyappearonthecommandline. $perl-e'print"Hello";'-e'print"World\n"' NoticethatlikeanormalPerlprogram,allbutthelastlineofcodeneedstoendwitha;character. Althoughitispossibletousea-eoptiontoloadamodule,Perlgivesyouthe-Moptiontomakethateasier. $perl-MLWP::Simple-e'printhead"http://www.example.com"' So-Mmoduleisthesameasusemodule.Ifthemodulehasdefaultimportsyoudon’twantimportedthenyoucanuse-minstead.Using-mmoduleistheequivalentofusemodule(),whichturnsoffanydefaultimports.Forexample,thefollowingcommanddisplaysnothingastheheadfunctionwon’thavebeenimportedintoyourmainpackage: $perl-mLWP::Simple-e'printhead"http://www.example.com"' The-Mand-moptionsimplementvariousnicepiecesofsyntacticsugartomakeusingthemaseasyaspossible.Anyargumentsyouwouldnormallypasstotheusestatementcanbelistedfollowingan=sign. $perl-MCGI=:standard-e'printheader' Thiscommandimportsthe“:standard”exportsetfromCGI.pmandthereforetheheaderfunctionbecomesavailabletoyourprogram.Multipleargumentscanbelistedusingquotesandcommasasseparators. $perl-MCGI='header,start_html'-e'printheader,start_html' Inthisexamplewe’vejustimportedthetwomethodsheaderandstart_htmlasthosearetheonlyonesweareusing. ImplicitLoops Twoothercommand-lineoptions,-nand-p,addloopsaroundyour-ecode.Theyarebothveryusefulforprocessingfilesalineatatime.Ifyoutypesomethinglike: $perl-n-e'somecode'file1 ThenPerlwillinterpretthatas: LINE: while(<>){ #yourcodegoeshere } Noticetheuseoftheemptyfileinputoperator,whichwillreadallofthefilesgivenonthecommandlinealineatatime.Eachlineoftheinputfileswillbeput,inturn,into$_sothatyoucanprocessit.Asaexample,try: $perl-n-e'print"$.-$_"'file Thisgetsconvertedto: LINE: while(<>){ print"$.-$_" } Thiscodeprintseachlineofthefiletogetherwiththecurrentlinenumber. The-poptionmakesthateveneasier.Thisoptionalwaysprintsthecontentsof$_eachtimearoundtheloop.Itcreatescodelikethis: LINE: while(<>){ #yourcodegoeshere }continue{ printordie"-pdestination:$!\n"; } Thisusesthelittle-usedcontinueblockonawhilelooptoensurethattheprintstatementisalwayscalled. Usingthisoption,ourlinenumbergeneratorbecomes: $perl-p-e'$_="$.-$_"' Inthiscasethereisnoneedfortheexplicitcalltoprintas-pcallsprintforus. NoticethattheLINE:labelistheresothatyoucaneasilymovetothenextinputrecordnomatterhowdeepinembeddedloopsyouare.YoudothisusingnextLINE. $perl-n-e'nextLINEunless/pattern/;print$_' Ofcourse,thatexamplewouldprobablybewrittenas: $perl-n-e'printunless/pattern/' Butinamorecomplexexample,thenextLINEconstructcouldpotentiallymakeyourcodeeasiertounderstand. Ifyouneedtohaveprocessingcarriedouteitherbeforeorafterthemaincodeloop,youcanuseaBEGINorENDblock.Here’saprettybasicwaytocountthewordsinatextfile: $perl-ne'END{print$t}@w=/(\w+)/g;$t+=@w'file.txt Eachtimeroundtheloopweextractallofthewords(definedascontiguousrunsof\wcharactersinto@wandaddthenumberofelementsin@wtoourtotalvariable$t.TheENDblockrunsaftertheloophascompletedandprintsoutthefinalvaluein$t. Ofcourse,people’sdefinitionofwhatconstitutesavalidwordcanvary.ThedefinitionusedbytheUnixwc(wordcount)programisastringofcharactersdelimitedbywhitespace.Wecansimulatethatbychangingourprogramslightly,likethis: $perl-ne'END{print$x}@w=split;$x+=@w'file.txt Butthereareacoupleofcommand-lineoptionsthatwillmakethatevensimpler.Firstlythe-aoptionturnsonautosplitmode.Inthismode,eachinputrecordissplitandtheresultinglistofelementsisstoredinanarraycalled@F.Thismeansthatwecanwriteourword-countprogramlikethis: $perl-ane'END{print$x}$x+=@F'file.txt Thedefaultvalueusedtosplittherecordisoneormorewhitespacecharacters.Itis,ofcourse,possiblethatyoumightwanttosplittheinputrecordonanothercharacterandyoucancontrolthiswiththe-Foption.Soifwewantedtochangeourprogramtosplitonallnon-wordcharacterswecoulddosomethinglikethis: $perl-F'\W'-ane'END{print$x}$x+=@F'file.txt Foramorepowerfulexampleofwhatwecandowiththeseoptions,let’slookattheUnixpasswordfile.Thisisasimple,colon-delimitedtextfilewithonerecordperuser.Theseventhcolumninthisfileisthepathoftheloginshellforthatuser.Wecanthereforeproduceareportofthemost-usedshellsonagivensystemwithacommand-linescriptlikethis: $perl-F':'-ane'$s{$F[6]}++;'\ >-e'END{print"$_:$s{$_}"forkeys%s}'/etc/passwd OK,soit’slongerthanonelineandtheoutputisn’tsorted(althoughit’squiteeasytoaddsorting),butperhapsyoucangetasenseofthekindsofthingsthatyoucandofromthecommandline. RecordSeparators InmypreviousarticleItalkedalotabout$/and$\–theinputandoutputrecordseparators.$/defineshowmuchdataPerlwillreadeverytimeyouaskitforthenextrecordfromafilehandle,and$\containsavaluethatisappendedtotheendofanydatathatyourprogramprints.Thedefaultvalueof$/isanewlineandthedefaultvalueof$\isanemptystring(whichiswhyyouusuallyexplicityaddanewlinetoyourcallstoprint). Nowintheimplicitloopssetupby-nand-pitcanbeusefultodefinethevaluesof$/and$\.Youcould,ofcourse,dothisinaBEGINblock,butPerlgivesyouaneasieroptionwiththe-0(that’sazero)and-l(that’sanL)command-lineoptions.Thiscangetalittleconfusing(well,itconfusesme)soI’llgoslowly. Using-0andgivingitahexadecimaloroctalnumbersets$/tothatvalue.Thespecialvalue00putsPerlinparagraphmodeandthespecialvalue0777putsPerlintofileslurpmode.Thesearethesameassetting$/toanemptystringandundefrespectively. Using-landgivingitnovaluehastwoeffects.Firstly,itautomaticallychompstheinputrecord,andsecondly,itsets$\equalto$/.Ifyougive-lanoctalnumber(andunlike-0itdoesn’taccepthexnumbers)itsets$\tothecharacterrepresentedbythatnumberandalsoturnsonauto-chomping. Tobehonest,Irarelyusethe-0optionandIusuallyusethe-loptionwithoutanargumentjusttoaddanewlinetotheendofeachlineofoutput.Forexample,I’dusuallywritemyoriginal“HelloWorld”exampleas: $perl-le'print"HelloWorld"' IfI’mdoingsomethingthatrequireschangingthevaluesoftheinputandoutputrecordseparatorsthenI’mprobablyoutoftherealmofcommand-linescripts. In-PlaceEditing Withtheoptionsthatwehavealreadyseen,it’sveryeasytobuildupsomepowerfulcommand-lineprograms.It’sverycommontoseecommandlineprogramsthatuseUnixI/Oredirectionlikethis: $perl-pe'somecode'output.txt Thistakesrecordsfrominput.txt,carriesoutsomekindoftransformation,andwritesthetransformedrecordtooutput.txt.Insomecasesyoudon’twanttowritethechangeddatatoadifferentfile,it’softenmoreconvenientifthealtereddataiswrittenbacktothesamefile. Youcangettheappearanceofthisusingthe-ioption.Actually,Perlrenamestheinputfileandreadsfromthisrenamedversionwhilewritingtoanewfilewiththeoriginalname.If-iisgivenastringargument,thenthatstringisappendedtothenameoftheoriginalversionofthefile.Forexample,tochangealloccurrencesof“PHP”to“Perl”inadatafileyoucouldwritesomethinglikethis: $perl-i-pe's/\bPHP\b/Perl/g'file.txt Perlreadstheinputfilealineatatime,makingthesubstitution,andthenwritingtheresultsbacktoanewfilethathasthesamenameastheoriginalfile–effectivelyoverwritingit.Ifyou’renotsoconfidentofyourPerlabilitiesyoumighttakeabackupoftheoriginalfile,likethis: $perl-i.bak-pe's/\bPHP\b/Perl/g'file.txt You’llendupwiththetransformeddatainfile.txtandtheoriginalfilebackedupinfile.txt.bak.Ifyou’reafanofvithenyoumightliketouse-i~instead. FurtherInformation Perlhasalargenumberofcommand-lineoptions.Thisarticlehassimplylistedafewofthemostuseful.Forthefulllist(andformoreinformationontheonescoveredhere)seethe“perlrun”manualpage. Tags tooling DaveCross Browsetheirarticles Feedback Somethingwrongwiththisarticle?HelpusoutbyopeninganissueorpullrequestonGitHub Tweetsbyperlfoundation



請為這篇文章評分?