從文字檔案傳遞變數的奇怪問題

從文字檔案傳遞變數的奇怪問題

我有一個腳本,可以為文件中的每一行運行另一個腳本。

當我echo每次都$line可以如預期看到該行的完整內容。

connect.sh僅在內部$1設定為user\ name

當我嘗試使用時"$line"$1結果connect.shuser\ name user\ password

如何設定程式流程,以便將toreboot.sh的每一行作為 2 個參數傳遞。/tmp/historyconnect.sh

最終結果$1是?user\ name$2user\ password

重新啟動.sh:

if [ -e "/tmp/history" ]; then
  while read -r line; do
    echo $line
    connect.sh $line \
      && break
  done </tmp/history
fi

連接.sh:

echo $1
echo $2

/tmp/歷史:

user\ name user\ password

答案1

我假設反斜線是為了轉義兩個空格,這樣它們就不會分隔這些值。

這樣read -r line你就可以得到變數 中的整行line,因此line包含user\ name user\ password, 和退格鍵。如果沒有技巧,將其拆分並不容易eval。未加引號的內容$line會因空格、反斜線或非反斜線而分割。引用後,它會擴展為一個單詞,如您所見。

幸運的是,read可以處理反斜線並將其輸入分成兩個(或更多)變數。這將使變數包含user nameand user password(刪除反斜線):

while read user pass ; do 
    echo "user: $user"
    echo "pass: $pass"
    ./connect.sh "$user" "$pass"
done < file

但是,如果您想在使用者名稱和密碼中允許使用空格,最好使用空格以外的其他分隔符號。冒號很常見,所以你會有這樣的輸入:

user name:user pass word

然後閱讀它

while IFS=: read -r user pass ; do 
    echo "user: $user"
    echo "pass: $pass"
done < file          

(只要密碼不以冒號結尾就應該有效)

答案2

如果參數中包含空格,則需要確保用雙引號將該字串引起來,以防止connect.sh將其解釋為多個參數。您可能希望將字串拆分為多個參數。我不確定該行的格式是什麼,但您也許可以執行以下操作:

line="user name user password"
# Split the line into space-separated tokens and store 1 and 2
UNAME=$(echo "$line" | cut -d ' ' -f 1,2)
# Split the line into space-separated tokens and store 3 and 4
UPASSWD=$(echo "$line" | cut -d ' ' -f 3,4)
echo "$UNAME"
echo "$UPASSWD"

這應該要列印:

user name
user password

您可能需要根據輸入行的實際格式進行一些調整。例如,如果您的 $line 具有以逗號分隔的使用者名稱和使用者密碼,您可以執行:

line="user name,user password"
# Split the line into comma-separated tokens and store 1
UNAME=$(echo "$line" | cut -d ',' -f 1)
# Split the line into comma-separated tokens and store 2
UPASSWD=$(echo "$line" | cut -d ',' -f 2)
echo "$UNAME"
echo "$UPASSWD"

請記住,如果您將一個參數傳遞給程式並且該參數包含空格,則需要使用雙引號以使程式將其視為一個參數。

相關內容