Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Mẹo chạy nhiều lệnh dưới bash
Bài này là tóm tắt một vài mẹo nhỏ mình học lỏm đc từ các đồng nghiệp.
Đính chính: có cập nhật một số góp ý của anh Cường
Cơ bản về exitcode
Trong UNIX/Linux qui định một process đc xem là thực thi thành công khi chúng thoát (exit
) với code số 0
. Và thất bại khi trả về non-zero status, vd: 1
chẳng hạn. Bạn sẽ thấy rất thường xuyên trong scripting có dòng code sau:
exit 0
hay
exit 1
Bạn tham khảo bảng exitcode sau để biết đc rõ hết các code đc hỗ trợ.
Xin hãy nắm qui tắc này trước.
Cở bản về job suspend
Trong bash, khi một job bị suspend thì subshell sẽ tự động trả về exitcode 0 (hay thành công). Nó sẽ không đợi cho cái job đó hoàn tất.
Qui định rằng khi bạn dùng tổ hợp phím Ctrl-Z
thì bạn ra lệnh cho shell tạm ngưng một job. Vâng xin nhắc lại là job, job cũng là một process, nó đc shell khởi tạo trực tiếp và chưa đc detach (nghĩa là chưa phải đc chạy như một service). Để giải thích rõ, hãy xem vd sau, chú ý tôi gói lệnh với dấu ()
, đây là operator để nhóm nhiều lệnh thành một job
(command1)
Bạn có thể thấy nếu bạn chạy Ctrl-Z trong trường hợp này thì shell sẽ suspend cái job ở trên, job này bao gồm thực thi một command1
process.
Bạn lưu ý rằng bạn có thể chạy nhiều lệnh trong cùng một job:
(command1; command2)
Trong trường hợp này thì active job của chúng ta bào gồm một subshell với 2 lệnh chạy, nếu chúng ta suspend thì lệnh 1 sẽ bị suspend và lệnh 2 sẽ đợi. Nếu lệnh 1 hoàn tất thì lệnh 2 mới chạy.
Chạy 2 lệnh, trong đó chạy lệnh số 2 chỉ khi lệnh số 1 thành công
Đơn giản là dùng operator &&
, vd:
command1 && command2
Cách bash xử lý rất đơn giản, bash sẽ đọc từ trái sang phải, nếu lệnh nào thành công thì sẽ trả về exitcode 0 và lệnh tiếp theo sẽ nhận biết để khởi chạy.
Mẹo này thường đường áp dụng để xây dựng CI pipeline, bước chuẩn bị nối trước bước chạy test.
Chạy 2 lệnh cho đến khi một lệnh thành công
Dùng operator ||
, vd:
command1 || command2
Cũng tương tự như lệnh &&
, bash sẽ chạy từ trái sang phải. Nếu command1
thành công thì cả pipeline sẽ dừng ở đây, hay command2
sẽ không đc chạy. Nhưng nếu command1
thất bại thì bash sẽ thử tiếp command2
, và lập lại đúng cái qui luật.
Mẹo này cực kỳ phổ biến để tạo một pipeline để thử nhiều nguồn khác nhau, vd viết một script để download video từ nhiều nguồn, chạy cho đến khi nào một nguồn đc download thành công.
Chạy 2 lệnh, trong đó chạy lệnh số 2 bất kể lệnh số 1 thành công hay không
Chúng ta sẽ dùng operator ;
, vd:
command1; command2
Operator này có nghĩa là chạy theo thứ tự, nếu lệnh số 1 xong hay không thì lệnh tiếp theo sẽ được thực thi. Xin lưu ý là có một yêu điểm, đó là nếu chúng ta suspend command1
thì command2
sẽ tiếp tục đc chạy.
Chạy 2 lệnh, trong đó nếu một trong hai lệnh bị suspend thì tất cả lệnh sẽ bị suspend.
Chúng ta tận dụng job grouping ()
operator để nhóm 2 lệnh thầnh một job.
(command1; command2)
Nếu chúng ta dùng Ctrl-Z để suspend thì cả job sẽ bị thoát ra, điều đó nghĩa là command1
và cả command2
sẽ cùng bị suspend. Điều này rất hữu dụng cho các lệnh yêu cầu sự đồng bộ.
Lời kết
- Một process gọi là thành công khi nó thoát với exitcode 0, và thất bại với exitcod1
- Suspend thông qua Ctrl-Z sẽ khiến job thông báo subshell trả về exitcode 0, lưu ý nó sẽ không đợi cho job hoàn tất
- Các operator
&&
,||
,;
,()
đc sử dụng để gán các logic điều kiện





