Kotlin scripting allows developers to write and execute scripts to automate tasks, perform quick computations, and more. This article will explore the essentials of Kotlin scripting, including writing and executing scripts, using them for automation, and best practices for scripting.

1. Introduction to Kotlin Scripting

Kotlin scripting offers a way to write short and concise scripts without the need for a full application structure. It’s particularly useful for tasks such as automation, quick data processing, and prototyping. Kotlin scripts are typically written with the .kts extension.

1.1 Benefits of Kotlin Scripting

Conciseness: Kotlin’s concise syntax makes scripts easier to write and read.

Kotlin’s concise syntax makes scripts easier to write and read. Interoperability: Kotlin can use existing Java libraries, making it powerful for various tasks.

Kotlin can use existing Java libraries, making it powerful for various tasks. Tooling Support: Kotlin scripts can be edited and executed in environments like IntelliJ IDEA, which provides excellent tooling support.

1.2 Getting Started with Kotlin Scripting

To get started with Kotlin scripting, you need to have Kotlin installed on your machine. You can use the Kotlin command-line tools or an Integrated Development Environment (IDE) like IntelliJ IDEA.

Example: Hello World Script

Kotlin println ( "Hello, World!" )

Executing the Script

Save the above code in a file named hello.kts and run it using the Kotlin command-line tool:

Kotlin kotlinc - script hello.kts

Output

Kotlin Hello, World !

2. Writing and Executing Kotlin Scripts

2.1 Basic Syntax and Structure

Kotlin scripts are written in a similar manner to Kotlin code files but do not require the enclosing fun main() function or class definitions. This allows for more direct and imperative code execution.

Example: Variable Declaration and Function

Kotlin val greeting = "Hello" fun greet (name: String ) = " $greeting , $name !" println ( greet ( "Kotlin" ))

Executing the Script

Save the above code in a file named greet.kts and run it using the Kotlin command-line tool:

Kotlin kotlinc - script greet.kts

Output

Kotlin Hello, Kotlin !

2.2 Using Libraries in Scripts

Kotlin scripts can utilize any Java or Kotlin library by specifying the dependencies. This can be done using the @file:DependsOn annotation.

Example: Using an External Library

Add Dependency

First, add the dependency to your script:

Kotlin @file : DependsOn (" com.github.kittinunf.fuel : fuel : 2.3.1 ") import com.github.kittinunf.fuel.httpGet import com.github.kittinunf.result.Result val url = "https://jsonplaceholder.typicode.com/posts/1" val (_, _, result) = url. httpGet (). responseString () when (result) { is Result.Failure -> { val ex = result. getException () println (ex) } is Result.Success -> { val data = result. get () println ( data ) } }

Executing the Script

Save the above code in a file named fetch.kts and run it using the Kotlin command-line tool:

Kotlin kotlinc - script fetch.kts

Output

Kotlin { "userId" : 1 , "id" : 1 , "title" : "sunt aut facere repellat provident occaecati excepturi optio reprehenderit" , "body" : "quia et suscipit..." }

3. Scripting for Automation Tasks

3.1 Automating File Operations

Kotlin scripts can automate file operations such as reading, writing, and processing files.

Example: File Processing Script

Kotlin import java.io.File val inputFile = File ( "input.txt" ) val outputFile = File ( "output.txt" ) val content = inputFile. readText () val processedContent = content. toUpperCase () outputFile. writeText (processedContent) println ( "File processing complete. Check 'output.txt'." )

Executing the Script

Save the above code in a file named fileProcessing.kts and run it using the Kotlin command-line tool:

Kotlin kotlinc - script fileProcessing.kts

Output

Kotlin File processing complete. Check 'output.txt' .

3.2 Scheduling Tasks

Kotlin scripts can be used with task schedulers (like cron jobs on Unix systems) to perform regular tasks.

Example: Backup Script

Kotlin import java.nio.file. * import java.time.LocalDateTime val sourceDir = Paths. get ( "sourceDir" ) val backupDir = Paths. get ( "backupDir" , LocalDateTime. now (). toString ()) Files. createDirectories (backupDir) Files. walk (sourceDir). forEach { path -> val targetPath = backupDir. resolve (sourceDir. relativize (path)) if (Files. isDirectory (path)) { Files. createDirectories (targetPath) } else { Files. copy (path, targetPath, StandardCopyOption.REPLACE_EXISTING) } } println ( "Backup completed to $backupDir " )

Executing the Script

Save the above code in a file named backup.kts and run it using the Kotlin command-line tool:

Kotlin kotlinc - script backup.kts

Output

Kotlin Backup completed to backupDir / 2023 - 05 - 18T20: 35 : 48 . 076

4. Scripting Best Practices

4.1 Keep Scripts Simple and Focused

Single Responsibility: Each script should perform a single task or a related group of tasks.

Each script should perform a single task or a related group of tasks. Readability: Write clean and readable code. Use comments and meaningful variable names.

4.2 Error Handling and Logging

Handle Exceptions: Ensure that scripts handle potential exceptions gracefully.

Ensure that scripts handle potential exceptions gracefully. Logging: Use logging to keep track of script execution and errors.

Example: Error Handling and Logging

Kotlin import java.io.File import java.util.logging.Logger val logger = Logger. getLogger ( "ScriptLogger" ) try { val file = File ( "nonexistent.txt" ) val content = file. readText () println (content) } catch (e: Exception ) { logger. severe ( "Error reading file: ${ e.message } " ) }

Executing the Script

Save the above code in a file named errorHandling.kts and run it using the Kotlin command-line tool:

