Debian-一旦有可供使用的互联网连接,如何在启动时运行脚本?


14

我正在运行Debian 7 Wheezy,并且一旦有功能正常的互联网连接,就需要在启动时启动一些屏幕。但是,如果互联网连接断开并重新连接,则不会。因此,仅在启动后的第一个功能性互联网连接上。

您能否为此发布一个虚拟脚本,并告诉我在指定条件下可以放置它的位置?

该脚本仅需要启动屏幕然后终止,但是屏幕应该继续。


编辑 我已经听说过该/etc/network/if-up.d/文件夹。但是,如果失去互联网连接然后重新建立连接,该如何确保脚本不会再次执行?


@Celada请参阅编辑
MinecraftShamrock

Answers:


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.

服务器关闭时会删除标志文件吗?
MinecraftShamrock,2014年

1
是的,因为在Debian上/var/run是易失性文件系统(a tmpfs)。因此,可以确保在每次启动时都会清空。
Celada 2014年

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 2014年

3
@MinecraftShamrock如果按原样使用Celada的脚本,则在回送接口出现时,您的代码将立即运行。如果要等待Internet连接,请至少检查IFACE是否不是lo-或某些虚拟接口-或更佳,通过ping测试Internet连接。
吉尔斯(Gilles)'所以

1
@MinecraftShamrock $IFACE可以将出现的任何接口作为值。您可以列出存在的所有接口,ip link或查看哪些接口配置为通过扫描启动/etc/network/interfaces
Celada 2014年

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在bash脚本的顶部添加然后运行,systemctl status my_service可能有助于确定脚本失败的原因。通常,始终对所有内容使用绝对路径echo,或通过添加明确定义$ PATH Environment=MYVAR=abc


2

互联网连接/etc/rc6.d/可能由中的一个条目建立S35networking。如果您更改该文件并在末尾插入命令,或者最好添加/etc/init.d/mystuff和链接/etc/rc0.d/S36mystuff到该文件,然后在其中插入命令,则该命令将在网络启动后立即开始。


如果连接丢失然后重新建立,是否会调用?因为否则我可以将脚本放入/etc/network/if-up.d
MinecraftShamrock 2014年

不,这只是在启动时
Anthon 2014年

1
那会起作用,但是为了正确起见,让我指出/etc/rc0.d在启动时不会运行任何脚本,而在关机时会运行(运行级别0)。在启动时,它将是/etc/rc2.d类似的东西。专门针对OP的Debian狂风,它是/etc/rcS.d/S12networking。当然,所有符号链接到同一个文件。另外BTW @Anthon感谢您修正我的回答:“请”而不是“放置”?真是错字!
Celada 2014年

@Celada你的权利是我(非Debian系统)上的rc6。我不确定您是否要在其中“请放”,但“放”似乎更脆。顺便说一句,我对您的回答表示赞同,这是一种更好的联网方法,因为它具有if-up.d通用的机制,也可用于重新连接。
Anthon 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.