落ち込んでいる以下のスクリプトは最初の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行では$()
コマンド置換を使用します。これが正しい方法です。他の行では、廃止されたバックティックを使用しました。少なくとも一貫性を保ってください。