バグってて大事なファイルを上書きしちゃったらすみません。責任取れません。
テストは一通りやったけど、 Linux 初心者で知らない挙動のほうが多いため怪しいです。
コード
@ko1nksm さんが一部コードを修正してくださいました。ありがとうございます。
変数を使用するときは必ずダブルクォートするようにしてください。それがベストプラクティスです。
肝に銘じます!
.bash_aliases
とかに貼り付けて使うと良いと思います。
$BACKUP_DIR
を事前に設定しておく必要があります。
export BACKUP_DIR=~/.local/share/backup
とかでいいんじゃないでしょうか。
backup() {
usage='
Function: backup
Description:
指定されたファイルまたはディレクトリをバックアップする。引数またはパイプ入力でパスを指定する。
ファイルは $BACKUP_DIR/フルパス_YYYYMMDDHHMMSS にコピーされる。
バックアップ先のディレクトリがない場合は作成される。
Parameters:
$1[ $2...] (string): バックアップ対象ファイルのパス。相対パスまたは絶対パス
Returns:
None
Example:
backup hello.txt (実際は/path/to/hello.txt)
$BACKUP_DIR/path/to/hello.txt_20210202030405 が作成される。
Example:
backup hello1.txt hello2.txt
Example:
backup hello*.txt
Example:
find ./he*llo{.jpg,.png} | backup
'
# 第1引数が -h の場合は使用方法を出力して終了する
[ "$1" = "-h" ] && echo "$usage" && return 0
# $BACKUP_DIR が設定されていない場合は異常終了
[ -z "$BACKUP_DIR" ] && echo 'backup: $BACKUP_DIR is not set' && return 1
if [ -p /dev/stdin ]; then
# パイプからの入力がある場合
if [ $# -gt 0 ]; then
# パイプからの入力も引数もあるときは異常終了
echo "backup: extra operand '$@'"
return 1
fi
while IFS='' read -r line; do
_backup_inner "$line"
done
elif [ $# -gt 0 ]; then
# 引数が1つ以上ある場合
for arg in "$@"; do
_backup_inner "$arg"
done
else
# パイプからの入力も引数もない場合は異常終了
echo "backup: no input from pipe and no arguments provided"
return 2
fi
}
_backup_inner() {
# ファイル・ディレクトリが存在しなければ終了する
[ ! -e "$1" ] && echo "backup: cannot access '$1': no such file or directory" && return
# echo "backup: $1"
# 引数を絶対パスに変換する 空白を含むと引数が分かれるのでクォートする
file=$(realpath "$1")
# コピー先フルパス
newfile=${BACKUP_DIR}${file}_$(date '+%Y%m%d%H%M%S')
# ディレクトリを作成
mkdir -p "$(dirname "$newfile")"
# コピー
cp "$file" "$newfile"
}
悲しみ
chatGPTを少し使ったんですが、苛立って次第に嫌味っぽくなっていく自分のことが嫌いになりそうで途中でやめました。