簡體   English   中英

使用bash腳本輸入ssh密碼,無此文件或目錄

[英]Enter ssh password using bash script, No such file or directory

我有許多使用相同密碼的服務器。 我想在所有服務器中保存相同的文件。 為此,我編寫了腳本,但無法正常工作? 這是正確的嗎? 我該怎么做?

#!/usr/bin/env bash

export HISTFILE=


IP1="1.1.1.1
2.2.2.2
3.3.3.3
4.4.4.4"

IP2="5.5.5.5
6.6.6.6
6.6.6.6
7.7.7.7"

DIR1="1
2
3
4"

DIR2="5
100
104
135"

for ip1 in $IP1
do

    sshpass -fpass1.txt scp -r root@$IP1:/attach/res* /user/path/to/$DIR1/

done

for ip2 in $IP2
do

    sshpass -fpass2.txt scp -r root@$IP2:/attach/res* /user/path/to/$DIR2/

done

結果是:

107: No such file or directory
107: No such file or directory
107: No such file or directory
107: No such file or directory
135: No such file or directory
135: No such file or directory
135: No such file or directory
135: No such file or directory

我不知道怎么可能先謝謝你

以下是一些建議:

  • 您總是可以在shell腳本中回顯line以查看發生了什么。
  • 您還可以使用set -xv來幫助調試Shell腳本。 只需將set -xv放在要調試的部分之前,然后set +xv為關閉調試即可。 您也可以使用export PS4="\\$LINENO> "在shell腳本中打印export PS4="\\$LINENO> "號。

這是使用set -xv腳本的外觀。 這是調試shell腳本的非常好的工具。 用它:

export PS4="\$LINENO: "
set -xv
for ip1 in $IP1
do
    sshpass -fpass1.txt scp -r root@$IP1:/attach/res* /user/path/to/$DIR1/
done

for ip2 in $IP2
do
    sshpass -fpass2.txt scp -r root@$IP2:/attach/res* /user/path/to/$DIR2/
done
set +xv

我只是做了sshpass命令echo語句,因為該程序無論如何都無法在我的系統上運行。 這是我的輸出與echo 這是您要執行的命令:

sshpass -fpass1.txt scp -r root@1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4:/attach/res* /user/path/to/1 2 3 4/
sshpass -fpass1.txt scp -r root@1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4:/attach/res* /user/path/to/1 2 3 4/
sshpass -fpass1.txt scp -r root@1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4:/attach/res* /user/path/to/1 2 3 4/
sshpass -fpass1.txt scp -r root@1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4:/attach/res* /user/path/to/1 2 3 4/
sshpass -fpass2.txt scp -r root@5.5.5.5 6.6.6.6 6.6.6.6 7.7.7.7:/attach/res* /user/path/to/5 100 104 135/
sshpass -fpass2.txt scp -r root@5.5.5.5 6.6.6.6 6.6.6.6 7.7.7.7:/attach/res* /user/path/to/5 100 104 135/
sshpass -fpass2.txt scp -r root@5.5.5.5 6.6.6.6 6.6.6.6 7.7.7.7:/attach/res* /user/path/to/5 100 104 135/
sshpass -fpass2.txt scp -r root@5.5.5.5 6.6.6.6 6.6.6.6 7.7.7.7:/attach/res* /user/path/to/5 100 104 135/

首先,該IP地址是錯誤的。 您會發現您似乎在循環,因為命令的執行次數是您期望的,但是您在命令IP地址中使用了錯誤的變量。 你有:

sshpass -fpass1.txt scp -r root@$IP1:/attach/res* /user/path/to/$DIR1/
                                ^^^^

並不是:

sshpass -fpass1.txt scp -r root@$ip1:/attach/res* /user/path/to/$DIR1/
                                ^^^^

請注意, $ip1是循環變量,而$IP1是包含所有IP地址的變量。 請勿使用大小寫不同的相同名稱來調用變量! 如果您給他們分別使用不同的名稱,那就更好了。 例如,用$ip_list1代替$IP1 ,用$ip代替$ip1

