बैश: खराब प्रतिस्थापन


148
#!/bin/bash

jobname="job_201312161447_0003"
jobname_pre=${jobname:0:16}
jobname_post=${jobname:17}

यह बैश स्क्रिप्ट मुझे उबंटू पर बैड प्रतिस्थापन प्रतिस्थापन प्रदान करती है । किसी भी तरह की सहायता की हम सराहना करेंगे।


यह मेरे लिए ठीक काम कर रहा है। आप क्या खत्म करने की कोशिश कर रहे हैं?
फेडोरक्वी 'SO रोकना नुकसानदेह'

मैं jobname को दो में विभाजित करने का प्रयास कर रहा हूं: job_201312161447 और 0003। यह त्रुटि केवल तभी दे रहा है जब मैं इसे ubuntu पर चलाने की कोशिश कर रहा हूं।
अरिंदम चौधरी

मम्म अजीब सी। यदि आप उपयोग करते हैं तो क्या होगा cut? cut -d_ -f1,2 <<< "$jobname"और cut -d_ -f3 <<< "$jobname"इसे बनाओ
फेडोरक्वी 'एसओ स्टॉप हॉर्मिंग' डिक

धन्यवाद। लेकिन क्यों jobname_pre = $ {jobname: 0: 16} ने त्रुटि दी
अरिंदम चौधरी

1
@ यदि आप सही हैं, तो मैं देखता हूं कि यदि आप sh script.shइसे "खराब प्रतिस्थापन" त्रुटि प्राप्त करते हैं।
फेडोरक्वी 'SO

जवाबों:


200

/bin/shUbuntu के तहत डिफ़ॉल्ट शेल ( ) dash, को इंगित करता है , नहीं bash

me@pc:~$ readlink -f $(which sh)
/bin/dash

इसलिए यदि आप chmod +x your_script_file.shऔर फिर इसे चलाते हैं ./your_script_file.sh, या यदि आप इसे चलाते हैं bash your_script_file.sh, तो यह ठीक काम करना चाहिए।

इसे चलाने से sh your_script_file.shकाम नहीं चलेगा क्योंकि हैशबैंग लाइन को नजरअंदाज कर दिया जाएगा और स्क्रिप्ट की व्याख्या की जाएगी dash, जो उस स्ट्रिंग प्रतिस्थापन सिंटैक्स का समर्थन नहीं करता है।


2
वह उपयोग कर रहा है /bin/bashतो आपका जवाब फिट नहीं है ?! तुम कहाँ पढ़ रहे हो वह उपयोग कर रहा है /bin/shया sh script.sh?
डैनियल डब्ल्यू।

4
@DanFromGermany क्योंकि वह त्रुटि का एकमात्र कारण है, अर्थात वह स्क्रिप्ट को इस तरह से चला रहा है कि वह हैशबैंग पर विचार नहीं करता है, और यह बैश वाक्य रचना किसी अन्य शेल (शायद डैश) द्वारा समर्थित नहीं है। प्रश्नों में हमेशा सभी आवश्यक विवरण नहीं होते हैं, और हमें डॉट्स में शामिल होना चाहिए ... वैसे भी मेरे उत्तर को अस्वीकार करने के लिए स्वतंत्र हैं।
वन्नी तोतारो

2
मुझे नीचा दिखाने की जरूरत नहीं है। मेरे पास एक ही त्रुटि संदेश है bad substitutionऔर मैं सिर्फ जानकारी इकट्ठा करने की कोशिश कर रहा हूं लेकिन यह सवाल मदद नहीं करता है क्योंकि इसमें बहुत कम जानकारी है।
डैनियल डब्ल्यू।

2
@DanFromGermany आप अपने स्वयं के प्रश्न पोस्ट करने की कोशिश कर सकते हैं, शायद यह वास्तव में एक ही समस्या नहीं है।
वन्नी तोतारो

69

मुझे भी यही समस्या थी। सुनिश्चित करें कि आपकी स्क्रिप्ट के पास नहीं है

#!/bin/sh 

आपकी स्क्रिप्ट के शीर्ष पर। इसके बजाय, आपको जोड़ना चाहिए

#!/bin/bash

5
मैंने उपयोग किया #!bin/bashऔर sh script.sh, इसने मुझे अभी भी त्रुटि संदेश दिया। फिर ./script.shकाम करता है।
Whyisyoung

यदि आपकी फ़ाइल शीर्ष पर एक शेबंग याद #!/bin/bashकर रही है तो खराब प्रतिस्थापन को भी ठीक कर देगी ।
जेमी

1
@whyisyoung आपके चर को उसके नाम में एक डॉट (।) हो सकता है। यह बुरा विकल्प देता है। त्रुटि।
user13107

4
@whyisyoung #!लाइन का उपयोग केवल तभी किया जाता है जब आप अपनी स्क्रिप्ट को सीधे निष्पादित करते हैं। यदि आप sh script.shलाइन का उपयोग करते हैं तो पूरी तरह से नजरअंदाज कर दिया जाता है।
bfontaine

35

यहां पहुंचने वाले अन्य लोगों के लिए, यह सटीक संदेश कमांड के लिए एनवी चर सिंटैक्स का उपयोग करते समय भी दिखाई देगा, उदाहरण ${which sh}के लिए सही के बजाय$(which sh)


21

