私はLinuxを初めて使用し、-rスイッチを使用せずに作成されるバックアップフォルダにディレクトリの内容をコピーするBashスクリプトを作成しようとしています。ディレクトリの最大深度は 2 と仮定します。スクリプトにいくつかのエコーを入れると、forループが最初の唯一の引数を現在のフォルダのパスとして使用することがわかりました。これはディレクトリ内のすべてのファイルを絶対に無視します。成功せずにコードを何度も変更してみました。文法的なエラーがありますか?ロジックが間違っていますか?答えを受けたいです。ありがとうございます!
pwd > route
r=$(<route)
cd ..
if [ ! -d backup ]; then
mkdir backup
fi
cd backup
pwd > buroute
BUrout=$(<buroute)
cd "$r"
for i in $r; do
if [ -f $i ]; then
cp $i "$BUrout"
fi
if [ -d $i ]; then
if [ $i == $r ]; then
continue
fi
cd "$i"
pwd > current
cur=$(<current)'/'
for file in "$cur"; do
if [ -f "$file" ]; then
cp $file "$BUrout"
fi
done
cd ..
fi
done
答え1
cp -r
ディレクトリ構造を明示的に平坦化したい場合を除き、なぜこれを使用したり達成できないのかはよくわかりませんが、rsync -a
大丈夫です。
サブディレクトリへのパスを取得するには、多くの作業を行う必要があります。 cd
ディレクトリに移動してpwd
ファイルに移動し、ファイルを変数として読み込みます。代わりに、eg BUrout="$PWD/backup"
($PWD
現在の作業ディレクトリのパス名を含む)を使用できます。
ループがディレクトリ名にあるため、ファイルを処理しません。あなたが望むのは、おそらくfor i in "$r"/*; do
2番目のループでも同じです。
いつも変数拡張を二重引用符で囲みます!たとえば、if [ "$i" = "$r" ]
(また、ダブルでは=
なくシングルであることに注意してください)。両方を見る」スペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?「そして」bash / POSIXシェルで変数を引用することを忘れてしまうセキュリティリスク」
スクリプトに単一cd
。本物デバッグが難しいです。
それ以外は構文エラーがなく、ロジックが正しいようです。
次のことを提案できます。これはまだ同じループロジックとコードで使用されるほとんどの同じテストを使用しますが、呼び出しがなく、cd
ディレクトリ名をあまり変更する必要はありません。
#!/bin/sh
source="$1"
dest="$2"
mkdir -p "$dest" # creates destination directory if not already exists
for name in "$source"/*; do
if [ -f "$name" ]; then
cp "$name" "$dest"
elif [ -d "$name" ]; then
for name2 in "$name"/*; do
if [ -f "$name2" ]; then
cp "$name2" "$dest"
fi
done
fi
done
または、一部の人にとって魅力的に見える短縮構文を使用してください。
#!/bin/sh
source="$1"
dest="$2"
mkdir -p "$dest" # creates destination directory if not already exists
for name in "$source"/*; do
[ -f "$name" ] && { cp "$name" "$dest"; continue; }
[ ! -d "$name" ] && continue
for name2 in "$name"/*; do
[ -f "$name2" ] && cp "$name2" "$dest"
done
done
スクリプトは、ソースディレクトリとターゲット/ターゲットディレクトリの2つのパラメータを使用します。
$ ./script mydir some_new_backup_dir
cp
どのコマンドがターゲットディレクトリの既存のファイルを上書きするかを確認しようとする試みは行われません。
また、両方のスクリプトがスクリプトである/bin/sh
ことに注意してください。彼らはbash
シェル固有のアイテムを使用しません。
ターゲットディレクトリが存在すると仮定すると、これはほぼ同じです。
find source_dir -maxdepth 2 -type f -exec cp {} target_dir ';'