यह उत्तर थोड़ा देर से आ सकता है, लेकिन मेरे पास एक ही मुद्दा था और स्वीकृत उत्तर मुझे बहुत संतोषजनक नहीं लगा, इसलिए मैंने थोड़ी और जांच की।
मुझे जो परेशान करता था वह यह था कि उपयोगकर्ता ने जो टाइप किया था, उसके बारे में सही जानकारी नहीं थी $0या $PROGRAM_NAMEनहीं । यदि मेरी रूबी स्क्रिप्ट एक PATH फ़ोल्डर में थी और उपयोगकर्ता ने निष्पादन योग्य नाम (जैसे या किसी भी पथ परिभाषा के बिना ) दर्ज किया, तो यह हमेशा कुल पथ तक विस्तारित होगा।./script/bin/script
मुझे लगा कि यह रूबी की कमी है, इसलिए मैंने पायथन के साथ भी यही कोशिश की और वहां पर अपने तीर्थयात्रियों के लिए, यह अलग नहीं था।
एक दोस्त ने मुझे एक हैक सुझाव देखने के लिए real thingमें /proc/self/cmdlineहै, और परिणाम था: [ruby, /home/danyel/bin/myscript, arg1, arg2...](शून्य-चार से विभाजित)। यहाँ खलनायक है, execve(1)जो एक दुभाषिया के पास जाने पर कुल पथ का विस्तार करता है।
उदाहरण सी कार्यक्रम:
extern char** environ;
int main() {
char ** arr = malloc(10 * sizeof(char*));
arr[0] = "myscript";
arr[1] = "-h";
arr[2] = NULL;
execve("/home/danyel/bin/myscript", arr, environ);
}
आउटपुट: :Usage: / home / danyel / bin / myscript फ़ाइल ...
यह साबित करने के लिए कि यह वास्तव में एक execveचीज है और मारपीट से नहीं, हम एक डमी दुभाषिया बना सकते हैं जो कुछ भी नहीं करता है लेकिन इसके लिए दिए गए तर्कों को प्रिंट करता है:
// interpreter.c
int main(int argc, const char ** argv) {
while(*argv)
printf("%s\n", *(argv++));
}
हम इसे संकलित करते हैं और इसे एक पथ फ़ोल्डर में डालते हैं (या शबंग के बाद पूरा रास्ता डालते हैं) और एक डमी स्क्रिप्ट बनाते हैं ~/bin/myscript/
Hi there!
अब, हमारे main.c में:
extern char** environ;
int main() {
char ** arr = malloc(10 * sizeof(char*));
arr[0] = "This will be totally ignored by execve.";
arr[1] = "-v";
arr[2] = "/var/log/apache2.log";
arr[3] = NULL;
execve("/home/danyel/bin/myscript", arr, environ);
}
संकलन और चल रहा है ./main: दुभाषिया / घर / डैनियल / बिन / myscript -v /var/log/apache2.log
इस सबसे अधिक संभावना के पीछे कारण यह है कि यदि स्क्रिप्ट आपके पेट में है और पूर्ण पथ प्रदान नहीं किया गया है, तो दुभाषिया इसे एक No such fileत्रुटि के रूप में पहचानेगा , जो यह करता है यदि आप करते हैं: ruby myrubyscript --options arg1और आप उस स्क्रिप्ट के साथ फ़ोल्डर में नहीं हैं ।