Bẫy: làm cho các tập lệnh bash của bạn mạnh mẽ hơn

Lướt mạng quốc gia, tôi bắt gặp một bài báo thú vị (mà tôi mang đến đây bằng văn bản vì nó được giải thích một cách thành thạo) nơi tác giả của nó chỉ cho chúng ta cách làm cho các tập lệnh Bash của chúng ta mạnh mẽ hơn bằng cách sử dụng Traps.

Làm cho các tập lệnh bash của bạn mạnh mẽ hơn với các bẫy

Hãy tưởng tượng rằng bạn có một tập lệnh bash chạy mỗi ngày mỗi sáu giờ và tại một thời điểm nào đó nó bị lỗi hoặc cùng một tập lệnh đó chạy hai lần đồng thời. Hai tình huống này khá khó chịu vì chúng yêu cầu sự can thiệp của con người để sửa chữa hoặc vào một số thời điểm nhất định chúng không thể được giải quyết, khiến hệ thống ở trạng thái không nhất quán. Giải pháp cho điều này, trong số những cách khác, là sử dụng bẫy.

Bẫy là một cách đơn giản và hiệu quả để kiểm soát đầu ra của các tập lệnh bash. Hãy quay lại cùng một tình huống ban đầu, nếu tập lệnh bị dừng theo cách thủ công, ví dụ như với ctrl-c, nó bị gián đoạn trả lại tín hiệu đầu ra

INT

và nếu nó kết thúc bằng

kill

thì đầu ra sẽ là

TERM.

Tất cả các mã thoát khả thi có thể được xem với

kill -l

Tuy nhiên, được sử dụng nhiều nhất chính xác là

INT, HẠN, THOÁT

Ví dụ: nếu tập lệnh bao gồm đồng bộ hóa tệp với

rsync

điều hợp lý nhất là dựa vào tệp khóa không cho phép tập lệnh chạy đồng thời:

LOCK = "/ var / run / rsync.lock" nếu [! -e $ LOCK]; sau đó chạm vào thanh foo $ LOCK rsync -avz rm $ LOCK khác echo "rsync đã chạy" fi

Trong tiếng Tây Ban Nha đơn giản, tập lệnh trên kiểm tra xem tệp khóa có tồn tại hay không và nếu nó không tồn tại, nó sẽ tạo ra nó và sau đó thực hiện lệnh tương ứng, cuối cùng là xóa tệp khóa. Nếu tệp tồn tại, tập lệnh chỉ cần gửi một thông báo đến người dùng cho biết rằng lệnh đã được chạy.

Tuy nhiên, khi có vấn đề xảy ra, tập tin khóa không được loại bỏ, làm hỏng các tác dụng không mong muốn. Giải pháp này rất đơn giản:

LOCK = "/ var / run / rsync.lock" nếu [! -e $ LOCK]; sau đó bẫy "rm -f $ LOCK; thoát" INT TERM EXIT chạm vào $ LOCK rsync -avz foo bar rm $ LOCK trap - INT TERM EXIT else echo "rsync đã chạy" fi

Điểm đặc biệt của giải pháp này là lệnh được bao bọc trong một cái bẫy để khi nhận được tín hiệu

INT, HẠN, THOÁT

tập lệnh dừng và xóa tệp khóa.

Điều đáng nói là có thể có một tình huống cạnh tranh trong kịch bản ở trên giữa thời gian tệp khóa được xác minh và thời điểm nó được tạo. Một giải pháp khả thi là sử dụng chế độ noclobber chuyển hướng và bash không chuyển hướng đến tệp hiện có:

LOCK = "/ var / run / rsync.lock" if (set -o noclobber; echo $$> "$ LOCK") 2> / dev / null; sau đó bẫy 'rm -f "$ LOCK"; thoát $? ' INT TERM EXIT rsync -avz foo bar rm -f $ LOCK trap - INT TERM EXIT else echo "rsync đã chạy: $ (cat $ LCK)" fi

Điểm đặc biệt của cái sau là nó được sử dụng như tôi đã nói, chế độ noclobber và tệp khóa chứa PID của quá trình đang được thực thi.

Cũng cần nhắc lại rằng còn có các giải pháp khác như

flock

o

solo

tuy nhiên trong bài đăng này, tôi muốn chia sẻ các giải pháp với các tài nguyên riêng của bash. Bạn có thể tìm hiểu thêm một chút về Bẫy với cái này hướng dẫn tuyệt vời.


Để lại bình luận của bạn

địa chỉ email của bạn sẽ không được công bố. Các trường bắt buộc được đánh dấu bằng *

*

*

  1. Chịu trách nhiệm về dữ liệu: Miguel Ángel Gatón
  2. Mục đích của dữ liệu: Kiểm soát SPAM, quản lý bình luận.
  3. Hợp pháp: Sự đồng ý của bạn
  4. Truyền thông dữ liệu: Dữ liệu sẽ không được thông báo cho các bên thứ ba trừ khi có nghĩa vụ pháp lý.
  5. Lưu trữ dữ liệu: Cơ sở dữ liệu do Occentus Networks (EU) lưu trữ
  6. Quyền: Bất cứ lúc nào bạn có thể giới hạn, khôi phục và xóa thông tin của mình.

  1.   Raphael Castro dijo

    Tuyệt quá! Cám ơn vì đã chia sẻ.

  2.   nx dijo

    Bài viết hay, chỉ cần thay đổi 'echo "rsync đã chạy: $ (cat $ LCK)"' thành 'echo "rsync đã chạy: $ (cat $ LOCK)"'

    Liên quan

  3.   dglangos dijo

    Một bài báo rất thú vị, vâng thưa ông! Cái này tôi giữ.

  4.   Joaquin dijo

    Đó là một lệnh rất hữu ích cần ghi nhớ. Tôi đã sử dụng nó trong một tập lệnh mà tôi đã xuất bản trong một bài đăng, để xóa một số tệp mà tập lệnh đã tạo khi nó bị dừng.

  5.   daniFP dijo

    Rất thú vị, vâng thưa ông.