Creating a command-line application

Swift is useful in creating not only Mobile applications or Mac OSX GUI applications it can be used to also create a commandline application which is run on the Terminal. Let’s start with the simplest/minimalist application. There is an commandline utility called yes. If you write and use bash scripts, then you could have come across and/or have used this utility. If not, all this utility does is stream a series of y to the terminal.

The Original Source Code

If you look at the source of the yes command it is quite simple all it does is puts("y") in an endless loop.

#include 
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1987, 1993\n\
	The Regents of the University of California.  All rights reserved.\n");
#endif /* not lint */

#ifndef lint
#if 0
static char sccsid[] = "@(#)yes.c	8.1 (Berkeley) 6/6/93";
#endif
__RCSID("$NetBSD: yes.c,v 1.5 1997/10/19 14:28:27 mrg Exp $");
#endif /* not lint */

#include 

int main __P((int, char **));

int
main(argc, argv)
	int argc;
	char **argv;
{
	if (argc > 1)
		for(;;)
			(void)puts(argv[1]);
	else for (;;)
		(void)puts("y");
}

Source: https://opensource.apple.com/source/shell_cmds/shell_cmds-203/yes/yes.c.auto.html

Recreating this in Swift

We shall re-create this in the simplest form, i.e. with the minimalist amount of code.

private func main(arguments: [String]) {
    let response:String
    if arguments.count > 1 {
        response = arguments[1]
    } else {
        response = "y"
    }

    while true {
        puts(response)
    }
}

Getting the Arguments

When you run code at the terminal, an array of parameters are passed to the utility, the first being the name of the application, followed by the arguments separated by spaces.
so if you were to run command one two, then the arguments array would look like

[0] = "command"
[1] = "one"
[2] = "two"

Getting the CommandLine arguments

Swift4 now has an easier way to access the arguments from the commandLine using the code as

let arguments = CommandLine.arguments

and now we can pass this to the main function as

main(arguments: arguments)

Recapping the entire code

import Foundation

func main(arguments: [String] ) {
    let characters: String
    
    if arguments.count > 1 {
        characters = arguments[1]
    } else {
        characters = "y"
    }
    
    while true {
        puts(characters)
    }
}

let arguments = CommandLine.arguments

main(arguments: arguments)

some concerns

In the terminal, if you find the yes utility and look at the size of the same, it is about 17760 bytes in size.If you were to compile the Swift code, the resulting file is about 10MB (Debug Mode) and approximately 6.6 MB for the release version.

You can also run this as a swift bash script file, all you need to do is add a script handler on the firstline of the script and save it. So, the script would look something like,

#!/usr/bin/swift

import Foundation

func main(arguments: [String] ) {
    let characters: String
    
    if arguments.count > 1 {
        characters = arguments[1]
    } else {
        characters = "y"
    }
    
    while true {
        puts(characters)
    }
}

let arguments = CommandLine.arguments

main(arguments: arguments)

Next you need to change the permissions for the script file by making them executable, by running the command on the terminal in the same directory as the script file.

  chmod +x script.swift

and then you can simply call it like you would a compiled utility. The size of the script is approximately 333 bytes given that you have the swift runtime present on your computer. This will also run on a Linux box or even a Windows box if you have installed Swift. Where as the compiled files are platform specific.

Views All Time
Views All Time
914
Views Today
Views Today
2
Posted in Article, Tutorial.