วางไข่ - ไม่พบคำสั่ง!


15

ฉันใช้ Mac OS X 10.9.4 ต่อไปนี้เป็นสคริปต์ของฉันเพื่อคัดลอกไฟล์จากเครื่องท้องถิ่นไปยังโฮสต์อื่น

#!/bin/bash
#!/usr/bin/expect

echo "I will fail if you give junk values!!"
echo " "
echo "Enter file name: "
read filePath
echo " "
echo "Where you want to copy?"
echo "Enter"
echo "1. if Host1"
echo "2. if Host2"
echo "3. if Host3"
read choice
echo " "
if [ $choice -eq "1" ]
then
  spawn scp filePath uname@host1:/usr/tmp   
  expect "password"   
  send "MyPassword\r"
  interact
elif [ $choice -eq "2" ]
then
  spawn scp filePath uname@host2:/usr/tmp   
  expect "password"   
  send "MyPassword\r"
  interact
elif [ $choice -eq "3" ]
then
  spawn scp filePath uname@host3:/usr/tmp   
  expect "password"   
  send "MyPassword\r"
  interact
else
  echo "Wrong input"
fi

เมื่อเรียกใช้สคริปต์นี้ฉันได้รับการติดตาม

./rcopy.sh: line 21: spawn: command not found
couldn't read file "password": no such file or directory
./rcopy.sh: line 23: send: command not found
./rcopy.sh: line 24: interact: command not found

ในกรณีของฉันฉันต้องการตัวบ่งชี้ EOD รอบรหัสที่คาดหวัง stackoverflow.com/questions/26125036/…
AnneTheAgile

คำตอบ:


20

สคริปต์ของคุณกำลังพยายามรวมล่ามสองตัว คุณมีทั้งและ#!/bin/bash #!/usr/bin/expectนั่นไม่ได้ผล คุณสามารถใช้หนึ่งในสองเท่านั้น ตั้งแต่bashเป็นครั้งแรกสคริปต์ของคุณจะถูกเรียกใช้เป็นสคริปต์ทุบตี

อย่างไรก็ตามภายในสคริปต์ของคุณคุณจะมีexpectคำสั่งเช่นและspawn sendเนื่องจากสคริปต์กำลังอ่านอยู่bashและไม่ได้รับexpectสิ่งนี้จึงล้มเหลว คุณอาจจะได้รับรอบนี้โดยการเขียนที่แตกต่างกันexpectสคริปต์และเรียกพวกเขาจากสคริปต์หรือโดยการแปลสิ่งที่ทั้งเพื่อbashexpect

วิธีที่ดีที่สุดและวิธีหนึ่งที่หลีกเลี่ยงวิธีปฏิบัติที่น่ากลัวที่มีรหัสผ่านของคุณเป็นข้อความธรรมดาในไฟล์ข้อความธรรมดาคือการตั้งค่า ssh แบบไม่มีรหัสผ่านแทน วิธีนี้scpจะไม่ต้องการรหัสผ่านและคุณไม่จำเป็นต้องexpect:

  1. ก่อนอื่นให้สร้างคีย์สาธารณะ ssh บนเครื่องของคุณ:

    ssh-keygen -t rsa

    คุณจะถูกถามถึงข้อความรหัสผ่านซึ่งคุณจะถูกขอให้ป้อนในครั้งแรกที่คุณเรียกใช้คำสั่ง ssh หลังจากเข้าสู่ระบบแต่ละครั้ง ซึ่งหมายความว่าสำหรับคำสั่ง ssh หรือ scp หลายคำคุณจะต้องป้อนเพียงครั้งเดียว ปล่อยให้วลีรหัสผ่านว่างเปล่าเพื่อให้เข้าถึงรหัสผ่านโดยสมบูรณ์

  2. เมื่อคุณสร้างรหัสสาธารณะของคุณให้คัดลอกไปยังคอมพิวเตอร์แต่ละเครื่องในเครือข่ายของคุณ:

    while read ip; do 
     ssh-copy-id -i ~/.ssh/id_rsa.pub user1@$ip 
    done < IPlistfile.txt

    IPlistfile.txtควรจะเป็นไฟล์ที่มีชื่อเซิร์ฟเวอร์หรือ IP ในแต่ละบรรทัด ตัวอย่างเช่น:

    host1
    host2
    host3

    เนื่องจากนี่เป็นครั้งแรกที่คุณทำเช่นนี้คุณจะต้องป้อนรหัสผ่านสำหรับแต่ละ IP ด้วยตนเอง แต่เมื่อคุณทำเสร็จแล้วคุณจะสามารถคัดลอกไฟล์ไปยังเครื่องเหล่านี้ได้ง่ายๆ

    scp file user@host1:/path/to/file
  3. ลบความคาดหวังออกจากสคริปต์ของคุณ ตอนนี้คุณสามารถเข้าถึงรหัสผ่านได้แล้วคุณสามารถใช้สคริปต์ของคุณเป็น:

    #!/bin/bash
    echo "I will fail if you give junk values!!"
    echo " "
    echo "Enter file name: "
    read filePath
    echo " "
    echo "Where you want to copy?"
    echo "Enter"
    echo "1. if Host1"
    echo "2. if Host2"
    echo "3. if Host3"
    read choice
    echo " "
    if [ $choice -eq "1" ]
    then
      scp filePath uname@host1:/usr/tmp   
    elif [ $choice -eq "2" ]
    then
      scp filePath uname@host2:/usr/tmp   
    elif [ $choice -eq "3" ]
    then
      scp filePath uname@host3:/usr/tmp   
    else
      echo "Wrong input"
    fi

1
หากคุณเปิดใช้เอเจนต์ ssh คุณจะต้องป้อนข้อความรหัสผ่านเพียงครั้งเดียวเท่านั้น มิฉะนั้นคุณจะต้องป้อนทุกครั้ง
เกล็นแจ็คแมน

5

รหัสของคุณอาจมีความกระชับมากกว่านี้:

#!/bin/bash

read -p "Enter file name: " filePath
if ! [[ -r $filePath ]]; then
    echo "cannot read $filePath"
    exit 1
fi

PS3="Where you want to copy? "
select host in host1 host2 host3; do
    if [[ -n $host ]]; then
        expect <<END
            spawn scp "$filePath" uname@$host:/usr/tmp   
            expect "password"   
            send "MyPassword\r"
            expect eof
END
        break
    fi
done

หากคุณตั้งค่าคีย์ ssh ตามที่แนะนำจะดียิ่งขึ้น:

    if [[ -n $host ]]; then
        scp "$filePath" uname@$host:/usr/tmp   
        break
    fi

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.