経過時間に基づいてファイルセットを処理する必要があります(リモートディレクトリに新しいファイルが追加されるタイミングを制御できないため)。
ファイルセットに対して複数のタスクを実行する必要があるため、find
結果を変数に保存して(該当する候補が変更されないようにすることができます)、各タスクにfind
同じリストを使用しました(別のタスクを実行する必要はありません)。やり直す)。
これは私が試しているものの簡単なバージョンです。
FILELIST=$(ssh ${SSHUSER}@${SSHHOST} "cd ${REMOTEPATH}; find -amin +${TIME} -type f,d -print")
if [[ ${#FILELIST} -lt 4 ]]; then
echo "No files" >> ${LOGFILE}
exit 1
fi
echo -en "Copying remote files to remote backup\n" >> ${LOGFILE}
ssh ${SSHUSER}@${SSHHOST} "cd ${REMOTEPATH}; cp -Rpv '${FILELIST}' ${REMOTEBACKUPPATH}" >> ${LOGFILE}
これは間違いなく私がcp: missing destination file operand after ''
理解することを提供します。cp
私が望む方法でファイルリストをフォーマットする方法がわかりません。
私は文書/ SEの記事を読んでしばらくこれをやってきましたが、理解できません。私が何を間違っているのかがわかったら、cp
その知識をに適用できることを願っていますrsync
。
まだ明確ではない場合、私は初めてbashスクリプトの世界に触れました。 :)
よろしくお願いします。
ベストアンサー1
bash
この問題を解決するのに最適なシェルではありません。代わりに提案します(いくつかのパラメータ拡張を引用せずに構文をすでに使用していますzsh
)。zsh
filelist=(
${(0)"$(
ssh $SSHUSER@$SSHHOST "
cd -- ${(qq)REMOTEPATH} &&
find . -amin +${TIME} -type f,d -prune -print0"
)"}
)
if (( $#filelist < 4 )); then
print No files >> $LOGFILE
else
print "Copying remote files to remote backup" >> $LOGFILE
print -rNC1 -- $filelist | ssh $SSHUSER@$SSHHOST "
cd -- ${(qq)REMOTEPATH} && xargs -r0 cp -Rpvt ${(qq)REMOTEBACKUPPATH}"
fi
($SSHHOST
これがGNUシステムであると仮定し(あなたはすでにいくつかのGNUismを使用しています。たとえば、ファイルは、f,d
に渡されません))ログインシェルはBourneのようなものです。find
cp -v
$SSHUSER
とにかくこのディレクトリ全体をコピーするので、その中にさらにファイルを見つける必要がないので、それをコマンドに追加しまし-prune
た。find
これらのディレクトリの内容を読み取ると、最後のアクセス時間も更新されます。
それにもかかわらず、ディレクトリのファイルを読み込んでも、ディレクトリのアクセス時間は更新されません。ディレクトリのアクセス時間は、ディレクトリ内のシェルまたはグローバルls
変数を使用する場合と同様に、ディレクトリ自体の内容を読み取ると更新されますfind
(最近のアクセス時間は必ずしも完全に維持されるわけではありません)。それで、正確に何をしたいのかは明確ではありません。
上記では、次を使用します。
filelist=( values )
定義する大量にfilelist=value
変数(スカラー代わりに変数)。${(0)"$(cmd)"}
cmd
NULから出力を分割します。 NULはファイルパスに許可されていない唯一の文字なので、NULで区切られたリストを使用することはファイルパスリストを渡す安全な方法です。cd -- ${(qq)REMOTEPATH}
、で始まる値(それ自体ではありませんが/一部のシェルでは)と引用符付きの値(ここではデフォルトのシェルによって拡張されます)を--
防ぐために(、$REMOTEPATH
-
-
-4
+3
$REMOTEPATH
qq
唯一の安全な方法$REMOTEPATH
)リモートシェルの場合(Bourneに似ていると仮定し、ログインシェルがcsh / fish / rc ...の場合、一部の値では機能しません$SSHUSER
。)&&
成功した場合にのみ、次のコマンドが実行されることを保証します。cd
それ以外の場合は、間違ったディレクトリで実行されます。-print0
:NULで区切られたファイルパスを印刷します(上記を参照)。- これは一致するファイルの数を
$#filelist
含みます(元のコードの4つと比較しましたが、理由はわかりません)。 - その後、そのリストをリモートホストに再送信する必要があります。これをリモートシェル用に送信されたシェルコードの引数として渡すのではなく(さまざまな問題や制限が発生する)、stdinに
print -N
NULで区切って渡します。ssh
これは継承されます。xargs
xargs
リストを読み、それを引数cp -t target
(-t
GNU拡張)に変換します。パラメータサイズの制限を避けるために必要なだけxargs
多くを実行してください。cp