Modernishisalibraryforshellscriptprogrammingwhichprovidesfeatureslikesafervariableandcommandexpansion,newlanguageconstructsforloopiteration,andmuchmore.Modernishprogramsareshellprograms;thenewconstructsaremixedwithshellsyntaxsothattheprogrammercantakeadvantageofthebestofboth.
Thereisnocompiledcodetoinstall,asmodernishiswrittenentirelyintheshelllanguage.Itcanbedeployedinembeddedormulti-usersystemsinwhichnewbinaryexecutablesmaynotbeintroducedforsecurityreasons,andisportableamongnumerousshellimplementations.Theinstallercanalsobundleareducedcopyofthelibrarywithyourscripts,sotheycanrunportablywithaknownversionofmodernishwithoutrequiringpriorinstallation.
Joinusandhelpbreathesomenewlifeintotheshell!Wearelookingfortesters,earlyadopters,anddeveloperstojoinus.Downloadthelatestreleaseorcheckouttheverylatestdevelopmentcodefromthemasterbranch.Readthroughthedocumentationbelow.Playwiththeexamplescriptsandwriteyourown.Trytobreakthelibraryandsendreportsofbreakage.Communicateviathegithubpage,orjointhemailinglists:modernish-dev,modernish-users,modernish-announce.
TableofcontentsGettingstartedTwobasicformsofamodernishprogramSimpleformPortableformInteractiveuseNon-interactivecommandlineuseNon-interactiveusageexamplesShellcapabilitydetectionNamesandidentifiersInternalnamespaceModernishsystemconstantsControlcharacter,whitespaceandshell-safecharacterconstantsReliableemergencyhaltLow-levelshellutilitiesOutputtingstringsLegibilityaliases:not,so,foreverEnhancedexitchdirinsubshellissetsetstatusTestingnumbers,stringsandfilesIntegernumberarithmetictestsandoperationsThearithmeticcommandletArithmeticshortcutsStringandfiletestsStringtestsUnarystringtestsBinarystringmatchingtestsMulti-matchingoptionFiletypetestsFilecomparisontestsFilestatustestsI/OtestsFilepermissiontestsThestackTheshelloptionsstackThetrapstackModulesusesafeWhythesafemode?HowthesafemodeworksImportantnotesforsafemodeExtraoptionsforthesafemodeusevar/loopSimplerepeatloopBASIC-stylearithmeticforloopC-stylearithmeticforloopEnumerativefor/selectloopwithsafesplit/globThefindloopAvailableoptionsAvailablefind-expressionoperandsPickingafindutilityCompatibilitymodeforobsoletefindutilitiesfindloopusageexamplesCreatingyourownloopusevar/localImportantvar/localusagenotesusevar/arithArithmeticoperatorshortcutsArithmeticcomparisonshortcutsusevar/assignusevar/readfusevar/shellquoteshellquoteshellquoteparamsusevar/stackusevar/stack/extrausevar/stack/trapTrapstackcompatibilityconsiderationsThenewDIEpseudosignalusevar/stringusevar/string/touplowusevar/string/trimusevar/string/replaceinusevar/string/appendusevar/unexportusevar/genoptparserusesys/baseusesys/base/mktempusesys/base/readlinkusesys/base/revusesys/base/seqDifferenceswithGNUandBSDsequsesys/base/shufusesys/base/tacusesys/base/whichusesys/base/yesusesys/cmdusesys/cmd/externusesys/cmd/hardenImportantnoteonvariableassignmentsHardeningwhileallowingforbrokenpipesTracingtheexecutionofhardenedcommandsSimpletracingofcommandsusesys/cmd/maprDifferencesfrommapfileDifferencesfromxargsusesys/cmd/procsubstusesys/cmd/sourceusesys/dirusesys/dir/countfilesusesys/dir/mkcdusesys/termusesys/term/putrusesys/term/readkeyAppendixA:ListofshellcapIDsCapabilitiesQuirksBugsWarningIDsAppendixB:RegressiontestsuiteDifferencebetweencapabilitydetectionandregressiontestsTestingmodernishonallyourshellsAppendixC:SupportedlocalesAppendixD:SupportedshellsAppendixE:zsh:integrationwithnativescriptsAppendixF:BundlingmodernishwithyourscriptGettingstartedRuninstall.shandfollowinstructions,choosingyourpreferredshellandinstalllocation.Aftersuccessfulinstallationyoucanrunmodernishshellscriptsandwriteyourown.Rununinstall.shtoremovemodernish.
Boththeinstallanduninstallscriptsareinteractivebydefault,butsupportfullyautomated(non-interactive)operationaswell.Commandlineoptionsareasfollows:
install.sh[-n][-sshell][-f][-Ppathspec][-dinstallroot][-Dprefix][-Bscriptfile...]
-n:non-interactiveoperation-s:specifydefaultshelltoexecutemodernish-f:forceunconditionalinstallationonspecifiedshell-P:specifyanalternativeDEFPATHfortheinstallation(becareful;usuallynotrecommended)-d:specifyrootdirectoryforinstallation-D:extradestinationdirectoryprefix(forpackagers)-B:bundlemodernishwithyourscripts(-Drequired,-nimplied),seeAppendixFuninstall.sh[-n][-f][-dinstallroot]
-n:non-interactiveoperation-f:delete*/modernishdirectorieseveniffilesleft-d:specifyrootdirectoryofmodernishinstallationtouninstallTwobasicformsofamodernishprogramInthesimpleform,modernishisaddedtoascriptwrittenforaspecificshell.Intheportableform,yourscriptisshell-agnosticandmayrunonanyshellthatcanrunmodernish.
SimpleformThesimplestwaytowriteamodernishprogramistosourcemodernishasadotscript.Forexample,ifyouwriteforbash:
#!/bin/bash.modernishusesafeusesys/base...yourprogramstartshere...Themodernishusecommandloadmoduleswithoptionalfunctionality.Thesafemoduleinitialisesthesafemode.Thesys/basemodulecontainsmodernishversionsofcertainbasicbutnon-standardisedutilities(e.g.readlink,mktemp,which),guaranteeingthatmodernishprogramsallhaveaknownversionattheirdisposal.Therearemanyothermodulesaswell.SeeModulesformoreinformation.
Theabovemethodmakestheprogramdependentononeparticularshell(inthiscase,bash).Soitisokaytomixandmatchfunctionalityspecifictothatparticularshellwithmodernishfunctionality.
(Onzsh,thereisawaytointegratemodernishwithnativezshscripts.SeeAppendixE.)
PortableformThemostportablewaytowriteamodernishprogramistousethespecialgenerichashbangpathformodernishprograms.Forexample:
#!/usr/bin/envmodernish#!usesafe#!usesys/base...yourprogrambeginshere...Forportability,itisimportantthereisnospaceafterenvmodernish;NetBSDandOpenBSDconsidertrailingspacespartofthename,soenvwillfailtofindmodernish.
Aprograminthisformisexecutedbywhatevershelltheuserwhoinstalledmodernishonthelocalsystemchoseasthedefaultshell.Sinceyouastheprogrammercan'tknowwhatshellthisis(otherthanthefactthatitpassedsomerigorousPOSIXcompliancetestingexecutedbymodernish),aprograminthisformmustbestrictlyPOSIXcompliant–except,ofcourse,thatitshouldalsomakefulluseoftherichfunctionalityofferedbymodernish.
Notethatmodulesareloadedinadifferentway:theusecommandsarepartofhashbangcomment(startingwith#!liketheinitialhashbangpath).Onlysuchlinesthatimmediatelyfollowtheinitialhashbangpathareevaluated;evenanemptylineinbetweencausestheresttobeignored.Thisspecialwayofpre-loadingmodulesisneededtomakeanyaliasestheydefineworkreliablyonallshells.
InteractiveuseModernishisprimarilydesignedtoenhanceshellprograms/scripts,butalsooffersfeaturesforuseininteractiveshells.Forinstance,thenewrepeatloopconstructfromthevar/loopmodulecanbequitepracticaltorepeatanactionxtimes,andthesafemoduleoninteractiveshellsprovidesconveniencefunctionsformanipulating,savingandrestoringthestateoffieldsplittingandglobbing.
Tousemodernishonyourfavouriteinteractiveshell,youhavetoaddittoyour.profile,.bashrcorsimilarinitfile.
Important:Uponinitialising,modernishadaptsitselftoothersettings,suchasthelocale.Italsoremovescertainaliasesthatmaykeepmodernishfrominitialisingproperly.Soyouhavetoorganiseyour.profileorsimilarfileinthefollowingorder:
first,definegeneralsystemsettings(PATH,locale,etc.);then,.modernishanduseanymodulesyouwant;thendefineanythingthatmaydependonmodernish,andsetyouraliases.Non-interactivecommandlineuseAfterinstallation,themodernishcommandcanbeinvokedasifitwereashell,withthestandardcommandlineoptionsfromothershells(suchas-ctospecifyacommandorscriptdirectlyonthecommandline),plussomeenhancements.Theeffectisthattheshellchosenatinstallationtimewillberunenhancedwithmodernishfunctionality.Itisnotpossibletousemodernishasaninteractiveshellinthisway.
Usage:
modernish[--use=module|shelloption...][scriptfile][arguments]modernish[--use=module|shelloption...]-c[script[me-name[arguments]]]modernish--test[testoption...]modernish[--version|--help]Inthefirstform,thescriptinthefilescriptfileisloadedandexecutedwithanyargumentsassignedtothepositionalparameters.
Inthesecondform,-cexecutesthespecifiedmodernishscript,optionallywiththeme-nameassignedto$MEandtheargumentsassignedtothepositionalparameters.
The--useoptionpre-loadsanygivenmodernishmodulesbeforeexecutingthescript.Themoduleargumenttoeachspecified--useoptionissplitusingstandardshellfieldsplitting.Thefirstfieldisthemodulenameandanyfurtherfieldsbecomeargumentstothatmodule'sinitialisationroutine.
Anygivenshort-formorlong-formshelloptionsaresetorunsetbeforeexecutingthescript.BothPOSIXshelloptionsandshell-specificoptionsaresupported,dependingontheshellexecutingmodernish.Usingtheshelloption-eor-oerrexitisanerror,becausemodernishdoesnotsupportitandwouldbreak.
The--testoptionrunstheregressiontestsuiteandexits.Thisverifiesthatthemodernishinstallationisfunctioningcorrectly.SeeAppendixBformoreinformation.
The--versionand--helpoptionsoutputtherelativeinformationandexit.
Non-interactiveusageexamplesCountto10usingabasicloop:modernish--use=var/loop-c'LOOPfori=1to10;DOputln"$i";DONE'Runaportable-formmodernishprogramusingzshandenhanced-promptxtrace:zsh/usr/local/bin/modernish-oxtrace/path/to/program.shShellcapabilitydetectionModernishincludesabatteryofshellfeature,quirkandbugdetectiontests,eachofwhichisgivenaspecialcapabilityID.SeeAppendixAforalistofshellcapabilitiesthatmodernishcurrentlydetects,aswellasfurthergeneralinformationonthecapabilitydetectionframework.
thisshellhasisthecentralfunctionofthecapabilitydetectionframework.Itnotonlytestsforthepresenceofshellfeatures/quirks/bugs,butcanalsodetectspecificshellbuilt-incommands,shellreservedwords,shelloptions(shortorlongform),andsignals.
Modernishitselfextensivelyusescapabilitydetectiontoadaptitselftotheshellit'srunningon.Thisishowitworksaroundshellbugsandtakesadvantageofefficientfeaturesnotallshellshave.Butanyscriptusingthelibrarycandothisinthesameway,withthehelpofthisfunction.
Testresultsarecachedinmemory,sorepeatedchecksusingthisshellhasareefficientandthereisnoneedtoavoidcallingittooptimiseperformance.
Usage:
thisshellhasitem...
IfitemcontainsonlyASCIIcapitallettersA-Z,digits0-9or_,returntheresultstatusoftheassociatedmodernishcapabilitydetectiontest.IfitemisanyotherASCIIword,checkifitisashellreservedwordorbuilt-incommandonthecurrentshell.Ifitemis--(end-of-optionsdelimiter),disabletherecognitionofoperatorsstartingwith-forsubsequentitems.Ifitemstartswith--rw=or--kw=,checkiftheidentifierimmediatelyfollowingthesecharactersisashellreservedword(a.k.a.shellkeyword).Ifitemstartswith--bi=,similarlycheckforashellbuilt-incommand.Ifitemstartswith--sig=,checkiftheshellknowsaboutasignal(usablebykill,trap,etc.)bythenameornumberfollowingthe=.Ifanumber>128isgiven,theremainderofitsdivisionby128ischecked.Ifthesignalisfound,itscanonicalisedsignalnameisleftintheREPLYvariable,otherwiseREPLYisunset.(Ifmultiple--sig=itemsaregivenandallarefound,REPLYcontainsonlythelastone.)Ifitemis-ofollowedbyaseparateword,checkifthisshellhasalong-formshelloptionbythatname.Ifitemisanyotherletterordigitprecededbyasingle-,checkifthisshellhasashort-formshelloptionbythatcharacter.itemcanalsobeoneofthefollowingtwooperators.--cacherunsallexternalmodernishshellcapabilityteststhathavenotyetbeenrun,causingthecachetobecomplete.--showperformsa--cacheandthenoutputsalltheIDsofpositiveresults,oneperline.thisshellhascontinuestoprocessitemsuntiloneofthemproducesanegativeresultorisfoundinvalid,atwhichpointanyfurtheritemsareignored.Sothefunctiononlyreturnssuccessfullyifalltheitemsspecifiedwerefoundonthecurrentshell.(Tocheckifeitheroneitemoranotherispresent,useseparatethisshellhasinvocationsseparatedbythe||shelloperator.)
Exitstatus:0ifthisshellhasalltheitemsinquestion;1ifnot;2ifanitemwasencounteredthatisnotrecognisedasavalididentifier.
Note:Thetestsforthepresenceofreservedwords,built-incommands,shelloptions,andsignalsaredifferentfromcapabilitydetectiontestsinanimportantway:theyonlycheckifanitembythatnameexistsonthisshell,anddon'tverifythatitdoesthesamethingasonanothershell.
NamesandidentifiersAllmodernishfunctionsrequireportablevariableandshellfunctionnames,thatis,onesconsistingofASCIIuppercaseandlowercaseletters,digits,andtheunderscorecharacter_,andthatdon'tbeginwithdigit.Forshelloptionnames,theconstraintsarethesameexceptadash-isalsoaccepted.Aninvalididentifierisgenerallytreatedasafatalerror.
InternalnamespaceFunction-localvariablesarenotsupportedbythestandardPOSIXshell;onlyglobalvariablesareprovidedfor.Modernishneedsawaytostoreitsinternalstatewithoutinterferingwiththeprogramusingit.Somostofthemodernishfunctionalityusesaninternalnamespace_Msh_*forvariables,functionsandaliases.Allthesenamesmaychangeatanytimewithoutnotice.Anynamesstartingwith_Msh_shouldbeconsideredsacrosanctanduntouchable;modernishprogramsshouldneverdirectlyusetheminanyway.Ofcoursethisisnotenforceable,butnamesstartingwith_Msh_shouldbeuncommonenoughthatnounintentionalconflictislikelytooccur.
ModernishsystemconstantsModernishprovidescertainconstants(read-onlyvariables)tomakelifeeasier.Theseinclude:
$MSH_VERSION:Theversionofmodernish.$MSH_PREFIX:Installationprefixforthismodernishinstallation(e.g./usr/local).$MSH_MDL:Mainmodulesdirectory.$MSH_AUX:Mainhelperscriptsdirectory.$MSH_CONFIG:Pathtomodernishuserconfigurationdirectory.$ME:Pathtothecurrentprogram.Replacementfor$0.Thisisnecessaryifthehashbangpath#!/usr/bin/envmodernishisused,oriftheprogramislaunchedlikesh/path/to/bin/modernish/path/to/script.sh,astheseset$0tothepathtobin/modernishandnotyourprogram'spath.$MSH_SHELL:Pathtothedefaultshellforthismodernishinstallation,chosenatinstalltime(e.g./bin/sh).Thisisashellthatisknowntohavepassedallthemodernishtestsforfatalbugs.Cross-platformscriptsshoulduseitinsteadofhard-coding/bin/sh,becauseonsomeoperatingsystems(NetBSD,OpenBSD,Solaris)/bin/shisnotPOSIXcompliant.$SIGPIPESTATUS:TheexitstatusofacommandkilledbySIGPIPE(abrokenpipe).Forinstance,ifyouusegrepsomethingsomefile.txt|moreandyouquitmorebeforegrepisfinished,grepiskilledbySIGPIPEandexitswiththatparticularstatus.HardenedcommandsorfunctionsmayneedtohandlesuchaSIGPIPEexitspeciallytoavoidundulykillingtheprogram.Theexactvalueofthisexitstatusisshell-specific,somodernishrunsaquicktesttodetermineitatinitialisationtime.IfSIGPIPEwassettoignorebytheprocessthatinvokedthecurrentshell,$SIGPIPESTATUScan'tbedetectedandissettothespecialvalue99999.SeealsothedescriptionoftheWRN_NOSIGPIPEIDforthisshellhas.$DEFPATH:ThedefaultsystempathguaranteedtofindcompliantPOSIXutilities,asgivenbygetconfPATH.$ERROR:Aguaranteedunsetvariablethatcanbeusedtotriggeranerrorthatexitsthe(sub)shell,forinstance::"${4+${ERROR:?excessarguments}}"(erroron4ormorearguments)Controlcharacter,whitespaceandshell-safecharacterconstantsPOSIXdoesnotprovideforthequotedC-styleescapecodescommonlyusedinbash,kshandzsh(suchas$'\n'torepresentanewlinecharacter),leavingthestandardshellwithoutaconvenientwaytorefertocontrolcharacters.Modernishprovidescontrolcharacterconstants(read-onlyvariables)withhexadecimalsuffixes$CC01..$CC1Fand$CC7F,aswellas$CCe,$CCa,$CCb,$CCf,$CCn,$CCr,$CCt,$CCv(correspondingwithprintfbackslashescapecodes).Thismakesiteasytoinsertcontrolcharactersindouble-quotedstrings.
Moreconvenienceconstants,handyforuseinbracketglobpatternsforusewithcaseormodernishmatch:
$CONTROLCHARS:AllASCIIcontrolcharacters.$WHITESPACE:AllASCIIwhitespacecharacters.$ASCIIUPPER:TheASCIIuppercaselettersAtoZ.$ASCIILOWER:TheASCIIlowercaselettersatoz.$ASCIIALNUM:TheASCIIalphanumericcharacters0-9,A-Zanda-z.$SHELLSAFECHARS:Safe-listforshell-quoting.$ASCIICHARS:ThecompletesetofASCIIcharacters(minusNUL).Usageexamples:
#Useaglobpatterntocheckagainstcontrolcharactersinastring:ifstrmatch"$var""*[$CONTROLCHARS]*";thenputln"\$varcontainsatleastonecontrolcharacter"fi#Use'!'(not'^')tocheckforcharacters*not*partofaparticularset:ifstrmatch"$var""*[!$ASCIICHARS]*";thenputln"\$varcontainsatleastonenon-ASCIIcharacter";;fi#Safelysplitfieldsatanywhitespace,commaorslash(requiressafemode):usesafeLOOPfor--split=$WHITESPACE,/fieldin$my_items;DOputln"Item:$field"DONEReliableemergencyhaltThediefunctionreliablyhaltsprogramexecution,evenfromwithinsubshells,optionallyprintinganerrormessage.Notethatdieismeantforanemergencyprogramhaltonly,i.e.insituationswerecontinuingwouldmeantheprogramisinaninconsistentorundefinedstate.Shellscriptsrunninginaninconsistentorundefinedstatemaywreakallsortsofhavoc.Theyarealsonotoriouslydifficulttoterminatecorrectly,especiallyifthefatalerroroccurswithinasubshell:exitwon'tworkthen.That'swhydieisoptimisedforkillingalltheprogram'sprocesses(includingsubshellsandexternalcommandslaunchedbyit)asquicklyaspossible.Itshouldneverbeusedforexitingtheprogramnormally.
Oninteractiveshells,diebehavesdifferently.Itdoesnotkillorexityourshell;instead,itissuesSIGINTtotheshelltoaborttheexecutionofyourrunningcommand(s),whichisequivalenttopressingCtrl+C.Inaddition,ifdieisinvokedfromasubshellsuchasabackgroundjob,itkillsallprocessesbelongingtothatjob,butleavesotherrunningjobsalone.
Usage:die[message]
Ifthetrapstackmoduleisactive,aspecialDIEpseudosignalcanbetrapped(usingplainoldtraporpushtrap)toperformemergencycleanupcommandsuponinvokingdie.
IftheMSH_HAVE_MERCYvariableissetinascriptanddieisinvokedfromasubshell,thendiewillonlyterminatethecurrentsubshellanditssubprocessesandwillnotexecuteDIEtraps,allowingthescripttoresumeexecutionintheparentprocess.Thisisforuseinspecialcases,suchasregressiontests,andisstronglydiscouragedforgeneraluse.Modernishunsetsthevariableoninitsoitcannotbeinheritedfromtheenvironment.
Low-levelshellutilitiesOutputtingstringsThePOSIXshelllacksasimple,straightforwardandportablewaytooutputarbitrarystringsoftext,somodernishaddstwocommandsforthis.
putprintseachargumentseparatedbyaspace,withoutatrailingnewline.putlnprintseachargument,terminatingeachwithanewlinecharacter.Thereisnoprocessingofoptionsorescapecodes.(Modernishconstants$CCn,etc.canbeusedtoinsertcontrolcharactersindouble-quotedstrings.Toprocessescapecodes,useprintfinstead.)
Theechocommandisnotoriouslyunportableandkindofbroken,soisdeprecatedinfavourofputandputln.Modernishdoesprovideitsownversionofecho,butitisonlyactivatedforportable-form)scripts.Otherwise,theshell-specificversionofechoisleftintact.Themodernishversionofechodoesnotinterpretanyescapecodesandsupportsonlyoneoption,-n,which,likeBSDecho,suppressesthefinalnewline.However,unlikeBSDecho,if-nistheonlyargument,itisnotinterpretedasanoptionandthestring-nisprintedinstead.Thismakesitsafetooutputarbitrarydatausingthisversionofechoaslongasitisgivenasasingleargument(usingquotingifneeded).
Legibilityaliases:not,so,foreverModernishsetsthreealiasesthatcanhelptomaketheshelllanguagelookslightlyfriendlier.Theiruseisoptional.
notisanewsynonymfor!.Theycanbeusedinterchangeably.
soisacommandthattestsifthepreviouscommandexitedwithastatusofzero,soyoucantesttheprecedingcommand'ssuccesswithifsoorifnotso.
foreverisanewsynonymforwhile:;.Thisallowssimpleinfiniteloopsoftheform:foreverdostuff;done.
EnhancedexitTheexitcommandcanbeusedasnormal,buthasgainedcapabilities.
Extendedusage:exit[-u][status[message]]
Asperstandard,ifstatusisnotspecified,itdefaultstotheexitstatusofthecommandexecutedimmediatelypriortoexit.Otherwise,itisevaluatedasashellarithmeticexpression.Ifitisinvalidassuch,theshellexitsimmediatelywithanarithmeticerror.Anyremainingargumentsafterstatusarecombined,separatedbyspaces,andtakenasamessagetoprintonexit.Themessageshownisprecededbythenameofthecurrentprogram($MEminusdirectories).Notethatitisnotpossibletoskipstatuswhilespecifyingamessage.Ifthe-uoptionisgiven,andtheshellfunctionshowusageisdefined,thatfunctionisruninasubshellbeforeexiting.Itisintendedtoprintamessageshowinghowthecommandshouldbeinvoked.The-uoptionhasnoeffectifthescripthasnotdefinedashowusagefunction.Ifstatusisnon-zero,themessageandtheoutputoftheshowusagefunctionareredirectedtostandarderror.chdirchdirisarobustcdreplacementforuseinscripts.
Thestandardcdcommandisdesignedforinteractiveshellsandappropriatetousethere.However,forscripts,itsfeaturescreateseriouspitfalls:
The$CDPATHvariableissearched.Ascriptmayinheritauser'sexported$CDPATH,socdmaychangetoanunintendeddirectory.cdcannotbeusedwitharbitrarydirectorynames(suchasuntrusteduserinput),assomeoperandshavespecialmeanings,evenafter--.POSIXspecifiesthat-changesdirectoryto$OLDPWD.Onzsh(eveninshmodeonzsh<=5.7.1),numericoperandssuchas+12or-345representdirectorystackentries.Allsuchpathsneedescapingbyprefixing./.Symboliclinksindirectorypathcomponentsarenotresolvedbydefault,leavingapotentialsymlinkattackvector.Thus,robustandportableuseofcdinscriptsisunreasonablydifficult.Themodernishchdirfunctioncallscdinawaythattakescareofalltheseissuesautomatically:itdisables$CDPATHandspecialoperandmeanings,andresolvessymboliclinksbydefault.
Usage:chdir[-f][-L][-P][--]directorypath
Normally,failuretochangethepresentworkingdirectorytodirectorypathisafatalerrorthatendstheprogram.Totoleratefailure,addthe-foption;inthatcase,exitstatus0signifiessuccessandexitstatus1signifiesfailure,andscriptsshouldalwayscheckandhandleexceptions.
Theoptions-L(logical:don'tresolvesymlinks)and-P(physical:resolvesymlinks)arethesameasincd,exceptthat-Pisthedefault.NotethatonashellwithBUG_CDNOLOGIC(NetBSDsh),the-Loptiontochdirdoesnothing.
Tousearbitrarydirectorynames(e.g.directorynamesinputbytheuserorotheruntrustedinput)alwaysusethe--separatorthatsignalstheendofoptions,orpathsstartingwith-maybemisinterpretedasoptions.
insubshellTheinsubshellfunctionchecksifyou'recurrentlyrunninginasubshellenvironment(usuallycalledsimplysubshell).
Asubshellisacopyoftheparentshellthatstartsoutasanexactduplicate(includingnon-exportedvariables,functions,etc.),exceptfortraps.Anewsubshellisinvokedbyconstructslike(parentheses),$(commandsubstitutions),pipe|lines,and&(tolaunchabackgroundsubshell).Uponexitingasubshell,allchangestoitsstatearelost.
Thisisnottobeconfusedwithanewlyinitialisedshellthatismerelyachildprocessofthecurrentshell,whichissometimes(confusinglyandwrongly)calleda"subshell"aswell.Thisdocumentationavoidssuchamisleadinguseoftheterm.
Usage:insubshell[-p|-u]
Thisfunctionreturnssuccess(0)ifitwascalledfromwithinasubshellandnon-success(1)ifnot.Oneoftwooptionscanbegiven:
-p:StoretheprocessID(PID)ofthecurrentsubshellormainshellinREPLY.-u:StoreanidentifierinREPLYthatisusefulfordeterminingifyou'veenteredasubshellrelativetoapreviouslystoredidentifier.Thecontentandformatareunspecifiedandshell-dependent.issetissetchecksifavariable,shellfunctionoroptionisset,orhascertainattributes.Usage:
issetvarname:Checkifavariableisset.isset-vvarname:Id.isset-xvarname:Checkifvariableisexported.isset-rvarname:Checkifvariableisread-only.isset-ffuncname:Checkifashellfunctionisset.isset-optionletter(e.g.isset-C):Checkifshelloptionisset.isset-ooptionname:Checkifshelloptionissetbylongname.Exitstatus:0iftheitemisset;1ifnot;2iftheargumentisnotrecognisedasavalididentifier.Unlikemostothermodernishcommands,issetdoesnottreataninvalididentifierasafatalerror.
Whencheckingashelloption,anonexistentshelloptionisnotanerror,butreturnsthesameresultasanunsetshelloption.(Tocheckifashelloptionexists,usethisshellhas.
Note:justisset-fchecksifshelloption-f(a.k.a.-onoglob)isset,butwithanextraargument,itchecksifashellfunctionisset.Similarly,isset-xchecksifshelloption-x(a.k.a-oxtrace)isset,butisset-xvarnamechecksifavariableisexported.Ifyouuseunquotedvariableexpansionshere,makesurethey'renotempty,ortheshell'semptyremovalmechanismwillcausethewrongthingtobechecked(eveninthesafemode).
setstatussetstatusmanuallysetstheexitstatus$?tothedesiredvalue.Thefunctionexitswiththestatusindicated.Thisisusefulinconditionalconstructsifyouwanttoprepareaparticularexitstatusforasubsequentexitorreturncommandtoinheritundercertaincircumstances.Thestatusargumentisaparsedasashellarithmeticexpression.Anegativevalueistreatedasafatalerror.Thebehaviourofvaluesgreaterthan255isnotstandardisedanddependsonyourparticularshell.
Testingnumbers,stringsandfilesThetest/[commandisthebaneofcasualshellscripters.Evenadvancedshellprogrammersarefrequentlycaughtunawarebyoneofthemanypitfallsofitsarcane,hackishsyntax.Itattemptstolooklikeshellgrammarwithoutbeingshellgrammar,causingmyriadproblems(1,2).Its-a,-o,(and)operatorsareinherentlyandfatallybrokenasthereisnowaytoreliablydistinguishoperatorsfromoperands,soPOSIXdeprecatestheiruse;however,mostmanualpagesdonotincludethisessentialinformation,andeventhefewthatdowillnottellyouwhattodoinstead.
Ksh,zshandbashoffera[[alternativethatfixesmanyoftheseproblems,asitisintegratedintotheshellgrammar.Nevertheless,itincreasesconfusion,asentirelydifferentgrammarandquotingrulesapplywithin[[...]]thanoutsideit,yetmanyscriptsendupusingtheminterchangeably.ItisalsonotavailableonallPOSIXshells.(Tomakemattersworse,Busyboxashhasafalse-friend[[thatisjustanaliasof[,withnoneoftheshellgrammarintegration!)
Finally,thePOSIXtest/[commandisincompatiblewiththemodernish"safemode"whichaimstoeliminatemostoftheneedtoquotevariables.Seeusesafeformoreinformation.
Modernishdeprecatestest/[and[[completely.Instead,itoffersacomprehensivealternativecommanddesignthatworkswiththeusualshellgrammarinasaferwaywhileofferingvariousfeatureenhancements.Thefollowingreplacementsareavailable:
评论