2012-05-15 3 views
5

Ich brauche einen Shell-Befehl von einem Scala-Skript auszuführen, und ich benutze das folgende Snippet für die:Terminal-Befehl cd nicht von Scala-Skript arbeitet

import scala.sys.process.{Process, ProcessIO} 

val command = "ls /tmp" 
val process = Process(command) 

val processIO = new ProcessIO(_ =>(), 
    stdout => scala.io.Source.fromInputStream(stdout).getLines.foreach(println), 
    _ =>()) 
process.run(processIO) 

Der Code funktioniert gut. Ich frage mich, warum ich

java.io.IOException: Cannot run program "cd": error=2, No such file or directory 

erhalten, sobald ich den Befehl cd /tmp && ls ändern, die zu ls /tmp IMO entspricht?

Antwort

8

Von Wikipedia on cd command:

[...] auf Unix-Systemen cd die Funktion chdir() POSIX C aufruft. Dies bedeutet, dass bei der Ausführung des Befehls kein neuer Prozess erstellt wird, um in das andere Verzeichnis zu migrieren, wie dies bei anderen Befehlen der Fall ist, z. B. ls. Stattdessen führt die Shell selbst diesen Befehl aus.

Es gibt sogar ein Zitat über Java gibt:

[...] weder die Java-Programmiersprache noch die Java Virtual Machine unterstützt chdir() direkt; ein Anforderungswechsel seit über einem Jahrzehnt offen geblieben, während das Team für Java verantwortlich, die Alternativen in Betracht gezogen, obwohl bis zum Jahr 2008 wurde der Antrag abgelehnt, nachdem nur eine begrenzte Unterstützung [...]

es sich vorgestellt wurde Versuchen:

$ which ls 
/bin/ls 
$ which cd 
$ 

In einfachen Worten, cd ist kein Programm (Prozess), die Sie ausführen können (wie /bin/ls) - es ist mehr eine Befehlszeile-Anweisung.

Was möchten Sie erreichen? Changing the current working directory in Java? oder ändern Sie das Arbeitsverzeichnis des Prozesses, den Sie gerade erstellt haben?

+3

mit 'type cd' und' type ls' in der Shell sind auch in Ihrer Shell demonstrativ. Es sollte berichten, dass cd keine ausführbare Datei ist, sondern eine eingebaute Shell. – stew

+0

Grundsätzlich wollte ich eine Ausgabe eines bestimmten Befehls lesen, der aus einem Verzeichnis ausgeführt werden sollte, das Laufzeit bekannt ist, wie: 'cd/somedir && find. -Mindepth 5 -Typ d'. Es gibt eine Reihe von Möglichkeiten, um es ohne "cd" zu erreichen, aber mit Perl Hintergrund war ich nur kurios, warum das mit JVM unmöglich war. Danke für die Antwort! – nab