/ बिन / श: धक्का: नहीं मिला


99

मैं एक फ़ाइल के अंदर निम्नलिखित कर रहा हूँ

pushd %dir_name%

और मुझे निम्नलिखित त्रुटि मिलती है

/bin/sh : pushd : not found

क्या कोई मुझे बता सकता है कि यह त्रुटि क्यों दिखाई दे रही है? मैंने अपना $ PATH वैरिएबल चेक किया और इसमें / बिन शामिल है इसलिए मुझे नहीं लगता कि इससे कोई समस्या हो रही है।


यह श के बारे में शिकायत नहीं कर रहा है, यह शिकायत कर रहा है यह नहीं मिल सकता है pushd। क्या आपके अंदर धक्का है $PATH?
कोनरक

7
Konerak: pushd का कोई मतलब नहीं है कि यह पथ में है, यह बैश बिलिन है। समस्या एक बैश बिलियन की हो रही है, न कि पोसिक्स शेल की।
जान हुदेक

आपने कोड क्यों संपादित किया?
Jan Hudec

1
सबसे अधिक संभावना है कि आपका डिस्ट्रो / बिन / बैश के बजाय / बिन / श / से / बिन / ऐश चला गया है। जब तक आप विशेष रूप से अपने मेक को बैश का उपयोग करने के लिए मजबूर नहीं करते हैं, तब तक यह जो भी / बिन / श का उपयोग करेगा।
stsquad

समान समस्या शेल स्क्रिप्ट में भी होगी यदि इसे bash द्वारा निष्पादित नहीं किया गया है।
व्लादिमीर Kroz

जवाबों:


113

pushdbashPOSIX- निर्दिष्ट बॉर्न शेल के लिए एक वृद्धि है। pushdआसानी से एक आदेश के रूप में लागू नहीं किया जा सकता है, क्योंकि वर्तमान कामकाजी निर्देशिका एक प्रक्रिया की एक विशेषता है जिसे बाल प्रक्रियाओं द्वारा नहीं बदला जा सकता है। (एक काल्पनिक pushdकमांड कॉल कर सकता है chdir(2)और फिर एक नया शेल शुरू कर सकता है , लेकिन ... यह बहुत उपयोगी नहीं होगा।) pushdबिलकुल वैसे ही शेल बनाया गया है cd

इसलिए, या तो #!/bin/bashवर्तमान स्क्रिप्ट को एक चर में चालू या संग्रहीत करने के लिए अपनी स्क्रिप्ट को बदलें , अपना काम करें, फिर वापस बदलें। निर्भर करता है कि आप एक शेल स्क्रिप्ट चाहते हैं जो बहुत कम सिस्टम (जैसे, डेबियन बिल्ड सर्वर) पर काम करती है या यदि आप ठीक हैं तो आपको हमेशा आवश्यकता होती है bash


17
ओपी का कहना है कि यह मेक से चला है। तो यह SHELL = /bin/bashस्क्रिप्ट शुरू करने के बजाय सेट करना होगा #!/bin/bash
Jan Hudec

@ जान हुडेक, आह! अच्छी पकड़। धन्यवाद।
१२:०२

लेकिन SHELL सेट करने से इस मामले में काम नहीं होगा, test1मेरे जवाब में देखें , stackoverflow.com/questions/5193048/bin-sh-pushd-not-found/…
hlovdal

1
@ क्लोवल्ड: नहीं, वास्तव में यह पर्याप्त नहीं होगा।
जान हुदेक

1
सुनिश्चित करें कि #!/bin/bashफ़ाइल की पहली पंक्ति है।
माइकल कोल

29

जोड़ना

शेल: = / बिन / बैश

आपके मेकफाइल के शीर्ष पर मैंने इसे एक और प्रश्न पर पाया है कि मैं मेकफाइल लक्ष्यों में बैश सिंटैक्स का उपयोग कैसे कर सकता हूं?


हाँ धन्यवाद। हालांकि, यह वास्तव में श (या इसके कुछ कार्यान्वयन) पर लाल सलाम को हरा करने के लिए डिफ़ॉल्ट है। यह मेरा मुद्दा था।
lzap

18

इसके लिए एक वर्कअराउंड एक वैरिएबल होगा जो वर्तमान वर्किंग डायरेक्टरी को प्राप्त करता है। फिर आप जो भी कर सकते हैं, उसमें से सीडी निकाल सकते हैं, फिर जब आपको इसकी आवश्यकता होती है, तो आप वापस सीडी में डाल सकते हैं।

अर्थात

oldpath = `pwd`
# जो भी आपकी स्क्रिप्ट करता है
...
...
...
# आप उस dir पर वापस जाएं जिसे आप पुश करना चाहते थे
सीडी $ पुरानेपथ

6
यदि cdआप चाहते हैं और उसके बाद की निर्देशिका में भी कर सकते हैं cd -, $oldpathतो उस चर का उपयोग करने की कोई आवश्यकता नहीं है यदि आप cdइनबेटवर्क का उपयोग नहीं करेंगे । इस बारे pushdमें दिलचस्प बात यह है कि हर बार जब आप इसका उपयोग करते हैं तो आप किसी निर्देशिका को स्टैक में धकेलते हैं, और बाद में आप नवीनतम का उपयोग करके वापस जा सकते हैं popd, इसलिए इसका उपयोग यह समझ में आता है जब आप एक से अधिक निर्देशिकाओं में जा रहे हैं और चाहते हैं एक निश्चित रास्ता वापस।
एनरिको

1
यदि यह सिर्फ एक oneliner है, तो निम्नलिखित भी काम कर सकता है(cd /new_path ; command )
barney765

10

