2016-02-25 7 views
5

निष्पादन योग्य द्वारा स्पष्ट होने के लिए, मेरा मतलब प्रोसेसर के लिए शाब्दिक बाइट तैयार नहीं है। उदाहरण के लिए एक बैश स्क्रिप्ट, जिसे व्याख्या और निष्पादन योग्य नहीं है, निष्पादन योग्य हो जाता है जब एक शेबैंग शीर्ष पर जोड़ा जाता है जो स्क्रिप्ट निर्दिष्ट करता है /bin/bash या /bin/sh या जो भी प्रोग्राम इसे व्याख्या करेगा।क्या कोई भाषा निष्पादन योग्य बनाना संभव है?

मैं सोच रहा था कि अन्य स्क्रिप्टिंग भाषाओं के साथ ऐसा करना संभव है या नहीं? और यदि हां, तो क्या यह वास्तव में एक शेबैंग जोड़ने जैसा आसान है जो प्रोग्रामिंग प्रोग्राम (यानी #!/usr/bin/python को पाइथन स्क्रिप्ट या #!/usr/local/bin/node जावास्क्रिप्ट के लिए संदर्भित करता है)?

मैं यह भी सोच रहा था कि जावा के साथ ऐसा करना संभव है, जो तकनीकी रूप से एक स्क्रिप्टिंग भाषा नहीं है लेकिन निश्चित रूप से निष्पादन योग्य नहीं है। ऐसा लगता है कि जावा कठिन होगा क्योंकि उपयोगकर्ता को वास्तव में संकलित फ़ाइल में शेबैंग जोड़ने का अवसर नहीं है।

उत्तर

3

आप निश्चित रूप से एक फ़ाइल बना सकते हैं:

#!/any/executable/program args 
...input goes here... 

आप जावा के साथ यह कर सकता है

#!/path/bin/java mainclass 
...this is System.in... 
+0

आह जावा के साथ ऐसा? –

+0

हां, यह सही है और आपको यह सुनिश्चित करना होगा कि इसे चलाने से पहले क्लासपाथ सही था। इसलिए आम तौर पर एक श्ल स्क्रिप्ट का उपयोग करना अधिक व्यावहारिक है। –

+0

यह दिलचस्प है। मुझे नहीं पता था कि आप शेबांग के बाद भी तर्क पारित कर सकते हैं।मुझे लगता है कि मैं स्वयं को हाहा सिखाए जाने के लिए मिलता हूं। उत्तर स्वीकृत! –

2

नहीं। यह किसी भी स्क्रिप्ट पर एक वह धमाके डाल करने के लिए संभव नहीं है और यह निष्पादित करेंगे। बैश इस तथ्य पर निर्भर करता है कि शेबांग वाली फ़ाइल # से शुरू होने वाली रेखाओं को अनदेखा करती है। इसलिए किसी भी स्क्रिप्टिंग भाषा या बाइट कोड जो शेबांग के साथ पहली पंक्ति को अनदेखा कर सकता है काम करेगा।

यदि आपकी भाषा # टिप्पणी के रूप में समर्थन नहीं करती है या पहली पंक्ति को अनदेखा करती है तो उसे दूसरी स्क्रिप्टिंग भाषा से गुज़रना पड़ता है जो इसे अनदेखा करता है।

कहा जा रहा है कि आप बाश स्क्रिप्ट्स प्राप्त कर सकते हैं जिनमें बाइनरी ब्लॉब्स इनलाइन कहा जा सकता है। खेल इंस्टॉलर ऐसा करते हैं।

उपयोग स्काला:

+0

आप बैश स्क्रिप्ट में बाइनरी ब्लॉब का उपयोग कैसे करते हैं? उदाहरण के लिए –

+0

http://www.linuxjournal.com/content/add-binary-payload-your-shell- स्क्रिप्ट – Alex

2

इसके बजाय कोड के बहुत सारे लेखन जावा स्रोत के रूप में निष्पादन योग्य बनाने की है, तो आप कुछ ही विकल्प हैं! क्या आप जानते थे कि स्कैला जावा से बनाया गया है? इसमें एक दुभाषिया और कंपाइलर है। आप एक स्क्रिप्ट, एक खोल या संकलन चला सकते हैं और इसे चला सकते हैं। स्कैला और जावा एक साथ काम करते हैं। दोनों एक ही बाइटकोड को संकलित करते हैं और एक JVM पर चलते हैं। हां, भाषा अजीब लगती है क्योंकि स्कैला जावा, आर और पायथन के बीच एक क्रॉस की तरह है, लेकिन अधिकांश मूल भाषा अपरिवर्तित है और सभी जावा पैकेज उपलब्ध हैं। स्काला को आज़माएं। यदि आप लिनक्स पर हैं, तो आप स्पार्क को भी एक मशीन के लिए भी देख सकते हैं।

यदि आप केवल जावा का उपयोग करने का आग्रह करते हैं, तो आप एक हाइब्रिड प्रोग्राम बना सकते हैं जो दो चीजें करता है (मैंने पहले यह किया है): कोड संकलित करें और इसे चलाएं। निष्पादन योग्य या यहां तक ​​कि एक बैश स्क्रिप्ट स्रोत फ़ाइलों को लेने और उन्हें निष्पादन योग्य बनाने का काम कर सकती है। यदि आप जावा खोल बनाना चाहते हैं, तो आपको एक गतिशील रनटाइम कंपाइलर/लोडर बनाना होगा, लेकिन आपको बस जावा/ओरेकल पहले से ही उपयोग करने की आवश्यकता है। एक फ़ाइल से जावा सिंटैक्स डालने की कल्पना करें जहां मैंने एक प्रिंट स्टेटमेंट रखा था। जब तक यह संकलित होता है तब तक आप वहां कुछ भी प्राप्त कर सकते थे। इस उदाहरण देखें:

package util.injection; 

import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.Writer; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.net.URLClassLoader; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
import java.util.Locale; 
import javax.tools.Diagnostic; 
import javax.tools.DiagnosticCollector; 
import javax.tools.JavaCompiler; 
import javax.tools.JavaFileObject; 
import javax.tools.StandardJavaFileManager; 
import javax.tools.ToolProvider; 

public class Compiler { 

    static final long t0 = System.currentTimeMillis(); 

    public static void main(String[] args) { 
     StringBuilder sb = new StringBuilder(64); 
     String packageName = "util"; 
     String className = "HelloWorld"; 
     sb.append("package util;\n"); 
     sb.append("public class HelloWorld extends " + Function.class.getName() + " {\n"); 
     sb.append(" public void test() {\n"); 
     sb.append("  System.out.println(\"Hello from dynamic function!\");\n"); 
     sb.append(" }\n"); 
     sb.append("}\n"); 
     String code = sb.toString(); 

     String jarLibraryFile = "target/myprojectname.jar"; 

     Function dynFunction = code2class(packageName, className, code, jarLibraryFile); 
     dynFunction.test(); 
    } 

    public static Function code2class(String packageName, String className, String code, String jarLibraryFile) { 
     String wholeClassName = packageName.replace("/", ".") + "." + className; 
     String fileName = wholeClassName.replace(".", "/") + ".java";//"testcompile/HelloWorld.java"; 
     File javaCodeFile = new File(fileName); 
     string2file(javaCodeFile, code); 
     Function dynFunction = null; 
     try { 

      boolean success = compile(jarLibraryFile, javaCodeFile); 

      /** 
      * Load and execute 
      * ************************************************************************************************ 
      */ 
      System.out.println("Running... " + (System.currentTimeMillis() - t0) + " ms"); 
      Object obj = load(wholeClassName); 
      // Santity check 
      if (obj instanceof Function) { 
       dynFunction = (Function) obj; 
       // Run it 
       //Edit: call dynFunction.test(); to see something 
      } 
      System.out.println("Finished... " + (System.currentTimeMillis() - t0) + " ms"); 
     } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException exp) { 
      exp.printStackTrace(); 
     } 
     return dynFunction; 
    } 

    public static boolean compile(String jarLibraryFile, File javaCodeFile) throws IOException { 
     /** 
     * Compilation Requirements 
     * ******************************************************************************************** 
     */ 
     System.out.println("Compiling... " + (System.currentTimeMillis() - t0) + " ms"); 
     DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); 

     // This sets up the class path that the compiler will use. 
     // I've added the .jar file that contains the DoStuff interface within in it... 
     List<String> optionList = new ArrayList<>(2); 
     optionList.add("-classpath"); 
     optionList.add(System.getProperty("java.class.path") + ";" + jarLibraryFile); 

     Iterable<? extends JavaFileObject> compilationUnit 
       = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(javaCodeFile)); 
     JavaCompiler.CompilationTask task = compiler.getTask(
       null, 
       fileManager, 
       diagnostics, 
       optionList, 
       null, 
       compilationUnit); 
     fileManager.close(); 

     /** 
     * ******************************************************************************************* 
     * Compilation Requirements * 
     */ 
     if (task.call()) { 
      return true; 
      /** 
      * *********************************************************************************************** 
      * Load and execute * 
      */ 
     } else { 
      for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { 
       System.out.format("Error on line %d in %s%n", 
         diagnostic.getLineNumber(), 
         diagnostic.getSource().toUri()); 
       System.out.printf("Code = %s\nMessage = %s\n", diagnostic.getCode(), diagnostic.getMessage(Locale.US)); 

      } 
     } 
     return false; 
    } 

    public static void string2file(File outputFile, String code) { 
     if (outputFile.getParentFile().exists() || outputFile.getParentFile().mkdirs()) { 

      try { 
       Writer writer = null; 
       try { 
        writer = new FileWriter(outputFile); 
        writer.write(code); 
        writer.flush(); 
       } finally { 
        try { 
         writer.close(); 
        } catch (Exception e) { 
        } 
       } 
      } catch (IOException exp) { 
       exp.printStackTrace(); 
      } 
     } 
    } 

    public static Object load(String wholeClassName) throws IllegalAccessException, InstantiationException, ClassNotFoundException, MalformedURLException { 
     // Create a new custom class loader, pointing to the directory that contains the compiled 
     // classes, this should point to the top of the package structure! 
     URLClassLoader classLoader = new URLClassLoader(new URL[]{new File("./").toURI().toURL()}); 
     // Load the class from the classloader by name.... 
     Class<?> loadedClass = classLoader.loadClass(wholeClassName); 
     // Create a new instance... 
     Object obj = loadedClass.newInstance(); 
     return obj; 
    } 

} 

.. .class फ़ाइलों निष्पादन अभी भी द्वारा कहीं और संग्रहीत और संदर्भित करना होगा

package util.injection; 

public class Function { 

    private static final long serialVersionUID = 7526472295622776147L; 

    public void test() { 
       System.out.println("Hello from original Function!"); 
    } 

    public int getID() { 
     return -1; 
    } 

    public void apply(float[] img, int x, int y) { 

    } 

    public double dot(double[] x, double[] y) { 
      return 0; 
    } 
} 
संबंधित मुद्दे