ip_list1="..."
for ip in $ip_list`
do
    sshpass -fpass1.txt scp -r root@$ip:/attach/res* /user/path/to/$DIR1/
done

糾正該問題,我得到:

sshpass -fpass1.txt scp -r root@1.1.1.1:/attach/res* /user/path/to/1
2
3
4/
sshpass -fpass1.txt scp -r root@2.2.2.2:/attach/res* /user/path/to/1
2
3
4/
sshpass -fpass1.txt scp -r root@3.3.3.3:/attach/res* /user/path/to/1
2
3
4/
sshpass -fpass1.txt scp -r root@4.4.4.4:/attach/res* /user/path/to/1
2
3
4/
sshpass -fpass2.txt scp -r root@5.5.5.5:/attach/res* /user/path/to/5
100
104
135/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/5
100
104
135/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/5
100
104
135/
sshpass -fpass2.txt scp -r root@7.7.7.7:/attach/res* /user/path/to/5
100
104
135/

現在看到問題了嗎? 您正在scping目錄不正確。 看起來您想將文件發送到多個目錄,並假設scp命令將以某種方式循環通過自身。

這是我的程序版本。 我添加了一個內部循環來遍歷每個IP地址的目錄:

#!/bin/bash

ip_list1="1.1.1.1   2.2.2.2   3.3.3.3    4.4.4.4" 
ip_list2="5.5.5.5   6.6.6.6   6.6.6.6    7.7.7.7" 
dir_list1="1        2         3          4" 
dir_list2="5        100       104        135" 
for ip in $ip_list1
do
    for dir in $dir_list1
    do
        echo "sshpass -fpass1.txt scp -r root@$ip:/attach/res* /user/path/to/$dir/"
    done
done

for ip in $ip_list2
do
    for dir in $dir_list2
    do
        echo "sshpass -fpass2.txt scp -r root@$ip:/attach/res* /user/path/to/$dir/"
    done
done

您不需要在多行上設置IP列表和目錄列表,因為for會在空白處破壞變量。 這既是福也是禍。 或者,如果您不小心的話,最好還是罵自己。 您必須確保沒有意外的空格。

現在的輸出更加合理:

sshpass -fpass1.txt scp -r root@1.1.1.1:/attach/res* /user/path/to/1/
sshpass -fpass1.txt scp -r root@1.1.1.1:/attach/res* /user/path/to/2/
sshpass -fpass1.txt scp -r root@1.1.1.1:/attach/res* /user/path/to/3/
sshpass -fpass1.txt scp -r root@1.1.1.1:/attach/res* /user/path/to/4/
sshpass -fpass1.txt scp -r root@2.2.2.2:/attach/res* /user/path/to/1/
sshpass -fpass1.txt scp -r root@2.2.2.2:/attach/res* /user/path/to/2/
sshpass -fpass1.txt scp -r root@2.2.2.2:/attach/res* /user/path/to/3/
sshpass -fpass1.txt scp -r root@2.2.2.2:/attach/res* /user/path/to/4/
sshpass -fpass1.txt scp -r root@3.3.3.3:/attach/res* /user/path/to/1/
sshpass -fpass1.txt scp -r root@3.3.3.3:/attach/res* /user/path/to/2/
sshpass -fpass1.txt scp -r root@3.3.3.3:/attach/res* /user/path/to/3/
sshpass -fpass1.txt scp -r root@3.3.3.3:/attach/res* /user/path/to/4/
sshpass -fpass1.txt scp -r root@4.4.4.4:/attach/res* /user/path/to/1/
sshpass -fpass1.txt scp -r root@4.4.4.4:/attach/res* /user/path/to/2/
sshpass -fpass1.txt scp -r root@4.4.4.4:/attach/res* /user/path/to/3/
sshpass -fpass1.txt scp -r root@4.4.4.4:/attach/res* /user/path/to/4/
sshpass -fpass2.txt scp -r root@5.5.5.5:/attach/res* /user/path/to/5/
sshpass -fpass2.txt scp -r root@5.5.5.5:/attach/res* /user/path/to/100/
sshpass -fpass2.txt scp -r root@5.5.5.5:/attach/res* /user/path/to/104/
sshpass -fpass2.txt scp -r root@5.5.5.5:/attach/res* /user/path/to/135/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/5/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/100/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/104/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/135/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/5/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/100/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/104/
sshpass -fpass2.txt scp -r root@6.6.6.6:/attach/res* /user/path/to/135/
sshpass -fpass2.txt scp -r root@7.7.7.7:/attach/res* /user/path/to/5/
sshpass -fpass2.txt scp -r root@7.7.7.7:/attach/res* /user/path/to/100/
sshpass -fpass2.txt scp -r root@7.7.7.7:/attach/res* /user/path/to/104/
sshpass -fpass2.txt scp -r root@7.7.7.7:/attach/res* /user/path/to/135/

刪除echo ,它現在應該可以工作了。

您似乎希望Bash一次在多行變量中循環一行,但這完全不是它的工作原理。 字符串是一個字符串,其中包含換行符的字符串仍然只是一個字符串。 您可以在未加引號的字符串中循環標記(單詞),但是沒有一種簡單的方法可以索引到相同長度的字符串中,因為您顯然想這樣做(隱式)。

您可以改用Bash數組:

IP1=( 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4 )
DIR1=( 1 2 3 4 )
for idx in 0 1 2 3; do
     sshpass -fpass1.txt scp -r root@"${IP1[$idx]}":/attach/res* /user/path/to/"${DIR1[$idx]}"
done

或者您可以使用簡單的參數列表和此處文檔:

while read ip dir; do
     sshpass -fpass1.txt scp -r root@$ip:/attach/res* /user/path/to/$dir/
done <<____HERE
    1.1.1.1  1
    2.2.2.2  2
    3.3.3.3  3
    4.4.4.4  4
____HERE

我傾向於選擇后一種方法,因為它更具可讀性和便攜性。 如果要更新列表,服務器IP和路徑將保持在一起,因此您不必跟蹤每個數組的索引(這對於包含四個元素的數組來說是微不足道的,但實際麻煩多了)您會成長超過六打左右,和/或超過兩到三個陣列)。 此語法可移植到最初的v7 Bourne shell ,因此可以在沒有Bash(現代版本)的地方使用。

(為您的娛樂,請參見如何使用數組實現以下內容。

while read user home shell groups loc; do
    cat <<-____HERE
        User:   $user
        Home:   $home
        Shell:  $shell
        Groups: $groups
        Loc:    $loc
____HERE
done <<HERE
    frodo    /home/shire    /bin/bash dev                   Mordor
    bilbo    /home/valinor  /bin/ksh  admin,dev             Undying Lands
    maisy    /home/maisy    /bin/zsh  dev                   Mouseville
    tallulah /home/tallulah /bin/sh   wheel,admin,dev,deity Dekadenz Kave
HERE

...尤其是當您添加更多用戶時。 或者也許不。)

您可以通過使用公共密鑰(我建議采用這種方式)將sshpass排除sshpass ,但我想您仍然需要使此腳本的邏輯以一種或另一種方式工作。

創建一個密鑰對 ,並將公共密鑰分發到您的服務器。 如果您在私鑰上輸入密碼,則需要在已加載密鑰的情況下運行ssh-agent

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM