sinh sản - lệnh không tìm thấy!


15

Tôi đang sử dụng Mac OS X 10.9.4, sau đây là tập lệnh của tôi để sao chép các tệp từ máy cục bộ sang máy chủ khác

#!/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

Khi chạy tập lệnh này, tôi đang theo dõi

./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

Trong trường hợp của tôi, tôi cần các dấu EOD xung quanh mã mong đợi. stackoverflow.com/questions/26125036/
Mạnh

Câu trả lời:


20

Kịch bản của bạn đang cố gắng kết hợp hai phiên dịch viên. Bạn có cả hai #!/bin/bash#!/usr/bin/expect. Điều đó sẽ không làm việc. Bạn chỉ có thể sử dụng một trong hai. Kể từ bashlần đầu tiên, tập lệnh của bạn đang được chạy dưới dạng tập lệnh bash.

Tuy nhiên, trong tập lệnh của bạn, bạn có expectcác lệnh như spawnsend. Vì kịch bản đang được đọc bởi bashvà không phải bởi expect, điều này thất bại. Bạn có thể khắc phục điều này bằng cách viết các expecttập lệnh khác nhau và gọi chúng từ bashtập lệnh của bạn hoặc bằng cách dịch toàn bộ nội dung sang expect.

Mặc dù vậy, cách tốt nhất và một cách tránh thực tiễn khủng khiếp là có mật khẩu của bạn ở dạng văn bản đơn giản trong một tệp văn bản đơn giản, là thiết lập ssh không mật khẩu thay thế. Theo cách đó, scpsẽ không cần mật khẩu và bạn không cần expect:

  1. Đầu tiên, tạo khóa ssh công khai trên máy của bạn:

    ssh-keygen -t rsa

    Bạn sẽ được yêu cầu nhập cụm mật khẩu mà bạn sẽ được yêu cầu nhập lần đầu tiên khi bạn chạy bất kỳ lệnh ssh nào sau mỗi lần đăng nhập. Điều này có nghĩa là đối với nhiều lệnh ssh hoặc scp, bạn sẽ chỉ phải nhập nó một lần. Để trống cụm mật khẩu để truy cập hoàn toàn không có mật khẩu.

  2. Khi bạn đã tạo khóa công khai của mình, hãy sao chép nó vào từng máy tính trong mạng của bạn:

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

    Các IPlistfile.txtphải là một tập tin chứa tên của máy chủ hoặc IP trên mỗi dòng. Ví dụ:

    host1
    host2
    host3

    Vì đây là lần đầu tiên bạn thực hiện việc này, bạn sẽ phải nhập mật khẩu thủ công cho từng IP nhưng sau khi thực hiện xong, bạn sẽ có thể sao chép tệp vào bất kỳ máy nào trong số này một cách đơn giản:

    scp file user@host1:/path/to/file
  3. Loại bỏ sự mong đợi từ kịch bản của bạn. Bây giờ bạn có quyền truy cập không mật khẩu, bạn có thể sử dụng tập lệnh của mình dưới dạng:

    #!/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
Nếu bạn khởi chạy một tác nhân ssh, bạn sẽ chỉ phải nhập cụm mật khẩu một lần. Nếu không, bạn sẽ cần phải nhập nó mỗi lần.
glenn jackman

5

Mã của bạn có thể ngắn gọn hơn rất nhiều:

#!/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

Nếu bạn thiết lập các phím ssh như được đề xuất, nó thậm chí còn tốt hơn:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.