Kotlin kotlinc - script errorHandling.kts

Output

Kotlin SEVERE: Error reading file : nonexistent . txt (No such file or directory)

4.3 Modularize Scripts

Reusable Functions: Break down scripts into reusable functions.

Break down scripts into reusable functions. Script Libraries: Create libraries of common functions and utilities.

Example: Modular Script

Utility Script ( utils.kts )

Kotlin fun greet (name: String ) = "Hello, $name !"

Main Script

Kotlin @file : Import (" utils.kts ") println ( greet ( "Kotlin" ))

Executing the Script

Save the utility script in a file named utils.kts and the main script in a file named main.kts . Then run the main script using the Kotlin command-line tool:

Kotlin kotlinc - script main.kts

Output

Kotlin Hello, Kotlin !

1. Monitoring Disk Usage

This script checks the disk usage of a specified directory and prints a warning if it exceeds a certain threshold.

Script: DiskUsageMonitor.kts

Kotlin import java.io.File val directory = File ( "/home/avishik/tutcoach.com/monitor" ) val threshold = 80 // percentage fun getDiskUsagePercentage (directory: File ): Int { val totalSpace = directory.totalSpace val freeSpace = directory.freeSpace val usedSpace = totalSpace - freeSpace return (usedSpace. toDouble () / totalSpace * 100 ). toInt () } val usage = getDiskUsagePercentage (directory) println ( "Disk usage for ${ directory.path } : $usage %" ) if (usage > threshold) { println ( "Warning: Disk usage exceeds $threshold %" ) }

Expected Output

Assuming the disk usage is 85%:

Kotlin Disk usage for / home / avishik / tutcoach.com / monitor: 85 % Warning: Disk usage exceeds 80 %

2. System Uptime Check

This script checks the system uptime and prints it.

Script: SystemUptime.kts

Kotlin import java.io.File fun getSystemUptime (): Long { val uptimeFile = File ( "/proc/uptime" ) val uptimeSeconds = uptimeFile. readText (). split ( " " )[ 0 ]. toDouble () return uptimeSeconds. toLong () } val uptime = getSystemUptime () println ( "System uptime: $uptime seconds" )

Expected Output

Assuming the system has been up for 123456 seconds:

Kotlin System uptime: 123456 seconds

3. File Cleanup Script

This script deletes files older than a certain number of days in a specified directory.

Script: FileCleanup.kts

Kotlin import java.io.File import java.time.Instant import java.time.temporal.ChronoUnit val directory = File ( "/path/to/cleanup" ) val daysOld = 30L fun deleteOldFiles (directory: File , daysOld: Long ) { val threshold = Instant. now (). minus (daysOld, ChronoUnit.DAYS). toEpochMilli () directory. listFiles ()?. forEach { file -> if (file.isFile && file. lastModified () < threshold) { if (file. delete ()) { println ( "Deleted: ${ file.path } " ) } else { println ( "Failed to delete: ${ file.path } " ) } } } } deleteOldFiles (directory, daysOld)

Expected Output

Assuming there are two old files, oldfile1.txt and oldfile2.txt , and they are successfully deleted:

Kotlin Deleted: / path / to / cleanup / oldfile1.txt Deleted: / path / to / cleanup / oldfile2.txt

4. Automated Backup Script

This script backs up a specified directory to a backup location.

Script: BackupScript.kts

Kotlin import java.nio.file. * import java.time.LocalDateTime val sourceDir = Paths. get ( "/home/avishik/tutcoach.com/demo" ) val backupDir = Paths. get ( "/home/avishik/tutcoach.com/dest" , LocalDateTime. now (). toString ()) fun backupDirectory (source: Path , destination: Path ) { Files. createDirectories (destination) Files. walk (source). forEach { path -> val targetPath = destination. resolve (source. relativize (path)) if (Files. isDirectory (path)) { Files. createDirectories (targetPath) } else { Files. copy (path, targetPath, StandardCopyOption.REPLACE_EXISTING) } } println ( "Backup completed to $destination " ) } backupDirectory (sourceDir, backupDir)

Expected Output

Assuming the backup is completed successfully to a directory named after the current date and time:

Kotlin Backup completed to / home / avishik / tutcoach.com / dest / 2024 - 05 - 21T15: 30 : 45 . 678

5. User Management Script

This script lists all users on the system and checks if a specified user exists.

Script: UserManagement.kts

Kotlin import java.io.File val passwdFile = File ( "/etc/passwd" ) val targetUser = "username" fun listUsers (passwdFile: File ): List < String > { return passwdFile. readLines (). map { it. split ( ":" )[ 0 ] } } fun checkUserExists (users: List < String >, targetUser: String ): Boolean { return users. contains (targetUser) } val users = listUsers (passwdFile) println ( "All users: $users " ) if ( checkUserExists (users, targetUser)) { println ( "User ' $targetUser ' exists." ) } else { println ( "User ' $targetUser ' does not exist." ) }

Expected Output

Assuming the target user username exists and the system has the following users: root , admin , username :

Kotlin All users: [root, admin, username] User 'username' exists.

These scripts and their outputs demonstrate how Kotlin can be effectively used for system administration tasks. Each script performs a specific function, providing useful outputs that help in

Conclusion

Kotlin scripting is a powerful tool for automating tasks, performing quick computations, and prototyping. With its concise syntax and interoperability with Java libraries, Kotlin provides an efficient way to write and execute scripts. By following best practices such as keeping scripts simple, handling errors, and modularizing code, developers can create robust and maintainable scripts for various automation tasks.