Skip to content

Instantly share code, notes, and snippets.

@kawaz
Created December 14, 2023 04:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kawaz/5e541b3648b019be4ace316f5d3341e0 to your computer and use it in GitHub Desktop.
Save kawaz/5e541b3648b019be4ace316f5d3341e0 to your computer and use it in GitHub Desktop.
ファイルを日付ディレクトリやインスタンスIDを付けた名前にしつつ移動またはコピーするスクリプト。ログをEFSに集約したりする等に使うことを想定している。
#!/bin/bash
# テンプレート変数を用意
declare -A TEMPLATE_KV=()
while read -r k v; do
k=${k//-/_}; k=${k//:/}; k=${k^^}
TEMPLATE_KV["$k"]="$v"
done < <(ec2-metadata -i -t -h -o -z -p -v)
TEMPLATE_KV[REGION]=$(perl -pe's/[a-z]$//' <<< "${TEMPLATE_KV[PLACEMENT]}")
usage() {
local message=$*
(
if [[ -n $message ]]; then
printf '%s\n' "$message"
echo
fi
echo "Usage:"
echo " $0 op from_path to_dir [to_name [...find_opts]] "
echo
echo "コマンド引数:"
echo " op mvまたはcp(cpは実際にはrsync -a)"
echo " from_path バックアップ元ディレクトリまたはファイルも可(サブディレクトリは対象外)"
echo " to_dir バックアップ先ディレクトリ(元ファイルのmtimeを元にしたdateコマンドのフォーマット文字と{テンプレート変数}が利用可能"
echo " to_name バックアップ先ファイル名(デフォルト={FILE}、元ファイルのmtimeを元にしたdateコマンドのフォーマット文字と{テンプレート変数}が利用可能"
echo ' find_opts from_pathに対して追加するfind引数(-maxdepth 1 -type f ! -size 0 は常に追加される )'
echo
echo '環境変数:'
echo ' DRY_RUN 空でない場合は実際のファイル操作は行わない'
echo
echo "利用可能テンプレート変数:"
echo " FILE=(個別の元ファイル名)"
for k in "${!TEMPLATE_KV[@]}"; do
echo " $k=${TEMPLATE_KV["$k"]}"
done
echo
echo "Example:"
echo " # ログファイルを日付ディレクトリに移動やコピーする"
echo " $0 mv /var/log/httpd_log /tmp/logdest/var_log_httpd_log/%Y/%m/%d '{FILE}.{INSTANCE_ID}' -name '*hourly*' -mmin +65"
echo " $0 cp /var/log/httpd_log /tmp/logdest/var_log_httpd_log/%Y/%m/%d '{FILE}.{INSTANCE_ID}' -name '*hourly*' -mmin -65"
echo " # dest_dirをefsにすることで動的に起動中されたインスタンス情報を1箇所に集める"
echo " (ec2-metadata > /tmp/ec2-metadata; $0 mv /tmp/ec2-metadata /tmp/ec2-metadata-all/%Y-%m-%d/ '{FILE}.{INSTANCE_ID}')"
) >&2
exit 1
}
op=$1
from_path=$2
to_dir=$3
to_name=${4:-'{FILE}'}
[[ $op =~ ^(mv|cp)$ ]] || usage "op is only 'mv' or 'cp'"
[[ -d $from_path ]] || [[ -f $from_path ]] || usage "from_path is not file or directory: $from_path"
[[ -n $to_dir ]] || usage "to_dir is empty"
[[ -n $to_name ]] || usage "to_name is empty"
[[ $to_name == */* ]] && usage "to_name must not contain '/'"
find_opts=("${@:5}")
mtime() { stat -c %Y "$1" 2>/dev/null || echo 0; }
apply_template() {
local template=$1
local from_file=$2
local from_mtime=$(mtime "$from_file")
local k v
local FILE=$(basename "$from_file")
template=$(date -d "@$from_mtime" +"$template")
for k in "${!TEMPLATE_KV[@]}"; do
v=${TEMPLATE_KV["$k"]}
template=${template//"{$k}"/"$v"}
done
template=${template//"{FILE}"/"$FILE"}
printf %s "$template"
}
while read -r from_file; do
[[ -f $from_file ]] || continue
to_file=$(apply_template "$to_dir/$to_name" "$from_file")
echo "$op $from_file $to_file"
[[ -n $DRY_RUN ]] && continue
[[ -d "${to_file%/*}" ]] || mkdir -p "${to_file%/*}"
if [[ $op == mv ]]; then
mv "$from_file" "$to_file"
elif [[ $op == cp ]]; then
rsync -a "$from_file" "$to_file"
fi
done < <(find "$from_path" -maxdepth 1 -type f ! -size 0 "${find_opts[@]}")
Usage:
archive_file.sh op from_path to_dir [to_name [...find_opts]]
コマンド引数:
op mvまたはcp(cpは実際にはrsync -a)
from_path バックアップ元ディレクトリまたはファイルも可(サブディレクトリは対象外)
to_dir バックアップ先ディレクトリ(元ファイルのmtimeを元にしたdateコマンドのフォーマット文字と{テンプレート変数}が利用可能
to_name バックアップ先ファイル名(デフォルト={FILE}、元ファイルのmtimeを元にしたdateコマンドのフォーマット文字と{テンプレート変数}が利用可能
find_opts from_pathに対して追加するfind引数(-maxdepth 1 -type f ! -size 0 は常に追加される )
環境変数:
DRY_RUN 空でない場合は実際のファイル操作は行わない
利用可能テンプレート変数:
FILE=(個別の元ファイル名)
INSTANCE_TYPE=m6i.large
PLACEMENT=ap-northeast-1a
LOCAL_HOSTNAME=ip-10-20-14-218.ap-northeast-1.compute.internal
PUBLIC_IPV4=13.114.104.27
PUBLIC_HOSTNAME=ec2-13-114-104-27.ap-northeast-1.compute.amazonaws.com
LOCAL_IPV4=10.20.14.218
REGION=ap-northeast-1
INSTANCE_ID=i-0d435422959edb181
Example:
# ログファイルを日付ディレクトリに移動やコピーする
archive_file.sh mv /var/log/httpd_log /tmp/logdest/var_log_httpd_log/%Y/%m/%d '{FILE}.{INSTANCE_ID}' -name '*hourly*' -mmin +65
archive_file.sh cp /var/log/httpd_log /tmp/logdest/var_log_httpd_log/%Y/%m/%d '{FILE}.{INSTANCE_ID}' -name '*hourly*' -mmin -5
# dest_dirをefsにすることで動的に起動中されたインスタンス情報を1箇所に集める
(ec2-metadata > /tmp/ec2-metadata; archive_file.sh mv /tmp/ec2-metadata /tmp/ec2-metadata-all/%Y-%m-%d/ '{FILE}.{INSTANCE_ID}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment