Điểm:2

Làm cách nào tôi có thể khởi động lại máy chủ Linux một cách an toàn khi mạng bị lỗi?

lá cờ id

tôi có một cá nhân Ubuntu máy chủ, được kết nối với Wi-Fi công cộng/chia sẻ AP (không thuộc quyền kiểm soát của tôi).

Đôi khi, nó có vấn đề về mạng và tôi rất chắc chắn, chỉ khởi động lại dịch vụ mạng sẽ không hoạt động. Cách duy nhất là khởi động lại nó.

Kế hoạch của tôi là thêm một crontab để kiểm tra kết nối mạng. Nếu nó không thành công, sau đó khởi động lại máy tính.

Nếu tôi chạy auto_reboot.sh theo cách thủ công, nó sẽ khởi động lại, khi một ping kiểm tra thất bại. Nhưng chạy từ crontab, nó không hoạt động :)

Đây là mục crontab của tôi

crontab -l
* * * * * /root/loadrc/transmissionrc/auto_reboot.sh

Tập tin /root/loadrc/transmissionrc/auto_reboot.sh

#!/bin/zsh

/root/loadrc/networkrc/ping.sh
rc=$?

nếu [[ $rc -eq 0 ]]
sau đó
    echo "nói Internet đã hoạt động trở lại."
khác
    khởi động lại
fi

Tập tin /root/loadrc/networkrc/ping.sh

#!/bin/zsh
((count = 10)) # Số tối đa để thử.

while [[ $count -ne 0 ]] ; làm
    ping -c 1 8.8.8.8 # Thử một lần.
    rc=$?
    nếu [[ $rc -eq 0 ]] ; sau đó
        ((count = 1)) # Nếu OK, thoát khỏi vòng lặp cờ.
    khác
        ngủ 1 # Giảm thiểu cơn bão mạng.
    fi
    ((count = count - 1)) # Vậy ta đi mãi không ra.
xong

thoát $rc

Tôi thêm một số nhật ký và cố tình hạ giao diện Wi-Fi xuống:

xem ifconfig wlan0 down
truyềnrc/auto_reboot.sh
#!/bin/zsh

tiếng vang "" > /root/loadrc/crontab.log

/root/loadrc/networkrc/ping.sh
rc=$?

nếu [[ $rc -eq 0 ]]
sau đó
    echo "nói Internet đã hoạt động trở lại."
khác
    khởi động lại
fi
mạngrc/ping.sh
#!/bin/zsh
((count = 10)) # Số tối đa để thử.


while [[ $count -ne 0 ]] ; làm
    /usr/bin/ping -c 1 8.8.8.8 >> /root/loadrc/crontab.log 2>&1
    tiếng vang "bước -> 2" >> /root/loadrc/crontab.log
    rc=$?

    nếu [[ $rc -eq 0 ]] ; sau đó
        tiếng vang "bước -> 3" >> /root/loadrc/crontab.log
        ((count = 1)) # Nếu OK, thoát khỏi vòng lặp cờ.
    khác
        tiếng vang "bước -> 4" >> /root/loadrc/crontab.log
        ngủ 1 # Giảm thiểu cơn bão mạng.
    fi
    ((count = count - 1)) # Vậy ta đi mãi không ra.
xong

thoát $rc

Tập tin /root/loadrc/crontab.log

/usr/bin/ping: kết nối: Không thể truy cập mạng
bước -> 2
bước -> 3

có nghĩa là, ở chế độ crontab, ngay cả khi kiểm tra ping không thành công, mã trả về vẫn bằng không.

Vì vậy, câu hỏi đặt ra là: làm cách nào để kiểm tra kết nối mạng ở chế độ crontab?

