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

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 :laughing:): source ~/.bashrc

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

2 Likes

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
  |_ ...

?

2 Likes

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
2 Likes
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

1 Like

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

Bạn chạy

./nenfile.sh

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

2 Likes

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

2 Likes

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

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
2 Likes

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.

2 Likes

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

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

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

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é.

1 Like

gợi ý giúp mình 1 đoạn regex với :frowning:

Bạn xem qua ví dụ này:

Họ hướng dẫn ignore file .txt, bạn có thể làm tương tự với file .zip.

Tuy nhiên với regex + code của mình đưa ra thì bạn sẽ không bao giờ đẩy file zip vào zip lại lần nữa, vì tên file không thoả mãn regex.

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?