2011-04-07 15 views
10

के भीतर अपेक्षा के साथ सहायता करें मैंने टर्मिनल सर्वर और स्पष्ट लाइनों से कनेक्ट करने के लिए अपेक्षा के साथ एक बैश स्क्रिप्ट लिखी है। मैं जो त्रुटि प्राप्त कर रहा हूं उसे समझने में असमर्थ हूं, क्योंकि मैंने सभी ब्रेसिज़ आवश्यक हैं। मैं couldn't read file "line": no such file or directory त्रुटि को भी समझ नहीं पा रहा हूं। कृपया मदद करें।बैश स्क्रिप्ट

मेरे स्क्रिप्ट:

#!/bin/bash 
VAR=$(expect -c " 
spawn telnet 1.1.1.1 
expect { 
     "Password:" { send "password\r" ; exp_continue} 
     "Prompt>" { send "en\r" ; exp_continue} 
     "Password:" { send "password\r" ; exp_continue} 
     "Prompt#" {send "clea line 10\r" ; exp_continue} 
     "[confirm]" {send "Y\r" ; exp_continue} 
     "Prompt#" {send "clea line 11\r" ; exp_continue} 
     "[confirm]" {send "Y\r" ; exp_continue} 
     "Prompt#" {send "exit\r" } 
    } 
") 

echo $VAR 

इसका उत्पादन:

missing close-brace 
    while executing 
"expect" 
couldn't read file "line": no such file or directory 

उत्तर

20

पहले समस्या यह है कि खोल नेस्टेड दोहरे उद्धरण चिह्नों की व्याख्या नहीं करता है के रूप में आप की तरह हो सकता है। इसे ठीक करने का सबसे आसान तरीका एक्सपेक्ट प्रोग्राम को सिंगल कोट्स में रखना है। यह तब तक पर्याप्त होगा जब तक कि उम्मीद कार्यक्रम में कोई एकल उद्धरण न हो।

अगली समस्या जो आप दौड़ेंगे, यह है कि एक ही expect कमांड में सभी पैटर्न और कार्रवाइयां उन्हें समानांतर में संसाधित करती हैं। वास्तव में क्या होता है कि पहले Password: पैटर्न किसी भी समय उस स्ट्रिंग को देखता है (यानी व्यवस्थापक पासवर्ड के लिए दूसरी बार भी)। यदि दो पासवर्ड अलग होने की आवश्यकता है तो यह एक समस्या होगी। कम से कम, समान पैटर्न को expect कमांड में जाने की आवश्यकता होगी ताकि उन्हें अनुक्रमिक रूप से निष्पादित किया जा सके। यह समस्या Prompt# पैटर्न को भी प्रभावित करती है जहां आप इसे तीन बार देखते हैं और तीन अलग-अलग प्रतिक्रियाएं भेजना चाहते हैं।

बाद में, आपको पहला स्पष्ट आदेश भेजने के बाद एक त्रुटि मिलेगी। उम्मीद है कि डबल कोट्स के अंदर स्क्वायर ब्रैकेट्स को इस तरीके से व्याख्या करें कि $() या `` (यानी कमांड प्रतिस्थापन) की व्याख्या कैसे करें। आप इस तरह एक त्रुटि देखेंगे:

invalid command name "confirm" 
    while executing 
"confirm" 
    invoked from within 
"expect { 
⋮ 

यह confirm एक Tcl के रूप में चलाने के लिए (या अपेक्षा) आदेश करने की कोशिश कर रहा है। इस व्याख्या को करने से टीसीएल को रोकने के लिए आप घुंघराले ब्रैकेट्स ({}) का उपयोग कर सकते हैं। इसके अलावा, उम्मीद है कि पैटर्न को डिफ़ॉल्ट रूप से "ग्लोब" अभिव्यक्ति के रूप में माना जाता है (यानी शैल वाइल्डकार्ड की तरह), इसलिए यदि आप पैटर्न के रूप में {[confirm]} लिखते हैं, तो भी यह सटीक स्ट्रिंग मैच के लिए उपयोग नहीं किया जाएगा (यह किसी एकल वर्ण c से मेल खाता है, o, n, f, i, r, या m)। सटीक मिलान के लिए पैटर्न को चिह्नित करने के लिए आपको -ex ध्वज का उपयोग करना होगा।

इन मुद्दों को ठीक करें, अनावश्यक के हवाले से कुछ छोड़ देते हैं और आप कुछ इस तरह से खत्म हो सकता है:

#!/bin/sh 
VAR=$(expect -c ' 
    proc abort {} { 
    puts "Timeout or EOF\n" 
    exit 1 
    } 
    spawn telnet 1.1.1.1 
    expect { 
    Password:  { send "password1\r" } 
    default   abort 
    } 
    expect { 
    Prompt>   { send "en\r"; exp_continue } 
    Password:  { send "password2\r" } 
    default   abort 
    } 
    expect { 
    Prompt#   { send "clea line 10\r"; exp_continue } 
    -ex {[confirm]} { send "Y\r" } 
    default   abort 
    } 
    expect { 
    Prompt#   { send "clea line 11\r"; exp_continue } 
    -ex {[confirm]} { send "Y\r" } 
    default   abort 
    } 
    expect { 
    Prompt#   { send "exit\r"; exp_continue } 
    timeout   abort 
    eof 
    } 
    puts "Finished OK\n" 
') 

echo "$VAR" 
+0

विस्तृत स्पष्टीकरण के लिए धन्यवाद। यह वास्तव में मेरी समस्या को हल करने में मेरी मदद करता है मैंने दो और बदलाव किए हैं जिन्हें मैं एक ही पोस्ट के अलग जवाब में बता रहा हूं। – Pkp

1

समस्या यह है कि कि उम्मीद लिपि में दोहरे उद्धरण चिह्नों की उम्मीद स्क्रिप्ट के अंत के रूप में इलाज कर रहे हैं। डबल कोट्स के साथ एकल कोट्स मिश्रण करने का प्रयास करें:

#!/bin/bash 
VAR=$(expect -c ' 
spawn telnet 1.1.1.1 
expect { 
"Password:" { send "password\r" ; exp_continue} 
"Prompt>" { send "en\r" ; exp_continue} 
"Password:" { send "password\r" ; exp_continue} 
"Prompt#" {send "clea line 10\r" ; exp_continue} 
"[confirm]" {send "Y\r" ; exp_continue} 
"Prompt#" {send "clea line 11\r" ; exp_continue} 
"[confirm]" {send "Y\r" ; exp_continue} 
"Prompt#" {send "exit\r" } 
} 
') 
1

@ डेविड का सही उत्तर है।

आपकी अपेक्षा स्क्रिप्ट शैली के बारे में एक टिप्पणी: आपकी उम्मीद/प्रेषण आदेश रैखिक हैं, इसलिए ऐसा लगता है कि एक उम्मीद ब्लॉक और exp_continue कथन का एक गुच्छा है। इसे और अधिक इस लिखने के लिए सीधा होगा:

VAR=$(expect -c ' 
    spawn telnet 1.1.1.1 
    expect "Password:" 
    send "password\r" 
    expect "Prompt>" 
    send "en\r" 
    expect "Password:" 
    send "password\r" 
    expect "Prompt#" 
    send "clea line 10\r" 
    expect "[confirm]" 
    send "Y\r" 
    expect "Prompt#" 
    send "clea line 11\r" 
    expect "[confirm]" 
    send "Y\r" 
    expect "Prompt#" 
    send "exit\r" 
    expect eof 
') 
3

@Chris: मैं परिवर्तन आप सुझाव शामिल किया और मेरे कोड अब काम कर रहा है।

1] एकल उद्धरण जो आप का उल्लेख पैरामीटर प्रतिस्थापन से बचाता है:

हालांकि मैं दो और अधिक परिवर्तन नीचे वर्णित करना था। उदाहरण के लिए मैं 1.1.1.1 के स्थान पर $IP नहीं लिख सकता। इसलिए इस के आसपास जाने के लिए मैंने एकल उद्धरण हटा दिए और डबल कोट्स के साथ बदल दिया। जैसा कि आपने बताया है कि नेस्टेड डबल्स उद्धरणों का अर्थ बैश द्वारा नहीं किया गया है जो सत्य है। इसलिए मैं

send \"password1\r\" 

कि दोहरे उद्धरण चिह्नों के अंदर से पहले बैकस्लैश जोड़ रहा है, अंदर दोहरे उद्धरण चिह्नों दुबारा लिखा। यह पैरामीटर प्रतिस्थापन की समस्या को सुधारता है।

2] एक ही उम्मीद कमांड के भीतर दो/तीन कार्यों को रखने के बाद भी, जैसा कि वे समानांतर में चलते हैं, मुझे समस्याओं का सामना करना पड़ता है। तो अपना सुझाव लेते हुए मैंने प्रत्येक कार्रवाई को अलग उम्मीद कमांड में रखा। कुछ

expect { 
    Prompt>   { send "en\r"; exp_continue } 
} 
expect { 
    Password:  { send "password2\r" } 
} 
संबंधित मुद्दे