Debian - วิธีการเรียกใช้สคริปต์เมื่อเริ่มต้นทันทีที่มีการเชื่อมต่ออินเทอร์เน็ตพร้อมใช้งาน?


14

ฉันใช้ Debian 7 Wheezy และฉันต้องเริ่มต้นบางหน้าจอเมื่อเริ่มต้นทันทีที่มีการเชื่อมต่ออินเทอร์เน็ตที่ใช้งานได้อย่างสมบูรณ์ อย่างไรก็ตามไม่ใช่หากการเชื่อมต่ออินเทอร์เน็ตล่มและเชื่อมต่ออีกครั้ง ดังนั้นเฉพาะการเชื่อมต่ออินเทอร์เน็ตที่ใช้งานได้ครั้งแรกหลังจากบูต

คุณช่วยโพสต์สคริปต์หุ่นจำลองเรื่องนี้และบอกฉันว่าจะเอาไปที่ไหนและทำให้มันถูกดำเนินการภายใต้เงื่อนไขที่กำหนด?

สคริปต์จำเป็นต้องเริ่มต้นหน้าจอจากนั้นยกเลิก แต่หน้าจอควรดำเนินการต่อไป


แก้ไข ฉันได้ยินชื่อ/etc/network/if-up.d/โฟลเดอร์แล้ว แต่ฉันจะแน่ใจได้อย่างไรว่าสคริปต์จะไม่ถูกเรียกใช้อีกครั้งหากการเชื่อมต่ออินเทอร์เน็ตขาดหายไปจากนั้นสร้างใหม่อีกครั้ง


@ Celada โปรดดูการแก้ไข
MinecraftShamrock

คำตอบ:


21

ใส่สคริปต์ของคุณ/etc/network/if-up.dและทำให้มันสามารถเรียกใช้งานได้ มันจะทำงานโดยอัตโนมัติทุกครั้งที่มีการเชื่อมต่อเครือข่าย

เพื่อให้มันทำงานได้เฉพาะในครั้งแรกที่มันถูกเรียกใช้ในการบู๊ตทุกครั้งให้ตรวจสอบว่ามีไฟล์แฟล็กที่คุณสร้างขึ้นหลังจากครั้งแรก ตัวอย่าง:

#!/bin/sh

FLAGFILE=/var/run/work-was-already-done

case "$IFACE" in
    lo)
        # The loopback interface does not count.
        # only run when some other interface comes up
        exit 0
        ;;
    *)
        ;;
esac

if [ -e $FLAGFILE ]; then
    exit 0
else
    touch $FLAGFILE
fi

: here, do the real work.

flagfile จะถูกลบเมื่อเซิร์ฟเวอร์ปิดหรือไม่
MinecraftShamrock

1
ใช่เพราะใน Debian /var/runเป็นระบบไฟล์ที่เปลี่ยนแปลงได้ (กtmpfs) ดังนั้นจึงรับประกันว่าจะว่างเปล่าในทุกการบูต
Celada

1
จับดี. ฉันคิดว่าคุณจะต้องโชคร้ายจริงๆ แต่ฉันคิดว่าใช่เพราะอินเทอร์เฟซแบบเสียบร้อนที่สามารถนำขึ้นมาพร้อมกัน ดังนั้นฉันคิดว่าคุณสามารถทำได้แบบอะตอมมิแทนการทดสอบแล้วสร้างซึ่งจะทำให้ปลอดภัย แต่สิ่งที่ฉันเกิดขึ้นจากส่วนบนของหัวของฉันไม่สวย! python -c 'import os; os.open("/var/run/work-was-already-done", os.O_EXCL|os.O_CREAT, 0)' 2>/dev/null || exit 0
Celada

3
@MinecraftShamrock หากคุณใช้สคริปต์ของ Celada ตามที่เป็นอยู่รหัสของคุณจะทำงานทันทีที่อินเทอร์เฟซแบบวนรอบปรากฏขึ้น หากคุณต้องการรอการเชื่อมต่ออินเทอร์เน็ตอย่างน้อยให้ตรวจสอบว่าIFACEไม่ใช่lo- หรืออินเทอร์เฟซเสมือน - หรือดีกว่าให้ทดสอบการเชื่อมต่ออินเทอร์เน็ตโดยการกระตุก
Gilles 'หยุดความชั่วร้าย'

1
@MinecraftShamrock $IFACEสามารถมีค่าเป็นอินเตอร์เฟสใด ๆ ที่เกิดขึ้น คุณสามารถแสดงรายการอินเทอร์เฟซทั้งหมดที่มีอยู่ด้วยip linkหรือดูว่ามีการกำหนดค่าใดที่จะถูกนำขึ้นมาด้วยการสแกน/etc/network/interfaces
Celada

9

systemdนี่คืองานที่เหมาะสมเป็นอย่างดีสำหรับ

การรันสคริปต์เป็นเซอร์วิส systemd

