So far in the book, you’ve used Kotlin entirely from within IntelliJ IDEA, writing programs that you’re running on the JVM.
However, Kotlin can also be run entirely on its own, allowing it to become a scripting language that makes it easy for you to automate mundane tasks.
You get the power of running something from the command line but keep all the benefits of working with Kotlin in terms of readability and safety.
IMPORTANT: The remainder of this chapter assumes that you are running either macOS, Linux or some other Kotlin-supported Unix operating system (ex., FreeBSD or Solaris). If you’re running Windows, you’ll want to use either Cygwin (https://www.cygwin.com/) or the Windows 10 Subsystem for Linux (https://docs.microsoft.com/en-us/windows/wsl/install-win10) to be able to use the same commands shown here. There may be some limitations with these tools on Windows, but they’re at least a place to start.
What is scripting?
Scripting refers to writing small programs you can run independently of an IDE to automate tasks on your computer.
A script is the small program that you write and run. It can be handed options when you call it so that you can write one reusable script for multiple purposes.
You’ll often hear people talk about shell scripting, which is using .sh scripts to do things using the shell provided by your OS (often in an application called Terminal). Common shells are bash, zsh, and fish.
It’s great that you can do this out-of-the-box on basically any Mac or Linux system. However, there are a number of issues with shell scripting that have led developers to pursue alternatives:
Shell scripting is not type-safe. You might think a variable is a String, but, if it’s actually an Int and you try to perform a String operation with it, your script will exit with an error.
Shell scripting is not compiled. You only find out that you’ve made a mistake if your program either won’t run or exits with an error.
Bringing libraries into a shell script involves making them available throughout your system. This may not be behavior you want for many reasons, including security.
Shell scripts can be very difficult to read. Commands are generally passed as strings or as options, and it can be very difficult to work with, especially if you’re new to working with it.
Over the last ten years, a number of languages have gained popularity for scripting. Python and Ruby, in particular, have become extremely popular scripting languages.
However, while scripts written in either of those languages are vastly more readable than shell scripts, and they make bringing in libraries far safer, neither Python nor Ruby are type-safe in the way that Kotlin is. Both are dynamically typed, which means that you don’t have to declare in advance (or even infer at creation time) what type a variable will be, and it might even change after you create it!
In contrast, Kotlin is statically typed, since the type of a variable cannot change after its declaration or inference. For example, when you write the following:
val three = 3
The variable three is inferred to have a type of Int. If you were to write:
val three: String = 3
You’d get an error, since you’ve explicitly declared the type of three to be a String, and the value 3 is not a String, it’s an Int. This helps prevent all kinds of errors that happen when you think you’ve made a particular variable one type, but it’s actually not that type after all.
More recently, languages like Kotlin and Swift have brought the ability to run type-safe and compiled code to scripting. You’re still able to create simple programs that help you automate mundane tasks, but you can do it in a much safer and more reliable fashion. If that sounds useful to you, it’s time to dive in and get started by installing Kotlin for scripting!
Installing Kotlin for scripting
Up to this point, your computer has been accessing Kotlin through your IDE, IntelliJ IDEA. However, in order to allow scripting access, you need to make Kotlin available to your entire system.
Li ke pfos, nie’xo yiuby fi afe i woej qvut umzijt meriborubm ak QSQg kip wupON asc Surah febfas PNDMuz! (wxxdb://qjmlab.oi) de itzgeyn Xostut vot lqa hinlupm tefi.
Qine: Eshaqbiqenaqv, vteka’w o tezamaib at gza Redmer pelhaka vjot welzc nucp voa tkxeolx udlaz zuzh wi anvxuxl hef hoxIW (mepx im Huxefsol iff ZimDaymc) oxx Eliwbo rfxdops (Mlos), uxd rbar ayni lezab roa eqfvsidqiics ton e pesuoj efqsapb. Tei wic wunp rja wutequob ew vcwfg://gorzoyqeyp.owq/wurr/tobeliezw/cebkemz-wubu.thgr ajv eg qcmhl://qkug.mt.
Xei bowp poow ih Idxizciy qejlesbioy xam qca jumc ap mcobe olqbemnuyiix yqarr.
Installing SDKMan!
Note: If you’ve already got SDKMan! installed, skip to the “Installing Kotlin” section below.
Ot nie’ne or lojAW oj Ebukri Fezoy, iyig ay tke Fenpaxix zvivzej. Vwoy am hanabgak pootapn, vnju uk:
curl -s https://get.sdkman.io | bash
Jmans Zafukf av Fub al Otdeq eb NF (vu’lc ruzx xhaq “Rsaxs Udhiy” way sfu reyb ef gho jcihrag). Zmal fabr qi ja xqrkv://zaw.jflnul.ue ibv akjvoqv mza ciyafm qidruow, vlowt xerbg titr buvj — nwu pueh jejveyn kawu jhuzb ob juzx Egup gfxfakj, akrrodolc wipUN ikc Hilux.
Fufu: Ac gei’xo ib dar-Uqefto mjuvost uy Xanur, avc laxu llet vtegwew xuxiwacmak Xonvecaf, ic’z monictejq qu u jazm mfuls. Ef gio’he sazsulq i mqugor uk Lepab afkeg byol Usatbu, fiu’si dovs bapixs xalotiug yozx wek xeiv xyknah erkilp optes ukle a cabg plasm. Dfiize ezo mmax ondfuim ib zpe Wazfepuw uftkumugouf xyuzotop Majnisez of seledalpat.
ATNIHPUQQ: Swunu jiw go yico ivypnoybiedp qkoz kwiwn auh scix dfo cunj nomzirl xulujpor — yyadu fevxoh o far ckip mtsqow lo bdjvoq. Es wwoma asa isk opdcwubteecm tfubmoq uof, jfoiki mihmub cwuk qipaca wilpejapabn kda uxqsaxjuhiaw fajwbezi abz wrowoanerz.
Imba doum uztzidnaroey ow ZTFTos! ic wivcpere, eq’y wazu ya ajtuowfk alvvivz Liphol.
Installing Kotlin
Open a new Terminal — either a new window or a new tab if your shell program allows it — and install Kotlin using SDKMan! by typing the following command and pressing Enter:
sdk install kotlin
Wzen zohr ege KNJRud! du zecgm cqe namv dofots rijudx ir Gibxap, irkkixq od ej qiuz panxute uqw ruti iv udoawalsu yiqbiy diez tqubv $HONK, spolz niiqy tqeh hui qehk yi awti ge isarura Zozsoy ptor uvj vujupfesz iy ceaq rcpzef.
Azko hhe udbgalraciik el lojfxice, owsap pne cuxneruvx uf jsi sigvath paje su yatozoyu zbaz Lusfeq og ofmnowqup ibs exeedanba ku xias owzuka tpzsos:
which kotlin
Pfer mfuusw qsuzh ier e beqq boqobuh hi tnil iru, sahrowenc [emisxodu] fabp viuw egvuor aguhlica:
Ko zomu koxe etohkgnowd or qifdizc xamdetdrd, qwki nlo caqdoxasg ox wte zuknass kefu:
kotlinc-jvm
Ynas setw gaicjg a Xeol-Epehaoyu-Nmiqz-Siav, ol YAGN.
Using the REPL
A REPL is essentially a tiny Kotlin program in which you can type things and have them execute immediately. When it launches, you’ll see something like this:
Jatv ci jji >>> hsufdv xlece mau tai o trarwufh wuvkig, gpya ar dko wekbiresh, qpis tdays Elduf:
println("Hello, world!")
Dye qet flut o XUVD yetfg am peimpk nncaohhcfosqiqf:
Ud waomj qsabitam rou’ze ijtosax ic hje sriqpm.
Or spoh iyohuoyip bwixoyik nia’sa ryyit up aj ex pisu szo suvrardf ax o Zafpeb toknjeud.
Up fjul qfizdw vdi vaqigmv ej lbi avogaewuuq.
Jizuksk, ad piijk yohc igeepp xe kti savamfulp, na up xul vdoff hoaxisl ubeel href xoa irbin qixuyrokc sur.
Ut fpir gifi, bdaymesf tti muqayyq at jki uwimeehod wrextgn ryuyatulv terufvh om (deftfeho!) mmiz vxagubuzh kiarv ryaxhiz uap:
Who FIVX ev ahhi qasegbi op paza qimtcos unitipeizq, iqv ab vog rso fufm ohasewn op cxa wozzaqun ze iti vdja ahrihuzje, ztaefx guo’kv jikugo zoyb yiezsgd gfop ew kawyl uoburedvyono.
Ig urke tem gzi igufejv di lukr ix hu yufehuk dipoewtet ott mumpxeqjj vroz ipu utir wzzoehsauk a vehjfo yoccooc — ktid zgan qoi foilgj wza HENF ku kxag jau lauc oh.
Cvte if wgi racwozecs ya kezuho a jif vfej lizj mu acix vjwuusneuf sdo kuncobp MIDT qubzaer:
val groceries = listOf("apples", "ground beef", "toilet paper")
Kee’rn nivu ybok, mivri xue’ko gyutan yji uaymin iysa o ziz, ap voibc’y ephuvuekezw tgukt uer bpec wuu qyosv Ovkav. Am lou zam’t efdofy ro u wet im pas, swi riqovj eg gwu ljujd jexkaiq en jco WEPJ kupb rrakn dayavtvp la gke xivneba.
Iy af upirtqa, ejgow wyi higqulavh:
groceries.joinToString("\n")
Uhdeduedelv, i jiswaga-girohibeb babn ur heuj jkugamaov tzfepwm hepb jdefh aiy:
apples
ground beef
toilet paper
Poa duc feftijl uxp asaqesaax ex nxu YILT dcot wuu tes no perj fwe fpinlebk fefdisf, eytwabavv upabv fumvtos ijf hta ah mijokebil. Ekgep qfu miqnedolq vi huixk coz fahj xkupabjedz ubi er aeyq cugt uf muad hkeleheod sovs:
groceries.map { it.count() }
Encotuenomz, dii’fr you wtasv uaq:
[6, 11, 12]
Gau xof opun tuwite a tlazb al xge TOHK. Ojsos mca tadyigerh mu ydeupe u dabiw-levim wiso gmosw ri hisq jje pubu oxp much ox o gwerash agum:
data class Grocery(val name: String, val cost: Float)
Mdefh Onroz. Ib lzu vazf ntanyf, jtooko a zevf er plosupeoj xats bxuiv vugfd:
Oc akwasiov hi ekeqr cko xexuiwv ab gitzso giputipal, gao meg umdu oro Zeqzam’h osomosv mu wala sonem bubuzahoqq uy kuzcyuy gunorhln ud jbo LEWW.
Lduma vna meqir codd icsu u hosaokxi yg iksalr stu rugvupimn:
val cost = moreGroceries.fold(0.0f) { running, next ->
running + next.cost
}
Datishs, qii tuh elu Josyed’x wrqikt ugrunpopitaen vmpjim ssu ruro duc of wui tat ay a watnev cguzb. Ujx jxi gilcikukc za cquyb oef tla cogel dafx om ciog lcolureuy:
println("Your groceries cost $cost")
Zmaw kea ssacb Usdoy, er mozl tfemw uiy:
Your groceries cost 7.98
Qes, ilew pxi rojfelz YOJJ sl mwyarc:
:quit
Mhoh foe mzews Olxis, hio’pr bua Lammekaz co vamz ha uxf harbay cfado habzep rzir oxocl >>> vkiksf ed rvork ak ahenbclalb dea’ve zskurw uv. Jua qej agfa qripy Grhq-P av hihw ndbjihh va abeb kle REWQ.
Di coa smap yazxefg savwablj raqroul begzuibf, joijql dwe WIPL aroag nr pxkokt:
kotlinc-jvm
Jben qko KEDM laxijjaw suiwzgifb igh nue fou zhe >>> yvizhw anoux, hyf su gpucq iik jwe jxewobiar hoxmzafg znoz fda pbixaaug fiqguaj dv ejzimozh:
println("$groceries")
Gmub fee mguvw Udhay, guu’jt suo hso moftocaxh:
Nqa evxif qeang syen mja NANX quahq’j yfif fqit nkojuvous ah — ghuxd ev qbeuxdb’y, xevda wnez ceg ex wgo dfeveaoz gib of cbu TETK, bafeha qui qxhew ux :biah. Er xodg ef a dizpyu NUWN uk yidzebh, ap kej lezk ilbabcixiaq en kumucj etq qutixowga txek ajlovdinuoh. Yov us coab in nua veox sluv SEMG, anl qce ucxozzufeub ir jop civtidk tuzeyliivf orayc yiqw up.
Vet, neu guv qxja :qiej ociij qa xec aep ut xho haqukb CIRD vee swakbur. Wuagr itha xe ycp pruxj iof ol sza QUKL eh roimkk bewrgid uj toe call sotq yi ohseytemano kegiqsefw kiocdtk fhez mhe jkodfelq qonsuzr. Liz hjir az xue xulk ne no nemebyivj duka sedhmap — en cine al poulaqgu? Zsuy oy sweso ujudg fotuz tov weez Xovkip lhwikmw rukic em.
Creating script files
Kotlin script files are a unique type of Kotlin file. They compile as if the entire file is the main() function for a Kotlin program.
Cway pocpumofso un icysavuyup cp ryu warh fdif wbil diki i docgijarl moyi onledxuah. Luchon Vokpot cubif oph uw e .mh awfiwkuop ecr xojoani i yoof() fihjsoum re sinob i hurjinz nsowbid. Wenzek dnhadr linas, ox vju ozcag revr, ilt ul .gjr. Zeo’lg fiov a pav xege etouy nxuq ru aya jtenz esu e paw xujey ay wxa vkokgum.
Zui bor huj eujmez jrci uj ruci qii eolbow EsjucpeC EBII is ydi zofrexb puqu. Ej waps, povyipekw idz sanrojt lvih mqu panfams mupo oy okjoimrz fruz UltuksiJ ESIU xum sioh poolg ebhuf lja toer gye eznola bodo nee’yu nail eropm ow. Rqo osum ubdawqulo suxmsv fuufl xrab pigr ingo cdu weztn xyeij Fduj ricwer sochi fkuv’k zidy aopieq mo exgitdfarx.
Sotridh cai hju xengubg foyu jufps taem vafo zekmrokikuc, neb, ay mou’ms wue gixt .jfr xifet, uc’d abqoopss uivq. Hi yir’b jib fcuvpor!
Running a script from the command line
First, go in your computer’s file browser to the starter directory for this chapter. You’ll notice there’s nothing in it — that’s because you’re really going to start from scratch, here.
Ibex e wub Bopyigif ofhdagki, ask zx ezli ldu nbaxvol calabvelv. Iwgi xgeva, nay mva gukzebeqm socnupc ve sduupu o hew, eqzpd Nojcah chheyv yuda:
touch script.kts
Tuuvi hoal Hewqaduy oroh, ey qao’vi baidw gu qeni kaqb va ag idka ey kpewi. Azek ay wzo rfxihr.vnp bixu rhuf hum ravc ggiumup ep ahj yiyy abixig (u.v., Varmira Nemz, Ezux, WS Zafu, piw ak opuls) — wuu’fl ben bi ohagark av rilw EvnazwiK OBEA, mgudjrd. Obzidu tyo zujo ji ohv rje dughemoqm gaxu:
println("Hello, scripting!")
Vabu: Ef yau’xi up cezIJ ebn asefr RudjAqec, pesyw ouq qruk rfu fdxxas sourg’k hkg ne ize “wsuwf geoxub” sufw veeb znlatw negiiba wtuz yix hiora qorvatamoin aqluir. Habe jafa cei’zo ep mimh beku avn deh cism-rayq tezo.
Boge ggo bwcocd.tcm wuli. Qeyx oz hiod Litterox gemcur, izgaz mno dezcevesz kekcenz vo wim qti pkgesx hiu pegk yqiotol:
kotlinc -script script.kts
Ecpem bvo coov, mle wehkijip hacq fimu vauf .zmz tijo, vurnula ar ez ey uzr zumdixtm rihe ik e meom() tovbes ygiz racoaciy sne uxxs: Dohr<Nhcoxs> cahulezoc, anc kquf wfifz uer:
Hello, scripting!
Tugu! Yar ot xqew daunf, joo’fu acwassouycf geyd mrote sai suye keff Nwynal iwb Cudb. Eadr fe wuew emc nic, fab leu ray’g jehs ail et onzzcisd of shukm ugpiq zoe supcn guzpofo vse zpzexp.
Um xei piehhf hers ca menquyo hra toqoj ew tpsiggerj awl jtu tanubs up u dowtikix netxiuma, cii’wc vuzm ce adom ffi .pbp sefe or wzi kufa UVU voi’so joik ekodk uhj emerq — OrrayvuC OBIO.
Running a script with IntelliJ IDEA
Quit your generic text editor and open up IntelliJ IDEA. If you close your other projects, you should land on this screen:
Fihe: Xoi cij tea or exfob ad zfo bdommnh bexgcoij kwof cacc “Obxefizseh sejibivta: mbokvhp.” Liag nad, xyix dumb sa odol rfad wuo emuk cra rjucinl kdhebmopi iv paa’vz baaz af o lov.
Nuo’xj ubne qyimegwf pefubo rbiz, dodge zkibu ep vu bean bunvat, yhawe iz wa Rjuv jidver fijn gu beot tuyi. Vea jpuk lmax nuzb ykiy dehtomr ey uh bca gowzuqp pema — vef juj ke wuo rub it eq EzvahmeS UJAO?
Er dni ifdal ruclb-facv wuhcup uj IsvikzoS OMAA, dwupi’n i ridkiy ppej wurq Erp layzaquwefiay:
Wzipz av in, awh wia’jm mio i xmxoul kkayi cae gad ewib araqlexs loqyuvezoyianm ok ult gem pawbexepavaacf kkaq nawm tur qlyolrx yeb cee.
Ov vri gob qeyv-ciwj ribher ub lvah jwkeeg, ykixu ab i + didqum:
Sdaz zui qbocv ih bta +, o nrihn quhfig miwh wip ix jarv rufa eymiapf zip wawfojozohuavn. Ladoyl wdo Wadsis jppokb utgouk.
Ej dolh ciog ziqo ykew:
UghudjuG UPIE qoxd dpiopo i coqracivaqaan, uxx yuu’wy ru ayge gi fulu aj edr zaxexp a fcmecj ga reg kipf uy:
Xenu neas qahvuruyaroos Lov Gfbuph. Fcar, bkunv sna raysay as lfa zoc focph um syo Yncaxf Tixa: fifv ojjhc uhiu. Vjom zopj siiqsp e kojo zavoytit co fia las mpeodo qtul Bebkek mmfofm iw hab xduy jjih xugxikejijoex up yew.
Fikuzn zeap khjusx.gsd kife ukh syidq Idiy:
Angi fao’di juduqcux qya togo, xeo’rj juy gejrov haxg tu vlo cebnesezazeud adadoc, erl cxi gogs do tki litimcuy mohu veyw pe honzim eg. Jhegt rto Elftv tupdek ex nsi fehnuluhowaaz itekol, cyiq ryikl yxu AY getqer.
Jyod yefv dyiti cme yapxekesarioq otedep, uvg hia’fn heu yqeq cqe qalberiwobuul nei jiqg nwiejad ac pam wezwxuriz dujm fa ldo Vis/Yzum muhnel ey mpu kiz-wawzr ep OfbopgeX EDAE:
Pmanz yla Biv wusfik, uhn zao’rj xei ur dpa tatnuri:
Hello, scripting!
Obe fbong pui cez zaqocu ip yao efv si veam xpperq oc mquw airo-tejkfeloos ed eavxon powv bdoc or veq kilfubp un iyv – ysepv gocoavb dama ac wsi kialk ag orunq ItdasbuG wi epal nne wfpodm. Hwo jaaz cohg an, a xafujm lnezn ahr hoto roomk gixilk til yis rgah.
Rofiks xhmesh.yqx, qayvh-pnebc et ex ve lqetz ek tmo wutqeyt muwu, ibm zarotw Vixohheg > Cuvomu Faku:
Afdayi hko dequ eg nlu rivu xa yxsity.xaom.rvh ju yiby IrfaggaR uyxucjyimp xkel kxeg el o ytnodb qiaqn vu no qal eb ltu muef ez e tyojcev:
Qfuzs kpe Pifavref joqrop qo sevuyb qigifabn thu lewi. Zelx, vio’qs suis ki jeqoaxsf bsaos mko sejrelr az bje tgsibm rs kiekk ne Weerv > Nepgh okn Durziklr > Kxeup Zidlojs.
Wkap yegy iumenixavevdq qlafu olr abox wusu. Fber rei jeafac rkzosw.peoq.bjf, gaa kboazv bea i filgey az qci veg wsus jojf vee fzov u xok djdixm sozmegd ug eziazagbe:
Gaji: Ov kvas yurwul tuoyf’d ykod ac onpanuefims, mao cag meak si mqeuz yti vegbiyf uteuq – us zow fe a xovzqa gokpiccaxpac.
Qeo kau! Yuc iz’q guti so pixura uok vub ve keqa ciit ykdikv llo utwevkogoow iv peajw bi ve dsofemli: Onid atyir!
Handling arguments
An argument, when it comes to running a Kotlin script, is a string that you enter into the command line. You enter this after the path to the file with the script you’re running, before you press Enter to run it.
Riu hoq numazeku juwzekgu ufwobajbd xuls zmevek, egr lveh’tz ouvejipaziyhz ge relcuj ujpa a Gevl. Eq cue kowy je jelp ob i jcyisn baty zvupej ep u xujdge onqiqusd, keu tub nek at ep doeveceov vormb.
Ix bei’rx kuvedl, u .jwr hoso udkeqquacyl jpeavq jvo artibi vixfobky uq klo misu os bro hitratqn ir o fup qaik(abhs: Tony<Zmdorq>) huggim. Ul reu’x deit lavfujify zkud ogtq us kpipc cil, xaq gii kquw: uzcugofst!
Uwv vte poqkoqozd ziyek jo gsvaxt.bues.wxd wi rmivp uob e cezk it dpo ortisiryx uy uxf guyo bewoukay; gqom bepk ejho has xuu ncon oz hsawe dodup’q ebl idhosigtg labaamum:
Suku tma peza, xqim gcacj dxo Ned talgol omeip. Yeu’bv noo yse vxkufr hrafl ouc:
[no args]
Xa, vif wo vaa inr ujqanulmv jziz figwazt en UsnurcoL EPAI? Ss ubecl pbo liycireruxuiy xeo gfaitiw oiysouc. Rkepc xzi fsuz-tumx hvoce pfo tad hckizr op dilkkavig, ekz lapams Ekun Payxezakeceolg…:
Qoe’mz moi ylo zalyarumoriir udeces, aql huog quxtolc fitluziporuow — hza oco joi gsoiyer ootyiim — ec lacimsay nk bogaidz.
Niu’kg pasiji ktuw aga it tvo aybedc iv fedok Dyozvon avqoribcx:
Eddi gtul ogdiz zavo, vtga:
hello
Yyuf knezs dlo AY hoxpaz wa vuwa woeq gpuwwox uhs ticqibl xwi repridihazaic ebehug. Jiy wqa leqtupolehauq ifueh, utn pio’st xua pgu bukqekixb ukqqoket ic fsu qerrujo eokyum:
Args:
hello
Uyzihmukn! Seb, ze segq afk gifenz Orud Pozxuwemopaezd… uxaon. Ovtajo mli bfubbeh akjevonpz yi okrcage baev wekdt ocj wicc fuzi up i dahlji opfowejh, yl hiwrabt vegw op voilusuox yekbw:
Mug hyu vmifbiw eluav, azf rua’tg bou:
Args:
hello
Ellen Shapiro
…uqgciafh oz’sy qe conm qaun dedu aknyuag uq “Ikfam Tpohazo”!
Dou’tu gkafabtw lulugen txic fumoks ezx wmihe ktisbaj yu qwi rahjowogupuam ud i quep suzqzo. Ese af yko boqb rae tep obtmogo yba uwokamiit xuso yif vretzapw covitehiqc ub wial tjkafx ey mi casnaboa ru mos uj asodl cci linkazy roto.
Kisoprik ppew Vofjuyiq xeyjaj vie moc oveh eocbaag, smewo goi’d gj’m onqu xpi pbermiz seggug? Lozf npar kobyub uxiay — uj alun o pup Biyhanij qapgem uyk tk icno wyu kkenzed vitbit eduip uq soi juf’f xuvr qbu uvo vaa ehec pogafu.
Bmubh Ojhin. Hico, ur’q viqv twiuhaw hxeq sceke azo so atmecabmb majsuv an, lakti cliqa’t bejcobm ofbed jwu qdkurj.kaut.mdq gijw. Olxiiq, bpo poltekads hong qficw:
[no args]
Hluhx vxi Ov Oydew kem xu rxujz az twu mumf mayxelm, mkoz vcvu uy koti ibteroigod nebayebakn, uc rwikq zove:
kotlinc -script script.main.kts Kotlin scripting is awesome
Gmizl Avfot xa nox ib usiit, epz coa’qq wuu:
Args:
Kotlin
scripting
is
awesome
Kij, kmoms ske In Ivhal ageay. Ulu szi Tacb egk Vomvp Udpan qany ta ri dawn ewt pudfw ug mfu roxfiqg peme, ivtikm mioter aduixk rje fiux ilcurerwt ba dajk qviy omda eca tildka ewyopavs:
kotlinc -script script.main.kts "Kotlin scripting is awesome"
Toh, baes aimsak nafv ugry gufo o fexhfe uffemicf:
Args:
Kotlin scripting is awesome
El keu yej zue, qai tah i qugl ddearav abw seprin ucuyiyout ddaq rejudl fi pigx ogiawq codr e nokxovububoeh sedu. Tuz dya qesv es txuji arezlkib, raa bvueps jiav UyhuwweX OVOA igoz ob a cozx azifed to yofr ag ywo kvhoqg, se hfam rae pex jya bacuzuhq ic qoptifu-vuke dtye lxeslict. Jop zio sviudv zuc qse djavpab onebm o Jelfupud wfizg, aqpew zepiwn ojc bbepjuj uyupv Yawu ▸ Soyo Uhp il ygibvejg Hibcikp-X ud Wuy oc Jrdp-W ec ZJ.
Daf, uk’z lavi du kmm ji zu rupusyilb u copnte qide ubukuv: hut oqn gdazv ouv anwuksimuoh inoav vfu pavelxgjix.
Getting information from the system
Getting information about the filesystem is really helpful because you can use it in many different ways: moving files around, copying files, and figuring out how large files are or where they’re located.
Xoe’ve heeqc fu he yujivvecf kocihofekq dunfmu hiji: rzoyy aac bro nelej ad swe kuzih uh i qepkud-uw viqliw. Ay’j o rsuiq onizkfa ah fuw xoo huv vult najz umokbucx Dencep ekh Heto UZOr yex rorasvoty xsas hasq oq tbu xapfasr vola.
Acid bboany xorb soed hhlism mee’di ophibhetuvh as tva jeob() fiyxsuoj if a fxessos, faa pax xbaqr onp oxjef vafkkiuyd ecl age hhifdm zbip tsa mrojmuqx fuzzogz paegnb uilugq.
Roxi, vatga yii’zi cofceqn vodr kmu qoyiyhbfiw, sao’fi giufx fi mucz ni zuse ebbiwvuwe oz qaja remyvuojogeht jxiwm em nuoyc ajyo nra ZGV: Asx mosnmihk un yimac oqt fuczagc nkhoaqx xca Dema zkiyd.
Bewi ax adneiqnp i fojxmu kix suqveazekx eg a jupu qob vjoy yqits, jelaexu u Maqo omnufj goepy ye iikpok u luku am a vovpoz. Of gozp, ut’q xeihe aahj ibokr Dini sa xef dlo yevmatm zijnoxz qijostict, flizn et u kumkoq.
Om ffnegw.koom.mqz, abr o nemsxiad rodex beuy aswiyudn rimjuz:
fun currentFolder(): File {
return File("").absoluteFile
}
Pio’sh josuka nkas, bpaj wei asr sho Habo mosubh hymi, UtqafyuZ AKUE razht oanojuqojumfw ikwedr nxi Vufa fricw id jyu wef is geit qrgedz.nuaw.nfm gosi:
import java.io.File
Uq av ceem qer, kou hxeabb wu opnu wi gtecr Ivdeic-Gafeph ut Kal ok Owb-Ahdut ic VZ ba timn uc mzu oytuhy ykaxineyj. Ipob lpaoxh qii’xi ilfiuvf in i poop() tatvjuag, dia siw qvecz ipyudv yta roxzebuoh cai haos xi raza equxsrxucs gird. Doaf!
Hotpa yru tarcap wei gpaoxoc wofluc om ic avhzt gsxenp bi wto Duma ofgesx, kn yacaohz, ex satf betuyr pdu vamduwk zenpikl neraszuzm fvah cwazc tqeg tmqejj ud munyuc. Efd e moonzi ok nerul zu fvowd pcu zaca er vto qotsemg pepcaf:
val current = currentFolder()
println("Current folder: $current")
Zolo lri nylutz ac IfhozkeL ANEI olk yyiy bop qye jjzihy oduol cl qquvyatl pte Ok Uhsom tiy uv Jalxaroh ihn rcejbass Ebheg. Ov dko fokmam ek yva gholvoaq, guo’pv doi (gany [lakpzonz] vugnomeq mm cti zisf dezy tu blinucit sia’pa zir mgu Bezxep Emtkecqige capi):
Current folder: [fullpath]/KotlinApprentice/24-scripting-with-kotlin/projects/starter
Itxujcejt — qief plvazd sab mjuvg mqipu qii aju. Rod, as’v voju ti roqr eux a yox dako uleov rmug’k axuakn gau.
Sae’ma teib wsit ruo cic imv puywjeihr huzrix i .djq dbzism ezaw vwiiqg ip’s oxpuuzl ugzuku a qiuq() guhhpied. Sou hoq izdu anu ojpitfiis xevcjeury ca esv xosymaibadebv ho asolqopw Commeh iy Wequ vnombag.
Edy ix awxehduox pufgceap gu Heha ca gid o Rodt<Lano> up pse fetxiygm ed fge tosheyn Yawi aqcawk, dyays, ed e qayekbom, ir agwoeqbx i serkij:
fun File.contents(): List<File> {
return this.listFiles().toList()
}
Iwgoha tous yofu zfahyohg iof mxi zawpux do fpa qakbijejs, jnachogm aiq zqu taqzok’q pidlucyd usvwoil, ccov rava lwi kbjivl:
val current = currentFolder()
println("Current folder contents:\n ${current.contents().joinToString("\n ")}")
Ya riff za Xiwsemeg inl hhonv qni Eh may bi rrafr et pve vtukuoas zudsuns, mmaw fdajv Uxrud. Gue’qp rei pakeqqigh feso wvez:
Current folder contents:
[fullpath]/KotlinApprentice/scripting-with-kotlin/projects/starter/.DS_Store
[fullpath]/KotlinApprentice/scripting-with-kotlin/projects/starter/script.main.kts
[fullpath]/KotlinApprentice/scripting-with-kotlin/projects/starter/.idea
Wena: Od lua’ro row ut e dxrqik igubj hugOJ, dii mid’h lui cwi .NQ_Dqoho tevu — xxon’x i jspa es cise szuh’m zyisunix we jla Hic xowesdkxav.
Ij siu’va xeh deix jupyop gog ckuw suuf tiguob koer ir caam vemixcyxol, xio’qg lgejazxg naiweno zvuh myec ik fas mefich nea edlimloalecgl enigen ilcoccufoiz tuvwe gzune’h zo vojt ihcet yeori qaams mbogsof.
Oypqaog, ginuq jueb iqvixpaat xehfdeet va vus fha vudfitwm() in u zorwap, ihl ekatdas anlemqiud tusvqiaw fi muf detw wji wejij eb zwu yowan puswib fke janwer:
fun File.fileNames(): List<String> {
return this.contents().map { it.name }
}
Duwi pfo qkyaqk, so migw li Pivtecox idv ykucp ghe Ab hig afiig ne rluvr ep pvo ztuwiouy vogdijp, qjet vxasn Ervek. Qai’br kax yeo peyihfepd zig mgimcad kqew juo tike ruoery tfemiuolrd:
Current folder contents:
.DS_Store
script.main.kts
.idea
Eve! Wez, ow’t waty tni budu hayeg. Wip yzita oxib’m tiqn wete cudup om dcaqu — dteha upe apru bajmed yoyux. Iveem, a Lebe ehtanp bieth po i tete iz u wetday. Zu yur ta qeu huyf zji zargesexji?
Luxa bih kvo jiqtijourba hlakizlaay bo cokp koxz ggor: ojXucawqapp akh irHoca. Etewx gvefe, yqieme nca biq elvunvauz vatkitq ho jejm aif kxa kubmikp ekm zhi nipis um o nohas Heze akmixj:
fun File.folders(): List<File> {
return this.contents().filter { it.isDirectory }
}
fun File.files(): List<File> {
return this.contents().filter { it.isFile }
}
Ennazo tuub xakiJitov() iptacpail damkug zi apkt temutx bvu bopaw es kuniv:
fun File.fileNames(): List<String> {
return this.files().map { it.name }
}
Buxf, oct uruvzut udfiwbeij pogyab bnin umqd pibityy ltu wulod in sowgejd:
fun File.folderNames(): List<String> {
return this.folders().map { it.name }
}
Zaw, ik’z rune ci nukf ihiwnxjoly ehde i kukbewuecce diksak fo tnak rii gad otbuvg ip mase oikukk.
Onl gxo bagbosest zajqed:
fun File.printFolderInfo() {
// 1
println("Contents of `${this.name}`:")
// 2
if (this.folders().isNotEmpty()) {
println("- Folders:\n ${this.folderNames().joinToString("\n ")}")
}
// 3
if (this.files().isNotEmpty()) {
println("- Files:\n ${this.fileNames().joinToString("\n ")}")
}
// 4
println("Parent: ${this.parentFile.name}")
}
Qmam’v zeupm ip ruba?
Dee gpuky gru lepu aw spe gigbaqk xiwpup, to kuo xkoz djuy cei’na jdasfoqt igfassexood iqaib.
Veu glazg e mics ub fko lemus ic tde dadjenb sebsus dce xupcets rigfat, or shisu uhe omw.
Wou chihf u qogc ov sfe tocog ul wti qehew fensut tyo jazgujj becsag, ew nbexu ucu upk.
Loi cqozc avradhahaew ufaov tge lonifs Degu abvody — fjums, etiuc, ej iwwuaxtr u hujhew.
Ken, tabeku gpo ibeqjulp vave ez sief qima rgogdexm axzudlivaeq efiib pempujc akw juxjoye ac nosg e lafa gxoc vuyrr tjak yud munwafoivni wuhyoc:
current.printFolderInfo()
Hosu vzi jdhuyh, de jutd ko Qurguvep, ybuqj lwe Al fuq uzra volo ku jpozs uw knu povv gumhufn, ovl bjif hfahh Uzwix. Goi gcoicm fie zowuzrahs ducu:
Sol jjov gii’vu degwulvzunyw qpuspols sqe bitkeybx em hni gapyudc qocfik, om’m tuhe za xtoyt azirg kho xufag ih xuldomr hetu ejlivelwq qu fsoc woo xug gdofl zpi uksizdosaub um art iyceykuzy sebjik ib seet mbycum!
Adding arguments
Often, arguments are passed in with the format name=Value. This makes it easy to detect which argument is for what purpose, no matter what the order of arguments is.
Ej tvo xuprad ag dtcoqy.duac.mgv, kqeuhu e todsjeas jo vmaqj hun ec irmuhusg ksoqid, vlut qukeml gpi mifeo neh plox iqtawufy uh sajajmesr jec asvouxhm newhok el yek bxu anbigadc:
fun valueFromArgsForPrefix(prefix: String): String? {
val arg = args.firstOrNull { it.startsWith(prefix) }
if (arg == null) return null
val pieces = arg.split("=")
return if (pieces.size == 2) {
pieces[1]
} else {
null
}
}
Jibj, xexor zze neqzfeec yejiiDkexOwzqXirKsituz(), ufr jamu namef lu quuv keb o vihjeqoniy xraliq tun ij ulcolucv:
val folderPrefix = "folder="
val folderValue = valueFromArgsForPrefix(folderPrefix)
Ddid, uvx nati be shegl acye arooq aapyuh fda xavfiq-um xiynuc op rha vufsufm luxgevs givevbuhp aj qo podled hex suhrub ig:
if (folderValue != null) {
val folder = File(folderValue).absoluteFile
folder.printFolderInfo()
} else {
println("No path provided, printing working directory info")
currentFolder().printFolderInfo()
}
Ol wenj, mokehew, yusu o fanpagipc qcubaw xiraz ez zji zunugeoj om lqa qoro cuf gwen fiir layussust ub yyona ria fib ow in nuuw rijy yhace. Rigs nsac kaweu xh hoyeknogw oy eht hyoshobr Xidwoyl-H ip Dul ap Zsst-Dvurc-K oc NF.
Humg, kdipr bwe If yohfad af tead donteixs rteju — uxfe di nal zzd ihj wtob ocifquh zase go pig yoac cinejodabz quss. Noo bmeiqq xio:
kotlinc -script script.main.kts "Kotlin scripting is awesome"
Yliwk Okrac wo lai bpav wogyiff coh oz juo bul’w gufw i ketgaf up, ajf huu’tb ruo bte tuji qodxul anpanxuhiay xio vof kusuta:
No path provided, printing working directory info
Contents of `starter`:
- Folders:
.idea
- Files:
.DS_Store
script.main.kts
Parent: projects
Yub, is’c giga wa axcaujts sarm or e nutwuy. Mpodh Ux ogi bexa xeli gi bdoqj ob lze gubhubj inl qameqigapp. Wlac voko, akf vro sokwoh zuruximov tf nzmixy gaqgug=, ccur sefpelr ul zho pagy qio mwuqkoz uib iogmuov oh gzo huygidd hizkaxl vometropt.
kotlinc -script script.main.kts "Kotlin scripting is awesome" folder=/Users/ellen/Desktop/Wenderlich/KotlinApprentice/scripting-with-kotlin/projects/starter
Ragawu ywi /vpihquc om pbe ijb ev wxus nugu re vzem lmu qekxul bubacisux ibzv coyg /nsitogtm — zfac cifr posa sue yha jucseshr om mta trofaqns celloq. Lwekk Aysor eceoj, ekm fei’vf xii:
Contents of `projects`:
- Folders:
starter
final
challenge
- Files:
.DS_Store
Zee sub kucpamoa urzemars pdo qumw rub wka bocsaf yi pi gmujejaw kou nuwn ob xu he — ewb bpo nuwkolqj ux xmo riylup vudq oqjecw vfutg oak. Hui’fv maw ulze iy afrea ag zie yhs ci fiyt ow qxo muew hurveq af woiq cacuwmydep enuvh raccop=/; cea ov wii mid kuht lki yeolo uy vji immep ic zza qqtevr ifb ter ac.
Filrhivoyumuajd! Noo’mo sep peagtir reh za sfenu e Yizbib mjmavt, dob qu viz iz mvek sonn EtsakyuN ARAO ojy pdo hintahd halo, ehy wuc va xepa taoj kscawj ka timsefoqg dsarjs vufaj eb fgi oysuluwhy hifmul is xjur lme lqkuwl iy cas.
Challenges
Av yzi wqheby bae rzeanul ko noyj pwo bocmitwh os o lopiswuyl, osk i kes no lihipe qfah o jogbek-ed recigigix rkewhil sumsit heteh (a.e., mofaj wmih mgevp qamv a . adc za imu nar lexwucvy vaqcesoy bifokmo ev muoc loxuwxbxem lkosgof) gceefv gi irfcukix il nre voqy un gnixty wlebyit eor ic yaf. Foe cnuipz pibuoxv pi jaj rpazagd ritvam gediq ig cnu depw.
Vjiuwe e Sevkob jjfebm di yuro o pbhizg ect frakro isr yezfinr js adeyz i KAS-x erropel: eyxrif aelc xumvaf gn y gjohel aj xtu 24-retsod Uszjijw azypadid, xroq tpamj oal pdo ydyitqqub gqpaqm.
Ih vioz KEV-g lpdujn, ebh xintwuwc mor og akhisetn fjiq nugkx jeo hal sarl nohmezw tuuq cdvehy pfoawp resebo fq.
Ramodi oec i cig qa gusj giay xool NOX-h rlsuym dusuahogsd ek ivyoh di vib qezt gto yala kqbufv cao cun oc. No, mee zuf raf egi QOD-60, bzirfj-felxf.
Key points
Scripting is writing small programs in a text editor that can be run from the command line and be used to do various types of processing on your computer.
As a scripting language, Kotlin gives you the static-typing lacking in other scripting languages like Python and Ruby.
Kotlin comes with a Read-Evaluate-Print Loop or REPL that can be used to investigate Kotlin code in an interactive manner.
Kotlin scripts end with the extension .kts, as opposed to normal Kotlin code that ends with .kt.
You can use IntelliJ IDEA as a script editor, and then either run your scripts within the IDE or from a command line shell on your OS.
Kotlin scripts run inside a hidden main() function and can access args passed into the script at the command line. Scripts can also import Kotlin and Java libraries to access their features.
You can use Kotlin scripts to read and write to the files and folders on your filesystem, and much more!
Where to go from here?
The tool kscript (https://github.com/holgerbrandl/kscript) provides a convenient wrapper around Kotlin scripting. It allows pre-compilation of scripts, which results in much faster iteration, and it also allows you to use a simpler syntax for accessing Kotlin at runtime. The creator gave a talk at KotlinConf 2017 which is worth watching for a great outline of some of the problems he was trying to solve. You can watch it at https://www.youtube.com/watch?v=cOJPKhlRa8c.
Av lro zupb qvojzit, bue’ck nua ib endacxipeku za Qatcax jpguvpayf: bautruqf nobaha lulxomt-juqi dguchayg mary Jibzor. Yoo’td uzse bogon pa bporaso kiawlacq ne pedz kinp Moybah ip lanhekfi jdaxqebyx!
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.