मोनो जादुई कैसे है?


149

मैं C # सीख रहा हूं, इसलिए मैंने थोड़ा C # प्रोग्राम बनाया जो कहता है Hello, World!, फिर इसे संकलित किया mono-cscऔर इसके साथ भाग लिया mono:

$ mono-csc Hello.cs
$ mono Hello.exe
Hello, World!

मैंने देखा है कि जब मैं हिट TABमें bash, Hello.exeनिष्पादन योग्य चिह्नित किया गया था। वास्तव में, यह फ़ाइल नाम लोड करने वाले शेल द्वारा चलता है!

Hello.exeहै एक अजीब फ़ाइल एक्सटेंशन के साथ एक ELF फ़ाइल:

$ readelf -a Hello.exe
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
$ xxd Hello.exe | head -n1
00000000: 4d5a 9000 0300 0000 0400 0000 ffff 0000  MZ..............

MZइसका मतलब है कि यह एक Microsoft Windows स्टैटिकली एक्सेलेबल है। इसे एक विंडोज बॉक्स पर छोड़ें, और यह चलेगा (चाहिए)।

मैं है wineस्थापित है, लेकिन wine, विंडोज क्षुधा के लिए एक संगतता परत जा रहा है, के बारे में 5x को चलाने के लिए जब तक ले जाता है Hello.exeके रूप में monoहै और इसे क्रियान्वित सीधे है, इसलिए यह नहीं है wineकि यह चलता है।

मुझे लगता है कि वहाँ कुछ monoकर्नेल मॉड्यूल स्थापित है monoजो कि execsyscall / s को स्वीकार करता है, या बायनेरिज़ के साथ शुरू होता है 4D 5A, लेकिन lsmod | grep monoदोस्त एक त्रुटि लौटाते हैं।

यहाँ क्या हो रहा है, और कर्नेल को कैसे पता है कि यह निष्पादन योग्य है?


बस प्रमाण के लिए यह मेरा शेल काम करने वाला जादू नहीं है, मैंने इसे चलाने के लिए क्रैप शैल (उर्फ sh) का उपयोग किया और यह अभी भी मूल रूप से चलता है।


यहाँ पूरा कार्यक्रम है, क्योंकि एक टिप्पणीकार उत्सुक था:

using System;

class Hello {
  /// <summary>
  ///   The main entry point for the application
  /// </summary>
  [STAThread]
  public static void Main(string[] args) {
    System.Console.Write("Hello, World!\n");
  }
}

