سؤال

كان لدي بعض التعليمات البرمجية التي تم تشغيل الأوامر من خلالها Runtime.getRuntime.exec (سلسلة), ، وكان يعمل على نظام التشغيل Windows.عندما قمت بنقل الكود إلى Linux، تعطل، وكانت الطريقة الوحيدة لإصلاحه هي التبديل إلى إكسيك (سلسلة []) إصدار.إذا تركت الأمور بهذه الطريقة، فهل سيعمل الكود بنفس الطريقة على نظامي التشغيل Windows وLinux، أم يجب علي استخدام exec(String) على Windows وexec(String[]) على Linux؟

هل كانت مفيدة؟

المحلول

يستخدم خيط[] على كليهما.

الجواب انا أعطاك من قبل كان نتيجة عدة ساعات بائسة من تصحيح أخطاء برنامج الإنتاج الذي يعمل على نظام التشغيل Windows.

بعد الكثير من الجهد توصلنا (أنا) إلى الحل المنشور قبل (استخدام خيط[] )

نظرًا لأن المشكلات التي واجهتك كانت على نظام Linux، أعتقد أن استخدام المصفوفة على كليهما سيكون الأفضل.

بالمناسبة.لقد جربت هذه الطريقة مع Java 1.4، ومنذ ذلك الحين يتوفر فصل جديد: ProcessBuilder تمت إضافته في Java1.5.لست متأكدًا من سبب كل ذلك، ولكن يجب أن يكون هناك سبب وجيه لذلك.ألقِ نظرة عليه واقرأ الفرق بين ملف Runtime.exec.ربما سيكون خيارا أفضل.

أخيرًا، لن تعمل بعض الأوامر على أي من النظامين الأساسيين لأنها مضمنة في Shell (إما Windows cmd أو bash/sh/ إلخ) مثل دير أو صدى صوت وبعض هؤلاء.لذلك أوصي بإجراء اختبار إضافي/إضافي على كل نظام أساسي مستهدف وإضافة معالجات استثناء للأوامر غير المدعومة.

:)

نصائح أخرى

طيب أستسلم:ما هو الأمر غير التافه الذي يمكنك تمريره إلى exec()، وتتوقع الحصول على نتائج معقولة على كل من Windows وLinux؟يبدو أن السؤال عما إذا كانت exec() مستقلة عن النظام الأساسي يفتقد الهدف الكامل من exec()، وهو استدعاء السلوك الخاص بالنظام الأساسي.

للإجابة على سؤالك فعليًا، نعم - ستكون الطريقة التي يتم بها تفسير سلسلة الأمر مختلفة على الأنظمة الأساسية المختلفة (وربما، بالنسبة للأصداف المختلفة، على Linux)، ومن المرجح أن ينتهي استخدام إصدار String[] بالمعلمات الحصول على تمرير بشكل صحيح.

يقوم Tokeniser الافتراضي لتقسيم المعلمة exec(String) إلى String[] بتقسيمها ببساطة حسب حرف المسافة.إنه لا يفسر علامات الاقتباس مثل أمر Shell الذي تم إدخاله يدويًا، لذا يجب عليك استدعاء إصدار String[] .ولكن إذا كنت تستخدم Sun JDK على كلا النظامين الأساسيين، فيجب أن يكون السلوك مشابهًا.

ومع ذلك، نظرًا لأن Windows يوفر أوامر shell مختلفة عن أنظمة التشغيل الأخرى (على سبيل المثال، النسخ بدلاً من cp)، فقد لا تعمل أوامرك على جميع الأنظمة الأساسية.

الفرق بين التابع exec()‎ الذي يأخذ سلسلة واحدة والأسلوب الذي يقبل مصفوفة هو أن إصدار المصفوفة يسمح لك بتحديد كيفية تقسيم الأمر ووسائطه (على سبيل المثال.بشكل صحيح).عند استخدام الطريقة (الطرق) التي تقبل سلسلة فقط، تقوم الطريقة بتقسيمها إلى مصفوفة على مسافة بيضاء.تتم معالجة المعالجة منذ ذلك الحين بنفس الطريقة لكلتا الطريقتين.

هذا هو الكود من فئة Runtime الذي يوضح كيفية تقسيم سلسلة مفردة إلى مصفوفة ثم استدعاء إصدار String[] لمواصلة المعالجة.

   public Process exec(String command, String[] envp, File dir)
            throws IOException {
         if (command.length() == 0)
             throw new IllegalArgumentException("Empty command");

         StringTokenizer st = new StringTokenizer(command);
         String[] cmdarray = new String[st.countTokens()];
         for (int i = 0; st.hasMoreTokens(); i++)
             cmdarray[i] = st.nextToken();
         return exec(cmdarray, envp, dir);
     }

لذا فإن الطريقة التي تقبل سلسلة لن تعمل إذا كان كسر الأمر على مسافة بيضاء لا يفصل الأمر والوسائط بشكل صحيح.

من [واجهة برمجة التطبيقات] [1]

تتحقق هذه الطريقة من أن cmdarray هو أمر نظام تشغيل صالح.الأوامر صالحة تعتمد على النظام ، ولكن على الأقل يجب أن يكون الأمر قائمة غير فارغة من السلاسل غير الفاتحة.

لذا نعم، فهو يعتمد على النظام.راجع للشغل، هل يمكنك نشر الكود ذي الصلة، حتى نتمكن من رؤية الخطأ الذي تفعله (في النهاية)؟

[1]: http://java.sun.com/javase/6/docs/api/Java/lang/Runtime.html#exec(java.lang.String[], ، java.lang.String[]، java.io.File)

يستدعي exec() الأوامر الأصلية على نظام التشغيل الأساسي.

لن تعمل الأوامر المصممة لنظام التشغيل Windows على نظام التشغيل Linux، ويجب إعادة كتابتها.

إذا كنت تريد تشغيل أوامر مختلفة على نظامي التشغيل Windows وLinux، فيمكنك معرفة نظام التشغيل الذي يعمل باستخدام شيء مثل ما يلي:

        String os = System.getProperty("os.name").toLowerCase();
        if (os.indexOf("win") >= 0) {
            // Windows Commands
        } else {
            // Linux Commands
        }

شيء جيد آخر هو كتابة الأوامر الخاصة بك في برنامج نصي (.bat لنظام التشغيل Windows و.sh لنظام التشغيل Linux) واستدعاء هذه البرامج النصية بدلاً من ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top