如何编写将对文件更改做出反应的Scala脚本

时间:2013-11-06 08:12:52

标签: scala

我想将以下批处理脚本更改为Scala(只是为了好玩),但是,脚本必须继续运行并侦听* .mkd文件的更改。如果更改了任何文件,则脚本应重新生成受影响的文档。文件IO一直是我的阿喀琉斯之踵......

#!/bin/sh
for file in *.mkd
do
  pandoc --number-sections $file -o "${file%%.*}.pdf"
done

任何关于良好方法的想法都将受到赞赏。

1 个答案:

答案 0 :(得分:4)

以下代码取自我对Watch for project files also的回答,可以查看目录并执行特定命令:

#!/usr/bin/env scala

import java.nio.file._
import scala.collection.JavaConversions._
import scala.sys.process._

val file = Paths.get(args(0))
val cmd = args(1)
val watcher = FileSystems.getDefault.newWatchService

file.register(
  watcher, 
  StandardWatchEventKinds.ENTRY_CREATE,
  StandardWatchEventKinds.ENTRY_MODIFY,
  StandardWatchEventKinds.ENTRY_DELETE
)

def exec = cmd run true

@scala.annotation.tailrec
def watch(proc: Process): Unit = {
  val key = watcher.take
  val events = key.pollEvents

  val newProc = 
    if (!events.isEmpty) {
      proc.destroy()
      exec
    } else proc

  if (key.reset) watch(newProc)
  else println("aborted")
}

watch(exec)

用法:

watchr.scala markdownFolder/ "echo \"Something changed!\""

必须对脚本进行扩展才能将文件名注入命令。截至目前,这个片段应该被视为实际答案的构建块。

修改脚本以合并* .mkd通配符将是非常重要的,因为您必须手动搜索文件并在所有文件上注册监视。重新使用上面的脚本并将所有文件放在目录中具有在创建新文件时拾取新文件的额外优势。

正如你所看到的那样,只需依靠Scala& amp; Java API,你最好依赖于替代库,或者只是在使用INotify时坚持使用bash。