You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用systemd/networkctl在特定网络接口进入routable状态时执行脚本?

如何利用systemd/networkctl在特定网络接口进入routable状态时执行脚本?

我来给你几个亲测靠谱的方案,专门解决你遇到的这个棘手问题——设备始终处于active状态,没法靠device单元触发,sysfs的path单元也不生效的情况:

方法一:用systemd-networkd-dispatcher直接对接状态事件

这是最精准的方式,因为systemd-networkd本身就会把接口状态变化的事件派发给dispatcher目录里的脚本,完全不需要你自己轮询:

  • 先给目标状态创建对应的目录(routable状态的专属目录):
    sudo mkdir -p /etc/systemd/networkd-dispatcher/routable.d
  • 在这个目录里创建你的触发脚本,文件名开头可以加数字控制执行优先级(比如99-my-interface-script.sh):
    #!/bin/bash
    # 替换成你要监控的接口名,比如eth0、wlan0
    TARGET_IF="eth0"
    if [ "$INTERFACE" = "$TARGET_IF" ]; then
        # 这里写你要执行的具体逻辑
        echo "[$(date)] 接口$TARGET_IF进入routable状态,执行脚本" >> /var/log/interface-trigger.log
        # 比如调用你自己的脚本:/path/to/your/custom-script.sh
    fi
    
  • 给脚本加上可执行权限:
    sudo chmod +x /etc/systemd/networkd-dispatcher/routable.d/99-my-interface-script.sh
  • 重启dispatcher服务让配置生效:
    sudo systemctl restart systemd-networkd-dispatcher.service
    之后每次你的接口进入routable状态,这个脚本就会自动触发,完全不用管设备是不是一直active。

方法二:自定义systemd服务+状态监听脚本

如果需要更灵活的逻辑(比如监听状态变化的整个过程),可以写一个简单的监听脚本配合systemd服务:

  • 先创建监听脚本/usr/local/bin/watch-interface-routable.sh:
    #!/bin/bash
    TARGET_IF="$1"
    if [ -z "$TARGET_IF" ]; then
        echo "请传入目标接口名作为参数"
        exit 1
    fi
    
    # 循环监听接口状态
    while true; do
        # 用networkctl获取当前接口状态
        CURRENT_STATE=$(networkctl status "$TARGET_IF" | awk '/State:/ {print $2}')
        if [ "$CURRENT_STATE" = "routable" ]; then
            # 执行你的自定义逻辑
            /path/to/your/script.sh
            # 如果只需要触发一次,就加break;如果要持续监听状态变化(比如从routable变其他再变回来再触发),就删掉break
            break
        fi
        sleep 2  # 每2秒检查一次,可根据需求调整间隔
    done
    
  • 给脚本加执行权限:
    sudo chmod +x /usr/local/bin/watch-interface-routable.sh
  • 创建systemd服务文件/etc/systemd/system/interface-routable-trigger.service:
    [Unit]
    Description=监听指定接口进入routable状态并执行脚本
    After=systemd-networkd.service
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    # 替换成你的接口名
    ExecStart=/usr/local/bin/watch-interface-routable.sh eth0
    # 如果需要重新触发检查,可以用systemctl reload这个服务
    ExecReload=/usr/local/bin/watch-interface-routable.sh eth0
    
    [Install]
    WantedBy=multi-user.target
    
  • 启用并启动服务:
    sudo systemctl enable --now interface-routable-trigger.service

一些小提醒

  • 所有脚本都必须设置可执行权限,否则systemd或dispatcher没法运行它们
  • 用networkd-dispatcher时,文件名开头的数字决定执行顺序,数字越大越晚执行,比如00-开头的会先于99-开头的脚本
  • 测试的时候可以用networkctl down eth0 && networkctl up eth0手动切换接口状态,验证脚本是否正常触发

备注:内容来源于stack exchange,提问作者Jochen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 07:53:03