2010-07-15 11 views
19

एक सी प्रोग्राम में मैं argv [0] लिख सकता हूं और नया नाम एक ps सूची में दिखाई देता है।bash में argv0 को कैसे बदलें ताकि कमांड ps में विभिन्न नामों के साथ दिखाई दे?

मैं इसे बैश में कैसे कर सकता हूं?

+0

क्या आपका मतलब है कि आप एक बैश खोल स्क्रिप्ट चलाने के लिए चाहते हैं और इसका नाम * ps * में "bash" के अलावा कुछ और है? – Karmastan

+0

अगर मैं 'foo.sh' नामक एक स्क्रिप्ट लिखता हूं, तो यह _ps_ में foo.sh के रूप में दिखाई देता है। मैं इसे 'bar.sh' के रूप में दिखाना चाहता हूं। – bstpierre

+0

btw मुझे संदेह है कि argv0 लिखना वास्तव में कानूनी है, खासकर यदि आप जो लिखते हैं वह मूल से अधिक लंबा है, लेकिन मुझे इस – frankc

उत्तर

10

मुझे बैश के स्रोत के माध्यम से जाने का मौका मिला है और ऐसा लगता है कि argv [0] को लिखने के लिए कोई समर्थन नहीं है।

25

exec -a <newname> के माध्यम से एक नया प्रोग्राम चलाते समय आप इसे कर सकते हैं।

+1

+1: और उपरोक्त में जोड़ने के लिए, आपके पास "अगर $ 0 वह नहीं है जो मैं चाहता हूं, तो 'exec -a what_i_want' शीर्ष पर ... – eruciform

+1

ऐसा प्रतीत नहीं होता है बैश 4.0.33 –

+4

में मेरे लिए प्रभावित करें दुर्भाग्य से यह * वर्तमान * खोल को प्रभावित नहीं करता है। आपको इसका उपयोग करके एक नया खोलना होगा। –

6
(exec -a foo bash -c 'echo $0') 
+0

यह * प्रक्रिया * पुनरारंभ होगा। नाम बदलने के लिए argv [0] को लिखने जैसा नहीं है। – bstpierre

+1

ठीक है, यह एक सबहेल फोर्क करता है, फिर उस निष्पादन को 'exec' द्वारा शुरू की गई प्रक्रिया के साथ बदल देता है। यह तब होता है जब आप बस 'bash -c' echo $ 0'' – chepner

0

मैं बस यह जोड़ दूंगा कि यह कम से कम कुछ वातावरण में रनटाइम पर संभव होना चाहिए। लिनक्स पर perl में $ 0 असाइन करना पीएस में दिखाई देता है जो बदलता है। मुझे नहीं पता कि यह कैसे लागू किया जाता है, हालांकि। अगर मैं पता लगा सकता हूं, तो मैं इसे अपडेट कर दूंगा।

संपादित करें: इस पर निर्भर करता है कि यह कैसे करता है, यह गैर-तुच्छ है। मुझे संदेह है कि रनटाइम पर रास्ते में बनाया गया कोई भी आधार है लेकिन निश्चित रूप से नहीं जानता है। आप how perl does sets the process name at runtime देख सकते हैं।

5

मुझे लगता है कि आपके पास एक शेल स्क्रिप्ट है जिसे आप निष्पादित करना चाहते हैं कि स्क्रिप्ट प्रक्रिया के पास एक नया argv[0] है। उदाहरण के लिए (मैंने केवल बैश में इसका परीक्षण किया है, इसलिए मैं इसका उपयोग कर रहा हूं, लेकिन यह कहीं और काम कर सकता है)।

$ ./script arg1 
process 70637 here, first arg was arg1 
    PID TTY   TIME CMD 
70637 ttys003 0:00.00 /bin/bash ./script arg1 

तो ps खोल, /bin/bash इस मामले में पता चलता है:

#!/bin/bash 

echo "process $$ here, first arg was $1" 
ps -p $$ 

उत्पादन कुछ इस तरह हो जाएगा। अब आप अपने इंटरैक्टिव खोल के exec -a कोशिश, लेकिन एक subshell में तो तुम इंटरैक्टिव खोल दूर उड़ा नहीं है:

$ (exec -a MyScript ./script arg1) 
process 70936 here, first arg was arg1 
    PID TTY   TIME CMD 
70936 ttys008 0:00.00 /bin/bash /path/to/script arg1 

ओह, वह अभी भी दिखाई /bin/bash। क्या हुआ? exec -a ने शायद argv[0] सेट किया था, लेकिन तब बैश का एक नया उदाहरण शुरू हुआ क्योंकि ऑपरेटिंग सिस्टम आपकी स्क्रिप्ट के शीर्ष पर #!/bin/bash पढ़ता है। ठीक है, अगर हम किसी भी तरह स्क्रिप्ट के अंदर निष्पादन करते हैं तो क्या होगा? सबसे पहले, हमें यह पता लगाने का कोई तरीका चाहिए कि यह स्क्रिप्ट का "पहला" निष्पादन है, या दूसरा, exec एड इंस्टेंस, अन्यथा दूसरा उदाहरण फिर से निष्पादित होगा, और अनंत लूप में चालू होगा। इसके बाद, हमें पर निष्पादन योग्य की आवश्यकता है, ओएस को हमारे वांछित argv [0] को बदलने से रोकने के लिए शीर्ष पर #!/bin/bash लाइन वाली फ़ाइल हो। यहाँ मेरी प्रयास है:

