शेल स्क्रिप्ट - अप्रत्याशित टोकन के पास सिंटैक्स त्रुटि `और’


15

निम्नलिखित शेल स्क्रिप्ट के साथ, मुझे त्रुटियाँ क्यों मिल रही हैं

syntax error near unexpected token `else'

शैल लिपि

echo "please enter username"
read user_name
echo "please enter password"
read -s pass
echo ${ORACLE_SID}
SID=${ORACLE_SID}
if ["${ORACLE_SID}" != 'Test'] then
sqlplus -s -l $USER_NAME/$PASS@$SID <<EOF
copy from scott/tiger@orcl insert EMP using select * from EMP
exit
EOF
else
echo "Cannot copy"
fi


आप लाइन "से कॉपी करें ...." को संपादित करना चाह सकते हैं क्योंकि यह वर्तमान में ऐसा कुछ दिखा सकता है जिसे आप दिखाना नहीं चाहते हैं। (हालांकि, मुझे आशा है कि वे पहले से ही संशोधित इन्फोस हैं, क्योंकि वे वास्तव में खराब सुरक्षा के अनुसार होंगे)
ओलिवियर डुलैक

1
@OlivierDulac यदि आप उस पंक्ति में उपयोगकर्ता नाम और पासवर्ड का उल्लेख कर रहे हैं, तो उन सभी Oracle डेटाबेस उपयोगकर्ताओं के लिए जाना जाता है। यह ओरेकल डेटाबेस की शुरुआत के बाद से आम और अच्छी तरह से जाना जाता है।
जकॉब

@OlivierDulac आपका स्वागत है, इस dba-oracle.com/t_scott_tiger.htm के
Jåcob

जवाबों:


26

आपको ifइस तरह की शर्त को समाप्त करना होगा:

if [ "${ORACLE_SID}" != 'Test' ]; then

या इस तरह:

if [ "${ORACLE_SID}" != 'Test' ]
then

नोट: आपको [पहले और बाद में भी स्पेस देना होगा ]

;या लाइनब्रेक का कारण यह है कि ifस्टेटमेंट का हिस्सा केवल एक कमांड है। सटीक होने के लिए किसी भी लंबाई का कोई भी आदेश। शेल उस कमांड को निष्पादित करता है, कमांड के निकास की स्थिति की जांच करता है, और फिर यह तय करता है कि thenभाग या भाग को निष्पादित करना है या नहीं else

क्योंकि कमांड किसी भी लम्बाई की हो सकती है, हालत भाग के अंत को चिह्नित करने के लिए एक मार्कर की आवश्यकता होती है। वह है ;या न्यूलाइन, उसके बाद then

