【Linux】ファイルで指定した対象を一括でバックアップする

## はじめに
大量の固定ファイルを一定時間ごとにバックアップしなきゃいけないことがあったので引数に一覧を渡して一括バックアップするシェルスクリプトを作ってみました。
あんまり使う機会はないかな。。

## 引数となるテキストファイル
バックアップを取りたいファイル名をフルパスで指定。

```:target.txt
/home/user/1dir/1f.txt
/home/user/1dir/2f.txt
/home/user/2dir/1f.txt
/home/user/2dir/2f.txt
/home/user/2dir/3f.txt
/home/user/2dir/4f.txt
```

## 作ったシェルスクリプト
ファイル名の末尾に「_YYYYmmddHHMMSS」を追加してバックアップします。
一応ログは標準とエラー標準分けてファイルに出しています。

```bash:bk_files.sh
#!/bin/bash

function bk_file(){
  now=`date '+%Y%m%d%H%M%S'`
  IN_FILE=$1
  BK_FILE="$IN_FILE"_$now
  # バックアップ作成
  cp $IN_FILE $BK_FILE
  
  if [ $? -gt 0 ]; then
    # エラーの場合ここで終わり
    return 1
  fi

  echo "IN:$IN_FILE OUT:$BK_FILE"
  return 0
}

# 正常とエラーで分けてログをとる
successlog=success_bk_file.log
errorlog=error_bk_file.log

# 処理対象を格納
DATA=`cat $1`

while read line
do
  # 関数呼び出し
  bk_file $line 1>> $successlog 2>> $errorlog
done << FILE
$DATA
FILE
```

## 実行環境
環境作るのが面倒なので以下を利用しました。

**jor1k**
http://s-macke.github.io/jor1k


## 実行前
totalの数値が間違っているのはjor1kのバグかな。。

```:ls 
~ $ ls -la */
1dir/:
total 2
drwxr-sr-x    4 user     user           111 Jul 27 07:50 .
drwxr-sr-x   11 user     user           339 Jul 27 07:49 ..
-rw-r--r--    1 user     user             0 Jul 27 07:50 1f.txt
-rw-r--r--    1 user     user             0 Jul 27 07:50 2f.txt

2dir/:
total 3
drwxr-sr-x    6 user     user           171 Jul 27 07:50 .
drwxr-sr-x   11 user     user           339 Jul 27 07:49 ..
-rw-r--r--    1 user     user             0 Jul 27 07:50 1f.txt
-rw-r--r--    1 user     user             0 Jul 27 07:50 2f.txt
-rw-r--r--    1 user     user             0 Jul 27 07:51 3f.txt
-rw-r--r--    1 user     user             0 Jul 27 07:51 4f.txt
~ $ 
```

## 実行
実行権限を付与して実行。

```:
~ $ chmod 755 bk_files.sh
~ $ sh bk_files.sh target.txt
```

最初「./bk_files.sh target.txt」の形式で実行しようとしたけどnot foundになるので「echo $SHELL」したらログインシェルはshだったのでshで実行しています。
実際に使っていた環境はbashでしたが、そうでなければシバンを「#!/bin/sh」に変えればよさそうですね。


## 実行後
日付付きでバックアップされてますね。

```:ディレクトリの状態
~ $ ls -la */
1dir/:
total 3
drwxr-sr-x    6 user     user           201 Jul 27 07:50 .
drwxr-sr-x   15 user     user           492 Jul 27 07:49 ..
-rw-r--r--    1 user     user             0 Jul 27 07:50 1f.txt
-rw-r--r--    1 user     user             0 Jul 27 08:03 1f.txt_20190727080313
-rw-r--r--    1 user     user             0 Jul 27 07:50 2f.txt
-rw-r--r--    1 user     user             0 Jul 27 08:03 2f.txt_20190727080313

2dir/:
total 5
drwxr-sr-x   10 user     user           351 Jul 27 07:50 .
drwxr-sr-x   15 user     user           492 Jul 27 07:49 ..
-rw-r--r--    1 user     user             0 Jul 27 07:50 1f.txt
-rw-r--r--    1 user     user             0 Jul 27 08:03 1f.txt_20190727080313
-rw-r--r--    1 user     user             0 Jul 27 07:50 2f.txt
-rw-r--r--    1 user     user             0 Jul 27 08:03 2f.txt_20190727080313
-rw-r--r--    1 user     user             0 Jul 27 07:51 3f.txt
-rw-r--r--    1 user     user             0 Jul 27 08:03 3f.txt_20190727080313
-rw-r--r--    1 user     user             0 Jul 27 07:51 4f.txt
-rw-r--r--    1 user     user             0 Jul 27 08:03 4f.txt_20190727080314
~ $
```

```:success_bk_file.log
~ $ cat success_bk_file.log
IN:/home/user/1dir/1f.txt OUT:/home/user/1dir/1f.txt_20190727080313
IN:/home/user/1dir/2f.txt OUT:/home/user/1dir/2f.txt_20190727080313
IN:/home/user/2dir/1f.txt OUT:/home/user/2dir/1f.txt_20190727080313
IN:/home/user/2dir/2f.txt OUT:/home/user/2dir/2f.txt_20190727080313
IN:/home/user/2dir/3f.txt OUT:/home/user/2dir/3f.txt_20190727080313
IN:/home/user/2dir/4f.txt OUT:/home/user/2dir/4f.txt_20190727080314
~ $
```

権限不足等でコピーエラーになったファイルはsuccess_bk_file.logには出力されずerror_bk_file.logに出力されます。

## あとがき
bk_file関数の中身を変えればいろいろできそう。
一括でバックアップした後にスタブを作りたい場合などは関数の中でcpコマンドの代わりに以下みたいなことをすればいい感じでできそうですね。

```bash:スタブを作る
touch $file
if [ $? -gt 0 ]; then
  # エラーの場合ここで終わり
  return 1
fi

echo '#!/bin/bash' > $file
echo '' >> $file
echo 'exit 0' >> $file

chmod 755 $file
```