Как преобразовать скрипт оболочки (bash) в код Scala? - PullRequest
0 голосов
/ 31 января 2019

У меня есть сценарий оболочки с серией определенных шагов.Я пытаюсь преобразовать скрипт в код Scala, поддерживая порядок шагов.По сути, я хочу, чтобы мой код Scala был зеркалом сценария оболочки.

Я использовал библиотеку sys.process ._ .В сценарии оболочки есть такие команды:

mkdir <pathToDir>
hadoop fs -copyToLocal <source> <dest>
rm -r <pathToDir>
java -jar <someScript>

Мне нужно поддерживать порядок выполнения этих шагов.

Я пробовал что-то вроде:

import sys.process._
Class A {
  def processMethod(): Unit = { 
    Process("mkdir -p <dir1>") #| Process("hadoop fs -copyToLocal 
    <hdfsDir1> <localDir1>") #| Process("mkdir -p <dir2>") #| 
    Process("hadoop fs -copyToLocal <hdfsdir2>/*.parquet <localDir2>") 
    #| Process("java -jar <pathToJarFile> -script <sampleScripts> 1>&2") 
    #| Process("rm -r<localDir1>") #| Process("rm -r <localDir2>") ! 
  }
}

Я ожидаю, что операции будут выполняться в порядке, в котором они были определены.Я запутался в том, как работает ProcessBuilder / Process или есть ли альтернатива для преобразования всего этого в код Scala?

Ответы [ 3 ]

0 голосов
/ 31 января 2019

В дополнение к методу ###, как указал @ymonad, вам действительно следует использовать методы ProcessBuilder более непосредственно.Это облегчает чтение и понимание кода.

import sys.process._

Seq("mkdir", "SO")        ###
Seq("touch", "SO/file")   ###
Seq("mv", "SO", "SoWhat") !

Использование Seq[String] вместо простого String предлагает некоторые преимущества при разборе нескольких аргументов, передаваемых процессу.

0 голосов
/ 31 января 2019

Я не углублялся в этот проект, поэтому не могу помочь вам с примером из первых рук, но посмотрите на проект Ammonite Scala .

Цитирование издомашняя страница:

Ammonite позволяет использовать язык Scala для создания сценариев: в REPL, в качестве сценариев, в качестве библиотеки для использования в существующих проектах или в качестве оболочки для автономных систем.

...

Цель Ammonite - освободить ваш код Scala от «тяжелых» проектов, используя облегченную среду выполнения Ammonite: если вы хотите запустить Scala, откройте Ammonite-REPL и запустите его,в интерактивном режиме!Если вы хотите запустить его позже, сохраните его в несколько скриптов Scala и запустите их позже.

По этой ссылке приведены некоторые примеры того, что вы можете сделать:

import ammonite.ops._

// Let's pick our working directory
val wd: Path = pwd/'ops/'target/"scala-2.11"/"test-classes"/'example3

// And make sure it's empty
rm! wd
mkdir! wd

// You can create folders through `mkdir!`. This behaves the same as
// `mkdir -p` in Bash, and creates and parents necessary
val deep = wd/'this/'is/'very/'deep
mkdir! deep

// You can also use backticks to execute commands which aren't valid Scala identifiers, e.g.
`ssh-add`
Enter passphrase for /Users/haoyi/.ssh/id_rsa:

0 голосов
/ 31 января 2019

В соответствии с документом , #| создает команду, которая будет выполнять команду и направлять вывод другим.Как говорится, следующий код в Scala:

(Process("echo hello") #| Process("wc -c")).!

эквивалентен следующему коду Bash:

echo hello | wc -c

, что не то, что вы хотите.

То, что выищем оператор ### , который создает команду, которая будет запускать одну команду, а затем другую.

Используя этот оператор, вы можете написать следующий код Scala:

(Process("ls") ### Process("echo hello")).!

Что эквивалентно следующему коду Bash:

ls
echo hello

Однако обратите внимание, что использование Process вышеописанным способом не является полностью эквивалентным Bash, поскольку оно не может изменить текущий каталог с помощью cd и не использоватьСинтаксис bash, такой как if, for, case.

Если вам действительно нужен код, эквивалентный bash, единственный способ - запустить скрипт с помощью bash.

...