テキストファイルから変数を渡す際の奇妙な問題

テキストファイルから変数を渡す際の奇妙な問題

ファイル内の各行に対して別のスクリプトを実行するスクリプトがあります。

echoそれぞれを実行すると、$line期待どおりに行の完全な内容が表示されます。

ただし、内部connect.shのみ$1として設定されますuser\ name

を使用しようとすると"$line"$1が にconnect.shなってしまいますuser\ name user\ password

reboot.sh各行を2 つのパラメータとして/tmp/history渡すようにプログラム フローを設定するにはどうすればよいでしょうか。connect.sh

最終結果は、そして$1ですか?user\ name$2user\ password

再起動してください:

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

接続:

echo $1
echo $2

/tmp/履歴:

user\ name user\ password

答え1

バックスラッシュは、値が区切られないように 2 つのスペースをエスケープするためにあると想定しています。

を使用すると、read -r line変数 の行全体を取得するので、バックスペースを含む が含まれます。 を使用したトリックなしでこれを分割するのは簡単ではありません。引用符で囲まれていない部分は、空白、バックスラッシュの有無にかかわらず分割されます。引用符で囲まれている場合は、ご覧のとおり 1 つの単語に展開されます。linelineuser\ name user\ passwordeval$line

幸いなことに、readはバックスラッシュを処理し、入力を 2 つ (またはそれ以上) の変数に分割できます。これにより、変数には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"

プログラムに引数を渡すときに、その引数にスペースが含まれている場合は、プログラムがそれを 1 つの引数として認識できるように二重引用符を使用する必要があることに注意してください。

関連情報