J'ai un script shell avec une série d'étapes définies. J'essaye de convertir le script en code Scala en maintenant l'ordre des étapes. Fondamentalement, je veux que mon code Scala soit un miroir du script shell.
J'ai utilisé la bibliothèque sys.process._ . Le script shell a des commandes comme:
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>") ! } }
J'ai besoin de maintenir l'ordre d'exécution de ces étapes.
J'ai essayé quelque chose comme:
mkdir <pathToDir> hadoop fs -copyToLocal <source> <dest> rm -r <pathToDir> java -jar <someScript>
Je m'attends à ce que les opérations s'exécutent dans l'ordre où elles ont été définies. Je ne sais pas comment fonctionne ProcessBuilder / Process ou s'il existe une alternative pour convertir tout cela en code Scala?
3 Réponses :
Selon le document , # |
construit une commande qui exécutera la commande et redirigera la sortie vers l'autre.
Cela étant dit, le code suivant dans Scala:
ls echo hello
équivaut au code Bash suivant:
(Process("ls") ### Process("echo hello")).!
ce qui n'est pas ce que vous voulez.
Ce que vous recherchez est ### opérateur qui construit une commande qui exécutera une commande puis une autre. p >
En utilisant cet opérateur, vous pouvez écrire le code Scala suivant:
echo hello | wc -c
Ce qui équivaut au code Bash suivant:
(Process("echo hello") #| Process("wc -c")).!
L'ammonite a une notion de dir de travail. ammonite.io/#Ammonite-Shell
En plus de la méthode ###
, comme @ymonad l'a souligné, vous devriez vraiment utiliser plus directement les méthodes ProcessBuilder
. Cela rend le code plus facile à lire et à comprendre.
import sys.process._ Seq("mkdir", "SO") ### Seq("touch", "SO/file") ### Seq("mv", "SO", "SoWhat") !
L'utilisation d'une Seq [String]
à la place d'une simple String
offre quelques avantages lors de l'analyse de plusieurs arguments transmis au processus.
Je n'ai pas creusé dans ce projet, je ne peux donc pas vous aider avec un exemple de première main, mais jetez un œil au Projet Ammonite Scala .
Citation de la page d'accueil:
Ammonite vous permet d'utiliser le langage Scala à des fins de script: dans le REPL, en tant que scripts, en tant que bibliothèque à utiliser dans des projets existants ou en tant que shell système autonome.
...
Le but d'Ammonite est de libérer votre code Scala des "projets" lourds, en utilisant le runtime léger Ammonite: si vous voulez exécuter un peu de Scala, ouvrez l'Ammonite-REPL et exécutez-le, interactivement! Si vous souhaitez l'exécuter plus tard, enregistrez-le dans certains scripts Scala et exécutez-les plus tard.
Sur ce lien , vous trouverez quelques exemples de ce que vous pouvez faire:
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:
Ammonite se facture comme remplacement bash: ammonite.io/#Ammonite-Shell