cp
BusyBox 1.35に付属のツールおよび/またはそのツールがない他のツールを使用して、一方向にローカルフォルダを同期する必要がありますrsync
。次のような結果が得られたが、cp -auv /source/ /target
ターゲットから削除されたアイテムは削除されません。ターゲットは最終的にソースの正確なコピーでなければなりませんが、すでにほとんどを持っているので、いくつかの更新を上書き、新しい追加、移動するインタラクティブなプロンプトなしで必要な場合があります。
直す。BusyBox番号cp -auv /source/ /target
一方向同期に必要なすべてのタスクを完了した場合とは別にターゲットから古いコンテンツを削除します。 2つのフォルダを「比較」してターゲットにまだ存在するアイテムを削除するコマンド/スクリプトはありますか?おそらく同様のことがうまくいく diff -qr /source /target | xargs rm -rf
でしょうか?diff
答え1
私はずっと前にbusybox 1.22で次のスクリプトを正常に使用しました。シミュレーションが速くて汚いです。非常に基本的な rsync
機能(時間とサイズベースの同期+ロギングのみ)もちろん、まずレビューする必要がありますまた、ファイルの削除を処理する機能を強化することもできます(rsync --del
例:機能)。
また、簡単に削除できる最後のインタラクティブな部分に注意してください。 :
#!/bin/sh
echo "#############################################"
echo "SHELL : $SHELL"
echo "BASH : $BASH"
echo "TERM : $TERM"
DATENOW=`date +%Y%m%d-%H%M%S`
# last argument
LASTARG=`echo "$@" | awk ' { print $NF } '`
# penultimate argument
num_args=$#
num_args_max=$num_args
let num_args=$num_args-1
PENUARG=` echo "$@" | awk -v vk=$num_args ' { print $vk } ' `
TRG="$LASTARG"
echo "#############################################"
ProcedureStartCopyOneFile() {
echo "*** COPY ***"
echo "File not exists : $FILETRG" >> ~/.config/bashmv/bashmv.log
echo -en "\r Copying ($i) (...)"
echo "$i" | cpio -pvdmu "$TRG"
echo -en "\r Copied ($i)."
TRSS=` du -hs "$FILETRG" --apparent-size | cut -f 1 `
SRSS=` du -hs "$i" --apparent-size | cut -f 1 `
if [ ! -d "$i" ] && [ "$SRSS" != "$TRSS" ] ; then
echo "Different size: $FILETRG"
echo "** WARNING **"
echo "Different size: $FILETRG" >> ~/.config/bashmv/bashmv.log
echo "** WARNING **" >> ~/.config/bashmv/bashmv.log
exit
else
echo -en "\r Copied ($i) [OK]"
fi
echo "*** COPY OK ***"
echo ".*.*"
}
ProcedureCopying() {
echo "> Parameters: Source: $SRC => Target: $TRG"
if [ -f "$SRC" ] || [ -d "$SRC" ] ; then
echo "Source: $SRC"
else
echo "Directory or file source $SRC not found."
exit
fi
if [ "$TRG" = "" ] ; then
exit
fi
if [ "$BASH" != "/bin/bash" ] ; then
echo "Warning: You should use BASH : /bin/bash !"
exit
else
echo "Intpreter BASH: $BASH [OK] "
fi
echo "** START ** "
[ ! -d ~/.config/bashmv ] && mkdir -p ~/.config/bashmv
[ ! -d "$TRG" ] && mkdir -p "$TRG"
if [ "$LASTARG" = "--debug" ] ; then
find "$SRC" -print
exit
fi
find "$SRC" -print | grep -v "^$\|^#" | while read -r i ; do
# echo "Processing $i"
FILETRG="${TRG}/${i}"
DATENOW=`date +%Y%m%d-%H%M%S`
echo "> Start: .*.* ($i)"
if [ ! -f "$FILETRG" ] && [ ! -d "$i" ] ; then
echo ".*.*"
echo "*** COPY ***"
echo "File not exists : $FILETRG" >> ~/.config/bashmv/bashmv.log
echo "$i" | cpio -pvdmu "$TRG"
TRSS=` du -hs "$FILETRG" --apparent-size | cut -f 1 `
SRSS=` du -hs "$i" --apparent-size | cut -f 1 `
if [ ! -d "$i" ] && [ "$SRSS" != "$TRSS" ] ; then
echo "Different size: $FILETRG"
echo "** WARNING **"
echo "Different size: $FILETRG" >> ~/.config/bashmv/bashmv.log
echo "** WARNING **" >> ~/.config/bashmv/bashmv.log
exit
else
echo "Copied ($i) [OK]"
fi
echo "*** COPY OK ***"
echo ".*.*"
elif [ -d "$i" ] ; then
mkdir -p "$FILETRG"
echo "Creating $FILETRG"
elif [ ! -d "$i" ] ; then
TRSS=` du -hs "$FILETRG" --apparent-size | cut -f 1 `
SRSS=` du -hs "$i" --apparent-size | cut -f 1 `
# echo "Source: $SRSS vs $TRSS"
if [ -d "$i" ] ; then
echo "Directory."
fi
if [ ! -d "$i" ] ; then
if [ -f "$FILETRG" ] && [ "$SRSS" = "$TRSS" ] ; then
echo "file $FILETRG exists. [Same size]"
fi
if [ "$SRSS111kkk" = "$TRSS" ] ; then
echo "Different size: $FILETRG"
echo "** WARNING **"
echo "Different size: $FILETRG" >> ~/.config/bashmv/bashmv.log
echo "** WARNING **" >> ~/.config/bashmv/bashmv.log
FILETRGERROR="${TRG}/Error/${i}"
[ ! -d "$TRG/Error" ] && mkdir -p "$TRG/Error"
echo "$TRSS" | cpio -pvdmu "$TRG/Error/${DATENOW}-${i}"
fi
fi
fi
done
echo "Finished!"
if [ "$LASTARG" = "--rm" ] ; then
echo "Delete the directory: $SRC [y/n] ? "
read inpud
[ "$inpud" = "n" ] && exit
rm -rf "$SRC"
fi
exit
匿名の役に立つ何人かの著者にすべての功績を認めます。
答え2
その答えを見つけるには、削除、レビュー、批判という最後のステップが必要だ。まず、ターゲットを更新します。ターゲットのエントリはソースよりも最新ではないと仮定します。つまり、ソースはターゲットの唯一の更新エージェントです。ソースから削除された以前のエントリを削除する必要がありますが、cp
これをしないでください。次のように@cevingのgrepコマンドを使用します。https://stackoverflow.com/a/51761017/612313
cp -auv /source/. /target
grep -v -F -x -f <(find /source -type f -printf '%P\n') <(find /target -type f -printf '%P\n')
これにより、/target/ に基づいて、/target のすべてのサブフォルダーにある未使用のすべてのファイルへのパスが印刷されますが、サブフォルダー自体は印刷されません。これで、この出力を供給する方法rm /target/$1
と最後の手順で空のサブフォルダを見つけて削除する方法を学ぶだけです。
たぶん、次のようになります(行が長すぎます)。
for i in $(grep -v -F -x -f <(find /source -type f -printf '%P\n') <(find /target -type f -printf '%P\n')); do echo /target/$i; done
または、
grep -v -F -x -f <(find /source -type f -printf '%P\n') <(find /target -type f -printf '%P\n') | while read i; do echo /target/$i; done
出力全体をecho
(rm
)に送信できますが、すべての行に/target/を追加することはできないため、最初に作業フォルダを変更する必要があるため、短くなります(?)。
cd /target
echo $(grep -v -F -x -f <(find /source -type f -printf '%P\n') <(find . -type f -printf '%P\n'))
これまでの私の最高の候補ソリューションは次のとおりです。
mkdir /target
pushd /target
cp -auv /source/. .
rm -v $(grep -v -F -x -f <(find /source -type f -printf '%P\n') <(find . -type f -printf '%P\n'))
find . -empty -type d -delete
popd
(何らかの理由でターゲットの最新ファイルには触れません。このスクリプトがターゲットの唯一のアップデートプログラムである場合は機能します。)
テストする質問initrd
:私たちはどの殻にありますか?灰のようなものであればpushd/pod
不可能かもしれませんし、$()
拡張パックも不可能かもしれません。私の結果を報告する予定です...