Swift脚本编程

(文章转载自:http://www.tuwenzhai.com/d/38f5bcac-6b60-4cd2-bd02-3ee36ee20265/3b070eb0-a1e0-4215-8967-608f33adc6b1

10.6 Swift脚本编程

 

10.6 Swift脚本编程

如果你在Terminal应用程序中使用过命令行工具,就与shell交互过。实际上,你在第1章执行命令来启动REPL时,使用的就是Bash shell。在Mac中可运行多个shell,但Bash是最常用的。

shell脚本是包含一系列使用shell语言编写的可执行代码行的文件。你可以不在shell提示符下输入大量代码行,而在shell脚本文件中输入它们,再像执行命令一样调用该文件名。很多开发人员都熟悉命令行,对他们来说,shell脚本很有用,可用来反复执行包含众多代码行的任务。

shell脚本虽然很有用,但要使用它们,你必须学习并掌握另一门语言,这样才能充分发挥它们的作用。另外,有些shell脚本是使用C shell或KornShell等其他shell语言编写的,要理解这样的shell脚本可能比较困难。

前面讨论shell脚本旨在引出这样一个事实,那就是在shell脚本中可运行Swift代码!考虑到Swift也是一种编译型语言,这可了不得,这充分说明了这门语言的强大功能和灵活性。如果你使用过C、C++或Objective-C,就能明白倘若能够在shell脚本中使用这些语言,那该有多方便。

编写shell脚本包括多个步骤。

  • 使用编辑器创建脚本。

  • 设置脚本的权限,使其能够执行。

  • 执行脚本。

10.6.1 编辑脚本

Xcode是个很好的编辑器,为何不使用它来创建shell脚本呢?

选择菜单File > New > File,在左边的OS X下选择Other,再在右边选择Shell Script,如图10-12所示。

图 10-12 在Xcode中创建shell脚本

单击Next按钮。在文件保存对话框中,将文件命名为SwiftScript,并将其保存到桌面(Xcode自动给shell脚本文件名添加扩展名.shto)。将出现一个窗口,你可在其中编辑脚本。

Xcode在这个文件开头自动添加了几行代码,其中最重要的是第一行:

  1. #!/bin/sh

这被称为hash bang语法,指定了要用来运行后续代码行的shell在文件系统中的完整路径。这里指定的是/bin/sh(Bash shell)。进行Swift脚本编程时,需要移除这行代码。事实上,请删除所有这些代码行,并输入如下代码行:

  1. #!/usr/bin/env xcrun swift
  2. import Foundation
  3. class Execution {
  4. class func execute(#path: String, arguments: [String]? = nil) -> Int {
  5. let task = NSTask()
  6. task.launchPath = path
  7. if arguments != nil {
  8. task.arguments = arguments!
  9. }
  10. task.launch()
  11. task.waitUntilExit()
  12. return Int(task.terminationStatus)
  13. }
  14. }
  15. var status : Int = 0
  16. status = Execution.execute(path: "/bin/ls")
  17. println("Status = \(status)")
  18. status = Execution.execute(path: "/bin/ls", arguments: ["/"])
  19. println("Status = \(status)")

稍后将详细介绍该脚本。现在,只管在Xcode编辑器中输入这些代码行,再选择菜单File > Save保存文件。

10.6.2 设置权限

脚本是从命令行运行的,因此请启动应用程序Terminal(你在第1章这样做过)。Terminal启动并显示shell提示符后,执行下面的命令:

  1. cd ~/Desktop
  2. chmod +x SwiftScript.sh

第一行将当前目录改为文件夹Desktop(你的脚本存储在这里)。第二行只需执行一次,它设置脚本文件的权限,使其能够被shell执行。

现在可以运行脚本了。

10.6.3 运行脚本

运行脚本很容易,只需指定脚本的名称,并在它前面加上一些额外内容:

  1. ./SwiftScript.sh

./告诉shell,该脚本位于当前目录中。必须显式地指出这一点,否则shell会找不到脚本。

该脚本运行时,你将看到文件夹Desktop和磁盘根文件夹的文件清单。你还将看到消息Status = 0,它指出用于显示文件的命令运行正常,没有出现问题。

执行这个脚本后,下面更详细地研究一下它都做了什么。

10.6.4 工作原理

第1行是前面说过的hash bang,这里指定的应用程序路径为/usr/bin/env,它是一个为shell脚本设置环境的特殊命令。路径后面是一个你应该很熟悉的命令——启动REPL的命令:

  1. #!/usr/bin/env xcrun swift

下一行你也应该很熟悉,这是一条import语句,你在本书前面的源代码示例中见过。与应用程序一样,Swift脚本也需要有基本代码库才能运行。Foundation是向Swift脚本提供基本功能的框架,因此这里导入它:

  1. import Foundation

接下来是一个名为Execution的Swift类,其使命是执行命令,这样的工作脚本做得很多。正如你看到的,要在Swift中执行命令,需要做些设置工作。通过将执行这些设置工作的代码封装在类中,后面再执行命令时将容易得多。

  1. class Execution {

这个类中唯一的方法是execute,它接受两个参数:一个名为pathString参数(用于指定要运行的可执行文件的路径)以及一个名为argumentsString数组参数(这个参数是可选的)。这个方法返回一个Int值,指出了命令的执行状态。

你可能还记得,调用方法或函数时,可以传递可选参数,也可以不传递。在这里,参数arguments还是可选类型,这意味着可以将其设置为nil

你可能有点陌生的是方法定义前面的关键字class。这是一个特殊方法,被称为类型方法。类型方法的调用方式不同于你熟悉的实例方法。

类型方法可直接通过类调用,而无需创建实例。类型方法通常旨在提供便利,你稍后将看到这一点。

  1. class func execute(#path: String, arguments: [String]? = nil) -> Int {

在这个方法中,是启动命令的步骤。使用了Foundation类NSTask来设置启动路径和参数:

  1. let task = NSTask()
  2. task.launchPath = path

对于参数arguments,必须检查其值是否为nil。仅当不为nil时,才使用惊叹号(!)将其拆封并赋给task对象的属性arguments

  1. if arguments != nil {
  2. task.arguments = arguments!
  3. }

设置好task对象后,调用其launch方法来执行指定的命令:

  1. task.launch()

有关NSTask的文档指出,必须调用方法waitUntilExit让任务结束。

  1. task.waitUntilExit()

最后,将task对象的属性terminationStatus作为Int值返回(这个属性的类型为Int32,因此这里将其转换为Int,以方便调用者):

  1. return Int(task.terminationStatus)
  2. }
  3. }

在类定义的后面,是实际使用这个类的代码。首先,定义了一个变量,用于存储方法execute返回的状态:

  1. var status : Int = 0

接下来,调用方法execute来执行命令/bin/ls(它显示目录中的文件)。注意到使用了命令参数path:,在方法的定义中使用字符#指定了必须这样做。要求用户指定参数名可突显参数的用途,让方法的用法更清晰。

另外,注意到这里没有传入参数arguments

在接下来的一行,显示了返回的状态。

  1. status = Execution.execute(path: "/bin/ls")
  2. println("Status = \(status)")

接下来,再次调用方法execute来执行命令/bin/ls,但这次通过参数arguments指定了根路径/

  1. status = Execution.execute(path: "/bin/ls", arguments: ["/"])
  2. println("Status = \(status)")

你刚才看到的场景将语言的灵活性推到了极致。你可以使用Swift编写一个类,并在shell脚本中使用它。你花时间使用Swift为应用程序编写的代码,可在脚本编程中重用。

posted @ 2016-01-22 10:58  我叫南部21号  阅读(1478)  评论(0)    收藏  举报