बाद के रिक्त स्थान [का कारण [है क्योंकि एक कमांड है। आमतौर पर शेल का एक बिलिन। शेल [शेष ]अंतिम पैरामीटर के रूप में सहित मापदंडों के रूप में कमांड को निष्पादित करता है । यदि आप [शेल नहीं डालते हैं तो शेल [whateverकमांड के रूप में निष्पादित करने का प्रयास करेगा और विफल हो जाएगा।

इससे पहले अंतरिक्ष के लिए कारण ]समान है। क्योंकि अन्यथा इसे स्वयं के एक पैरामीटर के रूप में मान्यता नहीं दी जाएगी।


यह उस जगह पर था, हालाँकि अब मुझे test.sh: line 6: [: missing
जेकब

@lesmana। पहले गलत उत्तर देने का एक अच्छा तरीका है, फिर किसी अन्य को सही उत्तर प्रदान करने से पहले संपादन करते रहना चाहिए। कृपया पहली बार सही उत्तर देने का प्रयास करें।
वैलेंटाइन बजरमी

1
मैं अपने पहले उत्तर को गलत नहीं मानता। वास्तव में, यह "ऑन स्पॉट" था। यह सिर्फ सवाल में सभी समस्याओं का हल नहीं था ।
lesmana

if है यह एक साधारण आदेश नहीं है, वाक्य रचना। यह एक आरक्षित शब्द है। कई अन्य प्रोग्रामिंग भाषाओं के विपरीत, शेल आरक्षित शब्दों को हर जगह नहीं पहचानता है, केवल जब वे एक कमांड का पहला शब्द होता है (कुछ सूक्ष्मताओं के साथ)।
गाइल्स का SO- बुराई पर रोक '22

स्पष्टीकरण के लिए धन्यवाद। मुझे पता है कि ifवाक्य रचना है। मैं संवाद करने की कोशिश कर रहा था कि ifसिंटैक्स द्वारा किसी निश्चित रूप में स्थिति का हिस्सा विवश नहीं है। मैंने पाठ संपादित किया है। मुझे उम्मीद है कि अब यह स्पष्ट है।
lesmana

5

आप आसानी से शेलचेक ऑनलाइन (एक स्टैंडअलोन टूल के रूप में भी उपलब्ध) का उपयोग करके अपनी शेल स्क्रिप्ट की जांच कर सकते हैं ।

इस मामले में, यह कहना होगा कि अगर बयान रिक्त स्थान, के बाद की जरूरत है [और इससे पहले कि ], और है कि आप एक की जरूरत है ;इससे पहले कि (या एक नई पंक्ति) thenएक ही लाइन पर।

जब आपने यह तय कर लिया है, तो यह आपको बताएगा कि USER_NAMEइसका उपयोग किसी भी चीज़ के लिए शुरू किए बिना किया जाता है। इसका कारण यह है कि आपके पास एक user_nameचर (मामला मायने रखता है) भी है। उसी के लिए सच है PASSऔर pass

यह आपको मैन्ग्लिंग से read -rरोकने के लिए उपयोग करने के लिए भी कहता है (उदाहरण के लिए, पासवर्ड के लिए महत्वपूर्ण हो सकता है), और यह कि जब आप शेल को गलती से फ़ाइल नाम ग्लोबिंग और वर्ड स्प्लिटिंग करने से रोकने के लिए कॉल करते समय चर को दोगुना कर दें (फिर यह महत्वपूर्ण है अगर पासवर्ड, उदाहरण के लिए, फ़ाइल ग्लोबिंग वर्ण जैसे , या रिक्त स्थान शामिल हैं)।read\sqlplus*

कोड को इंडेंट करना इसे और अधिक पठनीय बना देगा:

#!/bin/bash

read -r -p 'please enter username: ' user_name
IFS= read -rs -p 'please enter password: ' pass

printf 'ORACLE_SID = %s\n' "$ORACLE_SID"
sid=$ORACLE_SID

if [ "$sid" = 'Test' ]; then
    echo 'Cannot copy' >&2
    exit 1
fi

sqlplus -s -l "$user_name/$pass@$sid" <<'SQL_END'
copy from scott/tiger@orcl insert EMP using select * from EMP
exit
SQL_END

यहां मैंने IFSपासवर्ड पढ़ने के लिए खाली स्ट्रिंग पर अस्थायी रूप से सेटिंग करके अग्रणी या अनुगामी अंतरिक्ष वर्णों के साथ पासवर्ड का उपयोग करना संभव बना दिया है read

अगर $ORACLE_SID/ $sidहै तो जमानत देने के लिए तर्क को भी बदल दिया गया था Test। यह एक ifशाखा में स्क्रिप्ट का मुख्य परिचालन हिस्सा होने से बचता है ।


ध्यान दें कि if ([ x = x ]) then (echo yes) fiयह भी काम करता है।
स्टीफन चेज़लस

@ स्टीफनचैलेजेलस आह, हाँ। और वह दिलचस्प प्रपत्र एक कार्यक्रम पैदा खोल कोड की दृष्टि हो सकता है लेकिन यह कैसे एक आम तौर पर लिखते हैं नहीं है ifके साथ बयान [ ... ]... :-)
Kusalananda

2

जब shआप चाहते हैं लेखन

if [ "$ORACLE_SID" != "Test" ]
then
  ...
fi

लिखते समय bash

if [[ "$ORACLE_SID" != "Test" ]]
then
  ...
fi

कृपया रिक्त स्थान का ध्यान रखें। [[पहले ऑपरेटर के बीच एक स्थान होना चाहिए ।

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