Bashスクリプトrsyncパズルゲーム

Bashスクリプトrsyncパズルゲーム

落ち込んでいる以下のスクリプトは最初の2つのターゲットには機能しますが、2番目のターゲットには機能しません。

#!bin/bash
...
backitup () {
Todaysdate=`date "+%Y-%m-%dT%H_%M_%S"`
Sourcedir=$1
Destination=$2
Username=$(echo $Sourcedir | cut -f1 -d'@')
if [ "$Username" = "root" ] ; then
    RSYNCPATH="rsync"
else
    RSYNCPATH="sudo rsync"
fi

cmd="sudo rsync -vazP --rsync-path='$RSYNCPATH' --log-file=/var/log/rsync.log $Sourcedir /BACKUPS/$Destination/back-$Todaysdate"
                echo $cmd >> ~/cmd.txt
                $cmd
...
}
backitup root@HAZns01:/etc "HAZNS01/etc"
backitup root@HAZns01:/home/ftpusers "HAZNS01/ftpusers"
backitup jakadmin@HAZFAND10:/etc "HAZFAND10/etc"
backitup jakadmin@HAZFAND11:/etc "HAZFAND11/etc"

後者の 2 つの呼び出しは以下を提供します。

unexpected remote arg: jakadmin@HAZFAND10:/etc

ただし、コマンドライン(bash cmd.txt)でcmd.txtの内容を実行し、手動で実行すると正常に実行されます。どうすればいいですか? (もちろん、パスワードのないSSHが正しく設定されています)

私は何を見逃していますか?

答え1

よりバッシュFAQ/050

WordSplittingと変数内の単一引用符はリテラルなので、この操作は文法的に失敗します。

シェルスクリプトを作成するときは、変数にコマンドを入れないでください。

関数を使用してコマンドを再利用します。録音用set -x。あるいは、必要に応じて配列を使用して、コマンドの一部とその引数を保持することもできます。

ちなみに、1行では$()コマンド置換を使用します。これが正しい方法です。他の行では、廃止されたバックティックを使用しました。少なくとも一貫性を保ってください。

関連情報