मैं लिनक्स शेल से करंट से अलग कार्यशील निर्देशिका के साथ एक कार्यक्रम कैसे चलाऊं?


352

लिनक्स शेल का उपयोग करते हुए , मैं वर्तमान कार्यशील निर्देशिका से अलग कार्यशील निर्देशिका के साथ एक कार्यक्रम कैसे शुरू करूं?

उदाहरण के लिए, मेरे पास एक बाइनरी फ़ाइल helloworldहै hello-world.txtजो वर्तमान निर्देशिका में फ़ाइल बनाती है ।

यह फ़ाइल निर्देशिका के अंदर है /a

वर्तमान में, मैं निर्देशिका में हूं /b। मैं अपना कार्यक्रम शुरू करना चाहता हूं ../a/helloworldऔर hello-world.txtतीसरी निर्देशिका में कहीं जाना चाहता हूं /c


5
मैंने उस कठिन तरीके की खोज की suजो किसी भी -cकमांड को चलाने से पहले आपके द्वारा निर्दिष्ट उपयोगकर्ता की होम डायरेक्टरी को कार्यशील निर्देशिका को रीसेट करता है । यह मेरे लिए बहुत मददगार था।
पैट्रिक एम

जवाबों:


561

इस तरह से कार्यक्रम को बुलाओ:

(cd /c; /a/helloworld)

कोष्ठकों के कारण एक उप-खोल पैदा होता है। यह उप-शेल इसके वर्किंग डायरेक्टरी को बदल देता है /c, फिर से निष्पादित करता helloworldहै /a। कार्यक्रम से बाहर निकलने के बाद, उप-शेल समाप्त हो जाता है, आपको मूल शेल के अपने प्रॉम्प्ट पर वापस लौटाता है, जिस निर्देशिका से आपने शुरू किया था।

त्रुटि से निपटने: निर्देशिका को बदले बिना प्रोग्राम को चलाने से बचने के लिए, जैसे कि गलत वर्तनी होने पर /c, helloworldसशर्त का निष्पादन करें :

(cd /c && /a/helloworld)

मेमोरी उपयोग को कम करना: हैलो वर्ल्ड निष्पादित करते समय सबस्क्रिप्शन वेस्ट मेमोरी से बचने के लिए, helloworldनिष्पादन के माध्यम से कॉल करें :

(cd /c && exec /a/helloworld)

[ इस उत्तर को बेहतर बनाने के लिए सुझाव देने के लिए जोश और जूलियानो का धन्यवाद !]


1
इस खोल के लिए तर्कों को पारित करने का कोई तरीका? के रूप में $ 1, और $ 2 में?
फिनिटेलिओप

2
@segfault: उपधारा में आसपास के दायरे तक पूरी पहुंच होती है।
डेविड श्मिट

लगता है जैसे यह है कि निर्देशिका में अस्थायी रूप से वैसे भी, है ना?
ढिन

1
आप $ *, $ @ या "$ @" करके सभी तर्क पारित कर सकते हैं (यदि आप दोहरे उद्धरणों का सम्मान करना चाहते हैं)
मार्सेल वाल्डेज़ ओरोज़्को

1
अगर मैं इस लाइन को /etc/rc.d/rc.local में जोड़ दूं तो यह काम करेगा?
प्रतीक पाटिल

95

करने के लिए इसी तरह के डेविड श्मिट के जवाब, प्लस जोश के सुझाव है, लेकिन एक खोल चल रही प्रक्रिया को नहीं छोड़ता:

(cd /c && exec /a/helloworld)

यह तरीका अधिक समान है कि आप आमतौर पर शेल पर कमांड कैसे चलाते हैं। व्यावहारिक अंतर को देखने के लिए, आपको ps efप्रत्येक समाधान के साथ दूसरे शेल से चलना होगा ।



25

एक विकल्प जिसके लिए एक उपधारा की आवश्यकता नहीं होती है और इसे बैश करने के लिए बनाया जाता है

(pushd SOME_PATH && run_stuff; popd)

डेमो:

$ pwd
/home/abhijit
$ pushd /tmp # directory changed
$ pwd
/tmp
$ popd
$ pwd
/home/abhijit

1
इसी तरह का सुझाव साहिल ने नीचे दिया है। कमांड फेल होने पर यह काम नहीं करता है। विचार करें pushd SOME_PATH && run_stuff && popd- अगर run_stuff विफल रहता है, तो popd निष्पादित नहीं होने वाला है।
एंटोन डेनेको