आपकी स्क्रिप्ट सिंटैक्स मान्य बैश और अच्छी है।

विफलता के संभावित कारण:

  1. आपका bashवास्तव में बैश नहीं है, लेकिन kshया कुछ अन्य शेल जो बैश के पैरामीटर प्रतिस्थापन को नहीं समझते हैं। क्योंकि आपकी स्क्रिप्ट ठीक दिखती है और बैश के साथ काम करती है। करो ls -l /bin/bashऔर जांचें यह वास्तव में बैश है और किसी अन्य शेल से सहानुभूति से जुड़ा नहीं है।

  2. यदि आपके पास अपने सिस्टम पर बैश है, तो आप अपनी स्क्रिप्ट को गलत तरीके से निष्पादित कर सकते हैं जैसे: ksh script.shया sh script.sh(और आपका डिफ़ॉल्ट शेल बैश नहीं है)। चूंकि आपके पास उचित शेबंग है, अगर आपके पास बैश है ./script.shया bash ./script.shठीक होना चाहिए।


7
मुझे आश्चर्य होगा कि क्या /bin/bash(नहीं /bin/sh) कभी एक अलग शेल से जुड़ा था।
चेपनर

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

7

स्पष्ट रूप से निष्पादन योग्य के रूप में निष्पादित करने के बजाय बैश कमांड का उपयोग करके स्क्रिप्ट चलाने का प्रयास करें।


3
अच्छा था। यह उपयोग करके sh scriptऔर अधिक स्पष्ट बनाने के लिए कुछ नमूना आउटपुट जोड़ने में मददगार होगा bash script... मेरा सुझाव :)
फेडोरक्वि 'एसओ

4

इसके अलावा, सुनिश्चित करें कि आपके पास अपनी स्क्रिप्ट की पहली पंक्ति के लिए एक खाली स्ट्रिंग नहीं है।

यानी सुनिश्चित करें कि #!/bin/bashआपकी स्क्रिप्ट की पहली पंक्ति है।


3

आपके उदाहरण के लिए प्रासंगिक नहीं है, लेकिन आप Bad substitutionकिसी भी प्रतिस्थापन सिंटैक्स के लिए भी बैश में त्रुटि प्राप्त कर सकते हैं जिसे बैश पहचान नहीं पाता है। यह हो सकता है:

  • आवारा व्हॉट्सएप। उदाहरण के लिएbash -c '${x }'
  • एक लेखन त्रुटि। उदाहरण के लिएbash -c '${x;-}'
  • एक सुविधा जिसे बाद के बैश संस्करण में जोड़ा गया था। जैसे bash -c '${x@Q}'कि बैश 4.4 से पहले।

यदि आपके पास एक ही अभिव्यक्ति में कई प्रतिस्थापन हैं, तो बैश समस्याग्रस्त अभिव्यक्ति को इंगित करने में बहुत मददगार नहीं हो सकता है। उदाहरण के लिए:

$ bash -c '"${x } multiline string
$y"'
bash: line 1: ${x } multiline string
$y: bad substitution

2
यह पहली हिट है, Bad substitutionइसलिए मैंने सोचा कि मैं उस मामले को शामिल करूं जिसमें हम भाग गए थे। (यह @Qबैश 4.3 में एक लंबी बहु-पंक्ति अभिव्यक्ति में छिपा था।)
डैनियल दरबोस

2
यह मेरा मुद्दा था जब मैक पर बैश 3.x चल रहा था
coloradocolby

2
@Qमें जोड़ा जा रहा है के बारे में सबूतbash-4.4
x-यूरी

2

दोनों - काम या पानी का छींटा - काम, लेकिन वाक्य रचना की जरूरत है:

FILENAME=/my/complex/path/name.ext
NEWNAME=${FILENAME%ext}new

1
वह पूरी तरह से अलग ऑपरेशन है। इसके अलावा, चूंकि ओपी लो -केस वैरिएबल नामों ( pubs.opengroup.org/onlinepubs/9699919799/basedefs/… देखें) का उपयोग करके अच्छी प्रथाओं का पालन कर रहा था - अपरकेस नामों का उपयोग ओएस या शेल के अर्थ वाले चर के लिए किया जाता है; लोअरकेस नाम हैं। आवेदन के उपयोग के लिए आरक्षित), यह वैसे ही करना पसंद करता है।
चार्ल्स डफी

0

लगता है "+ x" समस्याओं का कारण बनता है:

root@raspi1:~# cat > /tmp/btest
#!/bin/bash

jobname="job_201312161447_0003"
jobname_pre=${jobname:0:16}
jobname_post=${jobname:17}
root@raspi1:~# chmod +x /tmp/btest
root@raspi1:~# /tmp/btest
root@raspi1:~# sh -x /tmp/btest
+ jobname=job_201312161447_0003
/tmp/btest: 4: /tmp/btest: Bad substitution

0

मैं बैश में घुंघराले ब्रेसिज़ के साथ एक अभिव्यक्ति में दो बार डॉलर का चिह्न जोड़ रहा था:

cp -r $PROJECT_NAME ${$PROJECT_NAME}2

के बजाय

cp -r $PROJECT_NAME ${PROJECT_NAME}2

-1

मैंने पाया है कि यह समस्या या तो चिह्नित उत्तर के कारण है या आपके पास बैश घोषणा से पहले एक पंक्ति या स्थान है

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