इसका कारण यह है कि पुश बश में एक अंतर्निहित कार्य है। तो यह PATH चर से संबंधित नहीं है और यह / bin / sh (जो कि डिफ़ॉल्ट रूप से मेक द्वारा उपयोग किया जाता है) द्वारा समर्थित नहीं है। आप इसे बदलकर सेट कर सकते हैं (हालांकि यह सीधे काम नहीं करेगा (test1))।

आप इसके बजाय सभी कमांड चला सकते हैं bash -c "..."। यह कमांड्स बनायेगा, जिसमें पुश / पोप शामिल हैं, जो बैश वातावरण में चलते हैं (test2)।

SHELL = /bin/bash

test1:
        @echo before
        @pwd
        @pushd /tmp
        @echo in /tmp
        @pwd
        @popd
        @echo after
        @pwd

test2:
        @/bin/bash -c "echo before;\
        pwd; \
        pushd /tmp; \
        echo in /tmp; \
        pwd; \
        popd; \
        echo after; \
        pwd;"

जब test1 बना रहे हैं और test2 बनाते हैं तो यह निम्नलिखित देता है:

prompt>make test1
before
/download/2011/03_mar
make: pushd: Command not found
make: *** [test1] Error 127
prompt>make test2
before
/download/2011/03_mar
/tmp /download/2011/03_mar
in /tmp
/tmp
/download/2011/03_mar
after
/download/2011/03_mar
prompt>

टेस्ट 1 के लिए, भले ही बैश को शेल के रूप में उपयोग किया जाता है, नियम में प्रत्येक कमांड / लाइन स्वयं द्वारा संचालित की जाती है, इसलिए पुशड कमांड पॉप से ​​अलग शेल में चलाया जाता है।


1
@ जान हुडेक, मुझे लगता है tcsh(और शायद csh?) उनके साथ शीघ्र खत्म करते हैं > :$ tcsh haig:/> exit $ csh haig:/> exit $
सरनॉल्ड

मेरा करता है :) वास्तव में मेरा PS1 है, (\u) \h:\w>लेकिन मैंने अभी जवाब के लिए इसे एक सामान्य स्ट्रिंग पर ले जाया है। DOS में संकेत >डिफ़ॉल्ट ( $P$GIIRC) के साथ समाप्त हो रहा है, और मुझे यह पसंद है।
१२:

SHELL के साथ सेट करें: = साथ नहीं =
कप कप

"SHELL = / bin / bash" सेट करना मेरे लिए ठीक काम करता है, यह सुनिश्चित करने के लिए कि आपको यह कैसे काम नहीं मिला।
आइजैक फ्रीमैन

4

आपका शेल (/ बिन / श) 'पुशड' खोजने की कोशिश कर रहा है। लेकिन यह इसे नहीं पा सकता क्योंकि 'पुशड', 'पोप' और अन्य कमांड जैसे कि बैश में बनते हैं।

जैसे आप अभी कर रहे हैं, वैसे ही Sh की जगह Bash (/ bin / bash) का उपयोग करके आपको स्क्रिप्ट लॉन्च करें, और यह काम करेगा



2

अन्य प्रतिक्रियाओं से संश्लेषण: pushdबैश-विशिष्ट है और आप कर रहे हैं एक और POSIX शेल का उपयोग कर रहा है। उस हिस्से के लिए अलग शेल का उपयोग करने के लिए एक सरल वर्कअराउंड है जिसे अलग-अलग निर्देशिका की आवश्यकता है, इसलिए बस इसे बदलने का प्रयास करें:

test -z gen || mkdir -p gen \
 && ( cd $(CURRENT_DIRECTORY)/genscript > /dev/null \
 && perl genmakefile.pl \
 && mv Makefile ../gen/ ) \
 && echo "" > $(CURRENT_DIRECTORY)/gen/SvcGenLog

(मैंने एक चर विस्तार के साथ लंबे रास्ते को प्रतिस्थापित किया। मैं शायद मेकफाइल में से एक हूं और यह स्पष्ट रूप से वर्तमान निर्देशिका में फैलता है)।

चूंकि आप इसे मेक से चला रहे हैं, मैं शायद टेस्ट को मेक रूल से बदल दूंगा। केवल

gen/SvcGenLog :
    mkdir -p gen
    cd genscript > /dev/null \
     && perl genmakefile.pl \
     && mv Makefile ../gen/ \
    echo "" > gen/SvcGenLog

(वर्तमान निर्देशिका उपसर्ग को गिरा दिया; आप वैसे भी कुछ बिंदुओं पर सापेक्ष पथ का उपयोग कर रहे थे) और नियम बनाने पर निर्भर रहने के बजाय gen/SvcGenLog। यह थोड़ा अधिक पढ़े जा सकेंगे और आप उस पर निर्भर कर सकते हैं genscript/genmakefile.plभी, तो Makefileमें genअगर आप स्क्रिप्ट को संशोधित पुनर्जीवित किया जाएगा। बेशक, अगर कुछ और की सामग्री को प्रभावित करता है Makefile, तो आप नियम को उस पर भी निर्भर कर सकते हैं।


2

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


1

"एप इंस्टॉल करें बैश" चलाएं यह आपकी जरूरत की सभी चीजों को स्थापित करेगा और कमांड काम करेगा


1

यहाँ इंगित करने के लिए एक विधि है

श -> बैश

इस कमांड को टर्मिनल पर चलाएं

sudo dpkg-reconfigure dash

इसके बाद आपको देखना चाहिए

ls -l /bin/sh

पॉइंट टू / बिन / बैश (और नहीं / बिन / डैश)

संदर्भ


0

इस चाल को करना चाहिए:

( cd dirname ; pwd ); pwd

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

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