01/10/2018, 17:13

Hướng dẫn cách viết 1 đoạn bashscript ngắn cho linux

Mọi người cho mình nhờ chút, hiện tại server Centos bên mình đang lưu log dưới dạng:
server.log.2018-08-19-01

nghĩa là theo định dạng : server.log.yyyy-mm-dd-hh và có khoảng vài ngàn file log như này trên server
Bây giờ mình muốn zip các log này lại theo định dạng server.log.yyyy-mm.zip vào 1 thư mục khác và đồng thời xóa những file log đó đi. Nhờ mọi người chỉ cách với mình xin cảm ơn

Aragami1408 viết 19:21 ngày 01/10/2018

mình có thể chỉnh sửa biến môi trường $DATE.

Bạn thử câu lệnh sau:

printenv | grep DATE

sẽ thấy dòng đại loại như:

DATE=date +%Y-%m-%d

thì giờ nếu bạn muốn sửa được cái DATE như định dạng mong muốn của bạn là yyyy-mm thì chèn đoạn này vào file ~/.bashrc(~/.zshrc nếu bạn dùng zsh):

...
export DATE=date +%Y-%m

sau đó dùng lệnh sau để reload lại shell nếu không muốn thoát ra vào lại(mặc dù thoát ra vào lại cũng là 1 cách ): source ~/.bashrc

Nếu thấy có vấn đề gì thì hỏi tiếp

HK boy viết 19:30 ngày 01/10/2018

Nhận thấy tên file zip trùng với phần đầu của log filename nên ta cắt phần đầu của log filename.

Không rõ là bạn muốn zip như thế này

server.log.yyyy-mm.zip
|_ ..
|_ server.log.yyyy-mm-dd-h1 # file log
|_ server.log.yyyy-mm-dd-h2
|_ ...

hay

server.log.yyyy-mm.zip
|_ ..
|_ server.log.yyyy-mm # folder
  |_ server.log.yyyy-mm-dd-h1
  |_ server.log.yyyy-mm-dd-h2
  |_ ...

?

HK boy viết 19:16 ngày 01/10/2018

Vậy thì

#!/bin/bash

for f in *; do
  log_regex='^server\.log\.[0-9]{4}\-[0-9]{2}\-[0-9]{2}\-[0-9]{2}$'
  if [[ $f =~ $log_regex ]]; then
    fname=${f:0:18}  # cắt folder name
    zip -urq "$fname.zip" $f  # nhét vào file zip
    rm -f $f  # remove luôn
  fi
done
Duy Nguyen Duc viết 19:26 ngày 01/10/2018
server.log.yyyy-mm.zip
|_ ..
|_ server.log.yyyy-mm-dd-h1 # file log
|_ server.log.yyyy-mm-dd-h2
|_ ...

Kiểu này bạn ơi

Duy Nguyen Duc viết 19:28 ngày 01/10/2018

for f in *; do log_regex=’^server.log.[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}$’ if [[ $f =~ $log_regex ]]; then fname=${f:0:18} # copy-n-zip-file snippet here zip -urq “$fname.zip” “$f” # nhét vào file zip rm -f “$f” # remove luôn fi done

Mình làm theo kiểu 1 của bạn mà không được, nó hiện ra như này này

HK boy viết 19:20 ngày 01/10/2018

Bạn chạy

./nenfile.sh

thì mới được nhé.

Aragami1408 viết 19:28 ngày 01/10/2018

Bạn chạy

./nenfile.sh

thì mới được nhé.

Và đừng quên: chmod a+x nenfile.sh để cấp quyền sử dụng

Duy Nguyen Duc viết 19:18 ngày 01/10/2018

Viết như này được không mọi người review giúp với, em chạy test ok rồi nhưng lên thật dữ liệu nó lớn không biết có hiểm họa gì không ạ

#/bin/bash

### Get numberdays backup
DIR_LOG=/home/vagrant/script #thu muc chua log
a=`ls -lht --time-style long-iso $DIR_LOG | more | tail -1 | awk -F ' ' '{print $6}'` # lay ngay cuoi cung cua log
lastday=$(date -d "2018-08-01" '+%s') # chuyen dinh dang time de tinh so ngay
daynow=`date +%Y-%m-%d` # lay ngay hien tai
day=$(date -d "$daynow" '+%s') # chuyen dinh dang time de tinh so ngay
numberdays=$(( ( day - lastday )/(60*60*24) )) #tinh so ngay chua log da tao

### backup file & zip file
for i in `seq 1 $numberdays`
do
  daybackup=`date +%Y-%m-%d --date="$i days ago"`
  if ls | grep $daybackup;then
    mkdir $daybackup && mv server.log.$daybackup* $daybackup && zip -r server.log.$daybackup.zip $daybackup && rm -rf $daybackup
  fi
done
Aragami1408 viết 19:22 ngày 01/10/2018

Sửa lại code cho, bạn chưa biết cách markdown rồi:

#!/bin/bash

# Get numberdays backup
DIR_LOG=/home/vagrant/script #thu muc chua log
a=ls -lht --time-style long-iso $DIR_LOG | more | tail -1 | awk -F ' ' '{print $6}' # lay ngay cuoi cung cua log
lastday=$(date -d “2018-08-01” ‘+%s’) # chuyen dinh dang time de tinh so ngay
daynow=date +%Y-%m-%d # lay ngay hien tai
day=$(date -d “$daynow” ‘+%s’) # chuyen dinh dang time de tinh so ngay
numberdays=$(( ( day - lastday )/(606024) )) #tinh so ngay chua log da tao

backup file & zip file
for i in seq 1 $numberdays
do
daybackup=date +%Y-%m-%d --date="$i days ago"
if ls | grep $daybackup;then
mkdir $daybackup && mv server.log.$daybackup* $daybackup && zip -r server.log.$daybackup.zip $daybackup && rm -rf $daybackup
fi
done
HK boy viết 19:20 ngày 01/10/2018

mkdir $daybackup && mv server.log.$daybackup* $daybackup && zip -r server.log.$daybackup.zip $daybackup && rm -rf $daybackup

Bạn cứ viết tách ra. Bash hiểu hết mà.

mkdir $daybackup
mv server.log.$daybackup* $daybackup
zip -r server.log.$daybackup.zip $daybackup
rm -rf $daybackup

Dòng mkdir cần chú ý vì $daybackup không phải lúc nào cũng không tồn tại, việc mkdir nhiều lần không cần thiết gây lãng phí tài nguyên, bash báo lỗi (directory existed), thậm chí có thể dẫn đến những tổn hại lớn hơn.

Duy Nguyen Duc viết 19:28 ngày 01/10/2018

Bài toán tạm ôn rồi, cảm ơn mọi người nhiều ạ

Duy Nguyen Duc viết 19:26 ngày 01/10/2018

Hi mọi người, hiện tại mình đặt file này trên server chạy được 1 thời gian rồi, tuy nhiên đang gặp phải 1 vấn đề là khi nó chạy để nén, nó nén luôn các file đã zip đặt trong cùng thư mục ấy, nhờ mọi người hỗ trợ chỗ này với, vì mô hình chung mỗi ngày nó đang nén đi nén lại các file đã zip rồi

anhpv viết 19:15 ngày 01/10/2018

thì bỏ file zip ra thư mục khác?

HK boy viết 19:28 ngày 01/10/2018

Bên trong vòng for các file thì bạn kiểm tra thêm điều kiện phải không có đuôi .zip mới được nhé.

Bài liên quan
0