$ cat ./script 
#!/bin/bash 

__second_instance="__second_instance_$$" 
[[ -z ${!__second_instance} ]] && { 
    declare -x "__second_instance_$$=true" 
    exec -a MyScript "$SHELL" "$0" "[email protected]" 
} 

echo "process $$ here, first arg was $1" 
ps -p $$ 

this answer के लिए धन्यवाद, वातावरण चर __second_instance_$$ के लिए मैं पहली बार परीक्षण, पीआईडी ​​(जो exec के माध्यम से परिवर्तन नहीं करता है) के आधार पर इतना है कि यह इस तकनीक का इस्तेमाल अन्य लिपियों के साथ भिड़ना नहीं होंगे। यदि यह खाली है, तो मुझे लगता है कि यह पहला उदाहरण है, और मैं उस पर्यावरण चर निर्यात करता हूं, फिर निष्पादित करता हूं। लेकिन, महत्वपूर्ण बात यह है कि, मैं इस स्क्रिप्ट को निष्पादित नहीं करता हूं, लेकिन मैं इस स्क्रिप्ट ($0) के साथ अन्य तर्कों के साथ-साथ ([email protected]) के साथ गुजरने के लिए सीधे शैल बाइनरी निष्पादित करता हूं। पर्यावरण चर एक हैक का एक छोटा सा है।

$ ./script arg1 
process 71143 here, first arg was arg1 
    PID TTY   TIME CMD 
71143 ttys008 0:00.01 MyScript ./script arg1 

यह लगभग नहीं है:

अब उत्पादन इस है।argv[0]MyScript है जैसा कि मैं चाहता हूं, लेकिन वहां अतिरिक्त अतिरिक्त ./script है जो सीधे खोल को निष्पादित करने का परिणाम है (ओएस के #! प्रसंस्करण के माध्यम से)। दुर्भाग्यवश, मुझे नहीं पता कि इससे बेहतर कैसे प्राप्त करें।

ARGV0=emacs nethack 
9
बस रिकार्ड के लिए

है, भले ही यह वास्तव में मूल पोस्टर के सवाल का जवाब नहीं है, यह zsh से कोई लेना देना तुच्छ कुछ है।

आप स्क्रिप्ट अपने आप में यह कर सकते हैं ...

cp /bin/bash ./new-name 
PATH=$PATH:. 
exec new-name $0 

आप नाटक करने के लिए आप एक खोल स्क्रिप्ट आप स्क्रिप्ट ही शांत या यहाँ तक कि कुछ "" करने के लिए नाम बदल सकते हैं एक भी नहीं हैं (कोशिश कर रहे हैं अंतरिक्ष) तो

exec new-name " " 

बैश अपनी स्क्रिप्ट निष्पादित और सिर्फ new-name रूप ps सूची में प्रकट होगा।

ठीक तो एक स्क्रिप्ट "को"

असल में, नाम

bash script 

नाम बदलने बैश बदल सकते हैं और स्क्रिप्ट नाम बदलने के लिए एक बहुत बुरा विचार :) है।

यदि आप चिंतित हैं, श्री मैकडूम के रूप में। जाहिरा तौर पर, एक नए नाम से एक बाइनरी (जो पूरी तरह से सुरक्षित है) की प्रति बनाने के बारे में भी एक सिमलिंक

ln -s /bin/bash ./MyFunkyName 
./MyFunkyName 

इस तरह बना सकते हैं, सिमलिंक क्या ps सूची में दिखाई देता है। (फिर से PATH = $ PATH का उपयोग करें: यदि आप नहीं चाहते हैं ./)

0

कॉपी एक अलग नाम करने के लिए बैश निष्पादन:

+0

टाइप करते हैं, मुझे उम्मीद है कि कोई भी नया शब्द सचमुच बैश का नाम बदलता है और स्क्रिप्ट का नाम बदलता है। यह मुझे यकीन है कि कई सारी चीजें तोड़ देंगे! – mcdoomington

+0

:) यह "** ** एक अलग नाम के लिए निष्पादन योग्य बैश ** के साथ शुरू होता है।" और आदेश स्पष्ट हैं। यदि मैं एक अलग नाम के साथ एक बिन चाहता हूं, तो मैं यह बहुत कुछ करता हूं, बाइनरी के नाम को बदलने के लिए कुछ भी नहीं तोड़ता है, स्पष्ट रूप से आपको इसे/bin/bash छोड़ने की आवश्यकता है। कभी-कभी डिब्बे इस्तेमाल किए गए नाम के अनुसार अलग-अलग कार्य करते हैं, लेकिन वे सामान्य रूप से डिफ़ॉल्ट व्यवहार भी करते हैं। मैं बैश कोड को हैक करने और अपने संस्करणों को संकलित करने के बाद से बहुत कुछ करता हूं। – teknopaul

+0

हाय टेक्नोपॉल, हां (मैंने इसे पढ़ा और समझ लिया), लेकिन आप जानते हैं कि एसओ चंपों को कैसे कॉपी और पेस्ट करें - शायद यह कहने के लिए जवाब संपादित करें कि आप किसी अन्य नाम पर बैश की प्रतिलिपि क्यों बनाते हैं;) अगर कोई सही बैश बदलता है ...अगर वे रीबूट करते हैं और संकेत नहीं देते हैं तो वे सवारी के लिए होंगे। – mcdoomington

संबंधित मुद्दे