หากระบบของคุณกำลังเรียกใช้systemdคุณสามารถกำหนดค่าสคริปต์ของคุณให้ทำงานเป็นบริการ systemd ซึ่งให้การควบคุมสภาพแวดล้อมรอบการทำงานและการดำเนินการรวมถึงเงื่อนไขเบื้องต้นสำหรับการเริ่มต้นสคริปต์เช่นเครือข่ายกำลังทำงานอยู่

โฟลเดอร์ที่แนะนำสำหรับบริการของคุณคือ/etc/systemd/system/(ตัวเลือกอื่นคือ/lib/systemd/systemแต่ควรใช้สำหรับบริการ OOTB เท่านั้น)

สร้างไฟล์เช่นด้วยsudo vim /etc/systemd/system/autossh.service:

[Unit]
# By default 'simple' is used, see also https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=
# Type=simple|forking|oneshot|dbus|notify|idle
Description=Autossh keepalive daemon
## make sure we only start the service after network is up
Wants=network-online.target
After=network.target

[Service]
## here we can set custom environment variables
Environment=AUTOSSH_GATETIME=0
Environment=AUTOSSH_PORT=0
ExecStart=/usr/local/bin/ssh-keep-alive.sh
ExecStop=pkill -9 autossh
# don't use 'nobody' if your script needs to access user files
# (if User is not set the service will run as root)
#User=nobody

# Useful during debugging; remove it once the service is working
StandardOutput=console

[Install]
WantedBy=multi-user.target

ตอนนี้คุณสามารถทดสอบบริการ:

sudo systemctl start autossh

การตรวจสอบสถานะของบริการ:

systemctl status autossh

หยุดบริการ:

sudo systemctl stop autossh

เมื่อคุณยืนยันว่าบริการใช้งานได้ตามที่คาดไว้ให้เปิดใช้งานด้วย:

sudo systemctl enable autossh

หมายเหตุ: เพื่อจุดประสงค์ด้านความปลอดภัยsystemdจะเรียกใช้สคริปต์ในสภาพแวดล้อมที่ จำกัด คล้ายกับวิธีการcrontabเรียกใช้สคริปต์ดังนั้นอย่าคาดเดาเกี่ยวกับตัวแปรระบบที่มีอยู่ก่อนเช่น $ PATH ใช้Environmentปุ่มต่างๆหากสคริปต์ของคุณต้องการกำหนดตัวแปรเฉพาะ การเพิ่มset -xที่ด้านบนสุดของสคริปต์ทุบตีของคุณจากนั้นเรียกใช้systemctl status my_serviceอาจช่วยระบุสาเหตุที่สคริปต์ของคุณล้มเหลว ตามกฎของ tumb ที่มักจะใช้เส้นทางที่แน่นอนสำหรับทุกอย่างรวมทั้งechoหรือกำหนดอย่างชัดเจน $ Environment=MYVAR=abcเส้นทางของคุณโดยการเพิ่ม


2

การเชื่อมต่ออินเทอร์เน็ตจะนำขึ้นมาจากรายการในอาจ/etc/rc6.d/ S35networkingหากคุณเปลี่ยนไฟล์นั้นและใส่คำสั่งของคุณในตอนท้ายหรือดีกว่าเพิ่ม/etc/init.d/mystuffและเชื่อมโยง/etc/rc0.d/S36mystuffไปยังมันและแทรกคำสั่งของคุณที่นั่นนั่นจะเริ่มขึ้นทันทีที่เครือข่ายทำงาน


มันจะถูกเรียกใช้หรือไม่หากการเชื่อมต่อขาดหายไป เพราะมิฉะนั้นฉันก็สามารถใส่สคริปต์เข้าไป/etc/network/if-up.d
MinecraftShamrock

ไม่นี่เป็นเพียงการเริ่มต้น
Anthon

1
สิ่งนี้จะใช้ได้ แต่สำหรับความถูกต้องให้ฉันชี้ให้เห็นว่าไม่มีสคริปต์ใน/etc/rc0.dจะทำงานเมื่อเริ่มต้นพวกเขาจะทำงานเมื่อปิด (รันระดับ 0) เมื่อเริ่มต้นมันจะเป็นสิ่งที่/etc/rc2.dคล้ายกัน โดยเฉพาะสำหรับ OP ของ Debian ดังเสียงฮืด ๆ /etc/rcS.d/S12networkingก็ มันเชื่อมโยงไปยังไฟล์เดียวกันทั้งหมดแน่นอน BTW @ ด้วยขอบคุณสำหรับการแก้ไขคำตอบของฉัน: "ได้โปรด" แทน "ใส่"? ช่างเป็นอะไรที่แปลกประหลาด!
Celada

@ Celada ทางขวาของคุณคือ rc6 ในระบบของฉัน (ไม่ใช่เดเบียน) ฉันไม่แน่ใจว่าคุณต้องการ 'กรุณาใส่' ที่นั่น แต่เพียงแค่ "ใส่" ดูเหมือนกรอบมากขึ้น BTW ฉันยกระดับคำตอบของคุณเป็นเพียงวิธีการที่ดีกว่าสำหรับการเชื่อมต่อเครือข่ายเนื่องจากมันมีif-up.dกลไกทั่วไปที่ใช้ในการเชื่อมต่ออีกครั้ง
Anthon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.