4
जब आपको उत्तर मिला, लेकिन मैं थोड़ा भ्रमित हूं, यदि आप जावा जैसी संकलित भाषा के मामले में php hello.phpया python hello.pyया जैसी आज्ञाएँ चलाते हैं, तो वे भी चलेंगी क्योंकि उनकी कोई निष्पादन योग्य नहीं है, लेकिन एक प्रोग्राम फ़ाइल को पढ़ता है और निष्पादित करता है। हालाँकि, यदि आप इसके बजाय दौड़ते हैं तो मैंने आपका प्रश्न पाया और उत्तर को और अधिक उचित माना (जो कि निश्चित रूप से द्विधा-समर्थन का उपयोग करता है।perl hello.pljava hello./hello.exemono hello.exe
kuldeep.kamboj

@ kuldeep.kamboj मुझे यकीन नहीं है कि मैं समझ रहा हूं कि आप क्या कह रहे हैं लेकिन मुझे बस आश्चर्य हुआ कि एक विंडोज निष्पादन योग्य लिनक्स बॉक्स पर "मूल रूप से" चलता है।
बिल्ली

1
वास्तव में मैं क्या कह रहा था कि किसी भी कोड फ़ाइल (या संकलित फ़ाइल) को प्रारूप में इसके कार्यक्रम के माध्यम से निष्पादित किया जा सकता है program codefile, आपके मामले में कार्यक्रम मोनो है, जबकि मेरे उदाहरणों में php, python, perl और java शामिल हैं। मुझे संदेह है कि अगर मोनो अभी भी। Exe फ़ाइल को कोड के माध्यम से निष्पादित करने की अनुमति देता है। यह विंडोज़ पर बिल्कुल निर्भर नहीं होना चाहिए क्योंकि यह एक संकलित कोड को निष्पादित करता है। हालाँकि अगर आपकी स्रोत फ़ाइल में कुछ निर्भर कोड हैं जैसे कि विंडोज़ केवल एपीआई तो जाहिर है आपको उस exe फ़ाइल को चलाने के लिए शराब की आवश्यकता होगी।
kuldeep.kamboj

4
इस के अद्भुत विडंबना यह है कि है /etc/magicया /usr/share/file/magic(या इसी तरह जादुई स्थान) फ़ाइल के लिए आवश्यक जानकारी यह करने के लिए सक्षम होने के लिए होता है।

1
@ इसकी एक बहुत ही दिलचस्प फ़ाइल (यदि मैं एक पसंदीदा फ़ाइल है, तो यह शायद मेरी पहली पसंद होगी)। इसमें सभी प्रकार की फ़ाइलों की पहचान करने की जानकारी है। लेकिन आपको यह पहचानने की आवश्यकता है कि फ़ाइल पहले क्या है इससे पहले कि आप यह पता लगा सकें कि इसे कैसे चलाना है। यही फाइल और उसका जादू करता है। इसी तरह की एक चीज - लिनक्स बाइनरी कर्नेल समर्थन थोड़ी देर के लिए लिनक्स से ताकि आप इसके $ foo.jarबजाय कर सकें $ java -jar foo.jar- मोनो के लिए जैसा किया जाता है।

जवाबों:


183

यह कार्रवाई में binfmt_misc है: यह कर्नेल को यह बताने की अनुमति देता है कि कैसे बायनेरिज़ को चलाना है जिसके बारे में पता नहीं है। की सामग्री को देखो /proc/sys/fs/binfmt_misc; आपके द्वारा देखी जाने वाली फ़ाइलों में से किसी को मोनो बिन्री चलाने के तरीके के बारे में बताना चाहिए:

enabled
interpreter /usr/lib/binfmt-support/run-detectors
flags:
offset 0
magic 4d5a

(एक डेबियन सिस्टम पर)। यह कर्नेल को बताता है कि बायनेरिज़ की शुरुआत MZ( 4d5a) के साथ की जानी चाहिए run-detectors। बाद के आंकड़े बताते हैं कि बाइनरी को चलाने के लिए मोनो या वाइन का उपयोग करना है या नहीं।

बाइनरी प्रकार को किसी भी समय जोड़ा, हटाया, सक्षम और अक्षम किया जा सकता है; विवरण के लिए ऊपर दिए गए दस्तावेज़ीकरण देखें (शब्दार्थ आश्चर्यजनक हैं, यहाँ प्रयुक्त आभासी फाइल सिस्टम पूरी तरह से मानक फाइल सिस्टम की तरह व्यवहार नहीं करता है)। /proc/sys/fs/binfmt_misc/statusवैश्विक स्थिति देता है, और प्रत्येक बाइनरी "डिस्क्रिप्टर" अपनी व्यक्तिगत स्थिति दिखाता है। अक्षम करने का दूसरा तरीका binfmt_miscइसके कर्नेल मॉड्यूल को लोड करना है, अगर यह एक मॉड्यूल के रूप में बनाया गया है; इसका मतलब यह भी है कि इसे पूरी तरह से टालना संभव नहीं है।

यह सुविधा नए बाइनरी प्रकारों का समर्थन करने की अनुमति देती है, जैसे कि एमजेड निष्पादनयोग्य (जिसमें विंडोज पीई और पीई + बायनेरी शामिल हैं, लेकिन डॉस और ओएस / 2 बायनेरिज़ भी!), जावा जार फाइलें ... यह ज्ञात बाइनरी प्रकारों को भी समर्थित होने की अनुमति देता है। आम तौर पर Qemu का उपयोग करते हुए नए आर्किटेक्चर; इस प्रकार, उपयुक्त पुस्तकालयों के साथ, आप पारदर्शी रूप से एआरएम लिनक्स बायनेरिज़ को एक इंटेल प्रोसेसर पर चला सकते हैं!

आपके प्रश्न को क्रॉस-संकलन से लिया गया है, जो कि .NET समझ में आता है, और यह एक चेतावनी के साथ लाता है binfmt_misc: कुछ कॉन्फ़िगरेशन स्क्रिप्ट दुर्व्यवहार करती हैं जब आप एक सिस्टम पर क्रॉस-कंपाइल करने की कोशिश करते हैं जो क्रॉस-संकलित बायनेरिज़ को चला सकता है। आमतौर पर, क्रॉस-संकलन का पता लगाने में एक द्विआधारी का निर्माण और इसे चलाने का प्रयास शामिल है; यदि यह चलता है, तो आप क्रॉस-संकलन नहीं कर रहे हैं, यदि यह नहीं होता है, तो आप (या आपके संकलक के टूटे हुए) हैं। autoconfस्क्रिप्ट आमतौर पर इस मामले में बिल्ड और होस्ट आर्किटेक्चर को स्पष्ट रूप से निर्दिष्ट करके तय की जा सकती हैं, लेकिन कभी-कभी आपको binfmt_miscअस्थायी रूप से अक्षम करना होगा ...


2
उन लोगों के लिए जो / खरीद के बारे में उत्सुक हैं, आप कैसे / खरीद / * काम में रुचि रखते हैं? पर सुपर उपयोगकर्ता
एक CVn
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.