देर से उत्तर, जो बैश फ़ाइल की सेटिंग पर निर्भर करता है। बैश विफल आदेश के बाद भी कमांड निष्पादित करना जारी रख सकते हैं (&& का उपयोग करने के विपरीत), लेकिन यह सेट नहीं किया जा सकता है कि set -eफ़ाइल का उपयोग करना और फिर यह विफल हो जाएगा popd
लोरेन

8
फिर भी, मुझे लगता pushd "${SOME_PATH}" && run_stuff; popdहै कि वर्तमान उत्तर से बेहतर है, क्योंकि पुशड / पॉपड शब्दार्थ विशेष रूप से कुछ निर्देशिका में जाने और फिर मूल एक पर वापस आने की इस स्थिति के लिए डिज़ाइन किया गया था।
मार्सेल वाल्डेज़ ओरोज़्को

यह उर्फ ​​के रूप में परिभाषित कैसे काम करता है और मुझे एक पैराम को पारित करने की आवश्यकता है?
DrB

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

19
sh -c 'cd /c && ../a/helloworld'

1
निर्दिष्ट कार्य निर्देशिका में जेल के अंदर एक कमांड निष्पादित करने के लिए FreeBSD के jexec के लिए इसका इस्तेमाल किया।
मारीआन Marierný

11

मुझे हमेशा लगता है कि UNIX टूल्स को फिल्टर के रूप में लिखा जाना चाहिए, स्टड से इनपुट पढ़ें और आउटपुट को stdout में लिखें। यदि संभव हो तो आप एक विशेष फ़ाइल के बजाय टेक्स्ट फ़ाइल की सामग्री को stdout करने के लिए लिखने के लिए अपने हेलोवर्ल्ड बाइनरी को बदल सकते हैं। इस तरह आप अपनी फ़ाइल को कहीं भी लिखने के लिए शेल का उपयोग कर सकते हैं।

$ cd ~ / b

$ ~ / a / helloworld> ~ / c / helloworld.txt


6
+1 सही होने के लिए, हालाँकि उत्तर केवल परिधीय रूप से एक उत्तर है।
डेविड श्मिट

8

बस अंतिम "&&" में ";" और अगर कमांड फेल या सफल नहीं हुआ तो यह वापस आ जाएगा।

cd SOME_PATH && run_some_command ; cd -

4

एक तरीका यह है कि एक आवरण खोल स्क्रिप्ट बनाने के लिए है।

शेल स्क्रिप्ट वर्तमान निर्देशिका को / c में बदल देगी, फिर / a / helloworld चलाएगी। शेल स्क्रिप्ट से बाहर निकलने के बाद, वर्तमान निर्देशिका वापस / b पर वापस लौट जाती है।

यहां बैश शेल स्क्रिप्ट उदाहरण दिया गया है:

#!/bin/bash
cd /c
/a/helloworld

2

इसे सरल क्यों न रखें

cd SOME_PATH && run_some_command && cd -

अंतिम 'सीडी' कमांड आपको अंतिम pwd निर्देशिका में वापस ले जाएगा। यह सभी * निक्स सिस्टम पर काम करना चाहिए।


आप @mezhaka लिख रहे हैं, उस पर विचार करना चाहिए था :)
साहिल

1
चेतावनी: यदि run_some_commandविफल रहता है, cd -तो निष्पादित नहीं किया जाएगा।
स्टारबिम्रेनबोलाब्स

1

यदि आप हमेशा यह चाहते हैं कि जब आप फ़ाइल लिखते हैं, तो एक पूर्ण पथ का उपयोग करें।


0

यदि आप इसे अपने कार्यक्रम के अंदर करना चाहते हैं तो मैं कुछ ऐसा करूंगा:

#include <unistd.h>
int main()
{
  if(chdir("/c") < 0 )  
  {
     printf("Failed\n");
     return -1 ;
  }

  // rest of your program...

}

वह एक शेल-स्क्रिप्ट में ऐसा करना चाहता है, और सी में नहीं। इसके अलावा, यह बाइनरी फ़ाइल को उपप्रकार करने के लिए एक भयानक विचार होगा।

-1

वर्तमान निर्देशिका से कमांड को निष्पादित करने के लिए स्क्रिप्ट निर्देशिका के लिए पूर्ण पथ प्रदान करते हैं

/root/server/user/home/bin/script.sh

1
यह कार्य निर्देशिका को बिल्कुल नहीं बदलता है - मुझे लगता है कि आप जो पूछा गया था, उससे अलग प्रश्न का उत्तर दे रहे हैं।
टोबी स्पाइट

आपके द्वारा दिए गए प्रश्न का उत्तर खोजने के लिए यहां आया था। धन्यवाद! lol
kfrncs
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.