djdomi avatar
lá cờ za
có vẻ như vấn đề x và y, vấn đề ban đầu bạn đang cố giải quyết là gì?
lá cờ sn
Re *"máy chủ Ubuntu cá nhân"*: Điều đó có khiến nó trở nên lạc đề không?
lá cờ br
Tôi sẽ không sử dụng `cron` cho việc đó, nhưng `watchdog`, được thiết kế đặc biệt để khởi động lại máy cục bộ nếu một số điều kiện không thành công và cho phép chạy các lệnh tùy chỉnh dưới dạng kiểm tra.
Điểm:7
lá cờ cn
Bob
/usr/bin/ping -c 1 8.8.8.8 >> /root/loadrc/crontab.log 2>&1 
tiếng vang "bước -> 2" >> /root/loadrc/crontab.log  
rc=$?

Tôi nghĩ rằng điều này kiểm tra mã thoát của tiếng vang lệnh trong khi logic của bạn cần mã thoát của ping chỉ huy.

huangyingw avatar
lá cờ id
vâng, lỗi trong tiếng vang của tôi, cảm ơn vì đã chỉ ra điều này.
marcelm avatar
lá cờ ng
@huangyingw Vì vậy, bạn có thể cập nhật câu hỏi của mình để sửa câu hỏi đó không?
Điểm:2
lá cờ il

Tôi có ba suy nghĩ về các giải pháp khả thi cho vấn đề của bạn:

1. Bạn đã nói:

Nếu tôi chạy auto_reboot.sh theo cách thủ công, nó sẽ khởi động lại khi kiểm tra ping không thành công. Nhưng chạy từ crontab, nó không hoạt động :)

Thông thường, khi một lệnh chạy đúng trong shell tương tác của bạn (từ CLI), nhưng không chạy đúng trong cron đó là do sự khác biệt trong môi trường; ví dụ. cron có một ĐƯỜNG khác với bạn làm từ trình bao tương tác của mình. Tiêu biểu, các cron môi trường là: ĐƯỜNG=/usr/bin:/bin. Bất kỳ tập lệnh nào bạn chạy chạy theo cron sẽ không thể tìm thấy các tệp thực thi không có trên PATH.

Bên cạnh đó, bạn có thể kiểm tra cron môi trường trên hệ thống của bạn bằng cách chạy env sử dụng của bạn crontab:

* * * * * /usr/bin/env > /my/cronlog/location/mycronenvironment.txt 2>&1

trong bạn auto_reboot.sh, bạn đã thất bại trong việc sử dụng một thông số kỹ thuật đường dẫn đầy đủkhởi động lại. Như khởi động lại thường được tìm thấy trong /sbin/khởi động lại, và /sbin có thể không trong PATH được sử dụng bởi cron, đây là một vấn đề tiềm ẩn.

Do đó, tôi khuyên bạn nên xác minh môi trường (PATH) được sử dụng bởi cronvà kiểm tra kỹ tất cả các lệnh của bạn có phải là: 1) trên cron ĐƯỜNG, hoặc 2) sử dụng một đặc tả đường dẫn đầy đủ.

2. Bạn sử dụng hết mọi thứ /nguồn gốc danh mục

Thông thường, /nguồn gốc không được sử dụng cho người dùng kịch bản. Có lẽ bạn đang sử dụng sudo? Hoặc, có lẽ bạn đã thực hiện một su để trở thành root? Nếu đây là trường hợp, tôi sẽ bình luận rằng đây không phải là thực hành tốt nhất, mặc dù nó vẫn có thể hoạt động. tôi cảm thấy thực hành tốt nhất là để sử dụng sudo từ của bạn người dùng tài khoản cho bất kỳ sự leo thang đặc quyền nào bạn cần.

Không cố tỏ ra khoa trương, tôi muốn nói rằng nguồn gốc tài khoản có một crontab chạy độc lập với bất kỳ người dùng crontab. Ngoài ra, các crontab gốc không yêu cầu sudo được sử dụng - mọi thứ được thực hiện trong crontab gốc được thực hiện với nguồn gốc đặc quyền.

