2009-02-09 11 views
1

J'ai essayé d'exécuter un script shell à partir du code Java, mais je suis confronté à un problème. Le script est dans le fichier batchstart.sh -impossible d'exécuter le script ksh à partir de Java: java.io.IOException:.: Non trouvé

#!/bin/ksh 
export DISPLAY=:0.0 

Maintenant, le script est exécuté avec un point sur la ligne de commande -. batchstart.sh

Comment l'exécuter à partir de Java? Mon code java est ci-dessous. Il jette l'exception suivante -

 
java.io.IOException: .: not found 
    at java.lang.UNIXProcess.forkAndExec(Native Method) 
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:102) 
    at java.lang.ProcessImpl.start(ProcessImpl.java:65) 
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:451) 
    at java.lang.Runtime.exec(Runtime.java:591) 
    at java.lang.Runtime.exec(Runtime.java:429) 
    at SetDisplay.main(SetDisplay.java:12) 
import java.io.*; 

public class SetDisplay { 

    public static void main(String[] args) { 

     File wd = new File("/myhomedir/"); 
     System.out.println("Working Directory: " +wd); 
     Process proc = null; 

     try { 
      proc = Runtime.getRuntime().exec(". batchstart.sh", null, wd); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Comment puis-je faire fonctionner le script shell?

J'ai également essayé le code suivant, mais cela ne fonctionne pas non plus.

File wd = new File("/bin"); 
System.out.println(wd); 
Process proc = null; 
try { 
    proc = Runtime.getRuntime().exec("/bin/bash", null, wd); 
} 
catch (IOException e) { 
    e.printStackTrace(); 
} 
if (proc != null) { 
    BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream())); 
    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true); 
    out.println("cd /home/"); 
    out.println(". batchstart.sh"); 
    out.println("exit"); 
    try { 
    String line; 
    while ((line = in.readLine()) != null) { 
     System.out.println(line); 
    } 
    proc.waitFor(); 
    in.close(); 
    out.close(); 
    proc.destroy(); 
    } 
    catch (Exception e) { 
    e.printStackTrace(); 
    } 
} 

Répondre

1

La commande source (".") est un shell intégré. Vous devez explicitement exécuter /bin/ksh, en passant votre nom de script en argument (suivi de tous les arguments de script).

Vous avez un plus gros problème si vous besoin de pour la source du script. Cela signifie généralement que les changements d'environnement se produisent dans le contexte de l'interpréteur de commandes en cours, pas un sous-shell.

Cela ne fonctionnera pas avec Java puisque Java n'est pas un shell. Vous aurez besoin de comprendre comment changer l'environnement avec Java.

Bien sûr, si je me trompe et qu'il y a autre chose dans ce script qui ne fait que régler DISPLAY, cela peut fonctionner comme suggéré. La méthode que vous allez devoir utiliser dépend de ce que vous essayez d'accomplir (comme dans "Exécutez-vous d'autres programmes utilisant exec() qui reposent sur la définition de DISPLAY?" Ou "Votre programme Java besoin d'AFFICHER pour être réglé? "). Si, comme vous l'indiquez dans votre commentaire, c'est uniquement votre programme Java qui a besoin d'être défini par DISPLAY, il suffit de le mettre à l'extérieur avant que votre programme s'exécute. Créez un fichier cmd (ou bash) qui définit la variable DISPLAY puis appelle le JRE pour exécuter votre programme.

#/bin/ksh 
export DISPLAY-:0.0 
/usr/bin/jre/java your_program blah.blah.blah 

Je voudrais également modifier votre main() pour vérifier qu'il est réglé sur quelque chose et sortir gracieusement sinon:

if (System.getenv ("DISPLAY") == null) 
    // doesn't exist, exit gracefully. 
+0

Mon programme Java a juste besoin d'être réglé sur DISPLAY. Donc, n'y a-t-il aucun moyen que je puisse exécuter le script depuis Java? – Vicky

+0

Donc vous voulez dire qu'il n'y a aucun moyen de faire fonctionner "export DISPLAY =: 0.0" à partir de Java? – Vicky

+0

Non, voir mise à jour. Votre problème de base est que tout ce que vous exécutez depuis Java n'affecte PAS l'environnement Javas. Et, en plus de cela, je ne crois pas que Java fournisse un setenv(). – paxdiablo

0

La période « » est un shell intégré, et exécute le script "in-place", analogue à #include en C/C++. En utilisant "." en dehors d'un shell-script n'a pas de sens.

Si vous voulez run le script de Java, vous devez exécuter l'interpréteur de script (/ bin/ksh):

Runtime.getRuntime().exec("/bin/ksh batchstart.sh", ...) 

mais notez que ce n'est pas sémantiquement équivalent, puisque vous êtes l'exécution de batchstart.sh en tant que sous-processus au lieu de l'utiliser.

0

Lorsqu'il est exécuté à partir de la ligne de commande, en utilisant un point au début d'un script indique que le script doit être exécuté dans l'environnement actuel , au lieu de fraie un nouveau sous-shell et en utilisant une nouvelle copie du courant environnement. Cela vous permet d'exporter une nouvelle valeur d'une variable d'environnement à utiliser par des commandes exécutées ultérieurement à partir du même shell interactif.

De toute évidence, cette technique ne fonctionne que si vous exécutez votre script batchstart.sh à partir d'un shell réel. Java ne sait pas comment fonctionne ce mécanisme et donc le point ne veut rien dire. Un script ne peut pas modifier l'environnement du processus Java à partir duquel il a été appelé. Si votre objectif est de modifier la valeur de la variable d'environnement DISPLAY pour les autres commandes exécutées par votre processus Java, envisagez d'utiliser la classe ProcessBuilder pour spécifier un nouvel environnement pour le processus enfant. Java ne contient pas de façon intégrée de modifier les variables dans son propre environnement.