Tất cả những gì đã nói, tôi thấy cuộc gọi đến khởi động lại trong tập lệnh của bạn - một lệnh đòi hỏi quyền root để chạy. Điều này sẽ hoạt động như bạn đã viết nó chỉ có khi được sử dụng trong crontab gốc. Câu hỏi của bạn không cho biết bạn có đang sử dụng hay không su hoặc sudo, và vì vậy tôi đã xem qua phần này với nỗ lực làm rõ hai điểm:

  1. Nếu là của bạn cron công việc yêu cầu nguồn gốc đặc quyền, nó có lẽ tốt nhất để chạy công việc đó từ crontab gốc. Cách khác là sử dụng sudo trong một người dùng crontab điều này có khả năng gây khó xử nếu cần xác thực cho sudo - như thường lệ.
  1. Các crontab gốc có thể được truy cập từ tài khoản người dùng thông thường chỉ bằng cách sử dụng Sudo crontab -e; tức là người ta không bắt buộc phải su đến nguồn gốc để truy cập vào crontab gốc.

3. Bạn có thể gặp lỗi logic trong tập lệnh của mình

Như đã chỉ ra trong câu trả lời khác, không rõ ràng là bạn có thể dựa vào giá trị của rc từ của bạn ping.sh kịch bản như một điều kiện cho khởi động lại. Thật không may, đây có phải là vấn đề hay không lại bị che lấp bởi hai phiên bản khác nhau của ping.sh trong câu hỏi của bạn - không rõ liệu bạn có đang sử dụng phiên bản đầu tiên hay không:

#!/bin/zsh
((count = 10)) # Số tối đa để thử.

while [[ $count -ne 0 ]] ; làm
    ping -c 1 8.8.8.8 # Thử một lần.
    rc=$?

hoặc phiên bản thứ hai:

#!/bin/zsh
((count = 10)) # Số tối đa để thử.


while [[ $count -ne 0 ]] ; làm
    /usr/bin/ping -c 1 8.8.8.8 >> /root/loadrc/crontab.log 2>&1
    tiếng vang "bước -> 2" >> /root/loadrc/crontab.log
    rc=$?

Đúng như lựa chọn cá nhân của tôi, tôi muốn kết hợp mã từ hai tập lệnh này (ping.shauto_reboot.sh) thành một tập lệnh vì nó có vẻ đơn giản hơn đối với tôi, nhưng bạn có thể có lý do chính đáng để thực hiện theo cách này và không có lý do gì nó không hoạt động nếu được thực hiện đúng cách.

huangyingw avatar
lá cờ id
cảm ơn câu trả lời của bạn, vâng, tôi đã tìm ra lý do, tôi cần sử dụng đường dẫn đầy đủ của lệnh khởi động lại. Tôi đã tách logic thành ping.sh, để sử dụng lại tốt hơn, có thể các tập lệnh khác của tôi có thể cần đến nó. đó là linux không đầu cá nhân của tôi chỉ để giải trí, vì vậy, tôi luôn đăng nhập bằng root, cron và script đều chạy bằng root. một câu hỏi tiếp theo: nếu tôi (root) chưa đăng nhập, liệu root cron có thực hiện công việc của nó không? những gì tôi muốn là một cron, thậm chí không có người dùng nào (kể cả root) đăng nhập, nó vẫn sẽ chạy thường xuyên và kiểm tra trạng thái mạng và khởi động lại nếu cần. @seamus
Seamus avatar
lá cờ il
@huangyingw: *"`một câu hỏi tiếp theo: nếu tôi (root) chưa đăng nhập, liệu cron gốc có thực hiện công việc của nó không? `"* Có - `cron` là một *daemon* chạy trong nền mà không có sự can thiệp của người dùng cần thiết; mục đích duy nhất của nó là chạy các công việc ngay cả khi người dùng chưa đăng nhập.
huangyingw avatar
lá cờ id
thật tuyệt khi nghe, cảm ơn. @seamus
Seamus avatar
lá cờ il
@huangyingw: Không có gì - và đừng quên [bỏ phiếu cho bất kỳ câu trả lời nào bạn thấy *hữu ích* và *chọn* một câu trả lời](https://serverfault.com/help/someone-answers) nếu thích hợp .

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.