启动时运行脚本时没有输出(但如果手动运行则输出正确)

启动时运行脚本时没有输出(但如果手动运行则输出正确)

我最近给自己买了一台 Raspberry Pi 2,以便在业余时间学习一些东西。它现在在 Raspbian 上运行,我通过安装了 Linux Mint 17.2 的笔记本电脑通过 ssh 远程控制它。

现在我希望 Pi 在重新启动后自动告诉笔记本电脑它处于在线状态,以便我知道我可以通过 ssh 连接到它。我知道我可以等待几秒钟或对 Pi 执行 ping 操作,但不知何故,我想到如果笔记本电脑上的终端中弹出一条小消息,那就太好了。

到目前为止,经过一些修补后我得到的结果如下(我对此非常陌生,所以我什至不知道这可能是严重错误的级别):

/usr/bin/ssh 'laptop_user'@'laptop_ip' "echo '### RaspberryPi 2 online ###' | /usr/bin/write 'laptop_user' pts/0"

如果我的笔记本电脑有IP“laptop_ip”并且“laptop_user”已登录pts/0(很多if,但我想在我得到最初的想法并运行之后我会得到这些),那么当在Pi上的终端中运行时,这是有效的)。在笔记本电脑终端上类似

Message from 'laptop_user'@'laptop_host' on pts/0 at 09:58:
### RaspberryPi 2 online ###
EOF

出现。 (是的!)

然后我将命令放入一个小脚本中:

#! /bin/sh
/usr/bin/ssh 'laptop_user'@'laptop_ip' "echo '### RaspberryPi 2 online ###' | /usr/bin/write 'laptop_user' pts/0"
exit 0

将其保存/etc/network/if-up.d/sayhi在 Pi 上,并使其可执行(遵循最佳答案)这个问题)。我检查了这个脚本确实在每次树莓派重新启动后执行。问题是,如果我手动运行脚本,一切都会正常,并且我会在笔记本电脑终端上收到消息。但是,如果脚本在重新启动时自动执行,我不会收到该消息。将命令放入rc.localorcrontab也不起作用。

不幸的是,我不知道 Pi(或任何计算机)的启动实际上是如何工作的。所以我不知道这个命令所需的服务是否已经准备好。

所以我的问题是:

当脚本自动运行时,为什么我没有收到“在线”消息,以及何时应该运行我的小脚本来实现所需的行为。

此外,可能还有比我的方法更好的替代方案。因此,如果有人能指出我正确的方向,我将不胜感激。

提前致谢!

编辑:

  • 我忘记提及我正在使用密钥身份验证,并且由于脚本将作为 Pi 运行,所以root我将其公共 RSA 密钥添加到authorized_keys笔记本电脑上,并使用私钥作为命令的标识文件ssh

  • /sbin/ip addr我现在正在记录启动时运行脚本时的输出,如果给我:

    eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether b8:27:eb:34:66:ce brd ff:ff:ff:ff:ff:ff

    稍后运行脚本(通过 ssh 手动)时/sbin/ip addr会给出:

    eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether b8:27:eb:34:66:ce brd ff:ff:ff:ff:ff:ff inet 192.168.0.105/24 brd 192.168.0.255 scope global eth0 valid_lft forever preferred_lft forever

    所以问题似乎是 Pi 在运行脚本时没有本地 IP /etc/network/if-up.d。我现在必须在分配 IP 后运行我的脚本。不幸的是,我对网络了解不够,无法做到这一点。

答案1

这很可能是因为您的启动脚本默认在根环境中运行。假设您使用~/.ssh/id_rsa.pub作为身份验证模式(你从来没有提到你正在使用密码,并且使用这样的东西,而自动化通常是一个坏主意,所以我假设密钥身份验证)

然后我将继续假设您还没有允许(甚至没有)生成在您的笔记本电脑上受信任的根密钥?

在这种情况下,您有两种选择。

  1. 以 root 身份运行ssh-keygen,并将 的内容复制 /root/.ssh/id_rsa.pub到您的/home/<user>/.ssh/authorized_keys文件中。

或者

  1. 将你的命令更改为/usr/bin/ssh -i /home/<user>/.ssh/id_rsa.pub 'laptop_user'@'laptop_ip' "echo '### RaspberryPi 2 online ###' | /usr/bin/write 'laptop_user' pts/0"

第二个更简洁,因为它使用您已经知道有效的用户证书。

debian启动顺序和网络连接问题

最有可能(在阅读您的评论后)这是一个脚本启动顺序问题,这意味着您的脚本在betwork network.d 上运行,有机会为您的接口分配 DHCP 并将其启动。

即使rc.local是在追赶,network.target但这与抱歉地说不一样network-online.target

您在这里再次有几个选项,其中之一就是简单地将其添加到您的crontab行中:

@reboot sleep 60 && /usr/bin/ssh -i /home/<user>/.ssh/id_rsa.pub 'laptop_user'@'laptop_ip' "echo '### RaspberryPi 2 online ###' | /usr/bin/write 'laptop_user' pts/0"

这将使您的命令在执行 SSH 命令之前休眠 60 秒。
这不是世界上最漂亮的东西,但如果你不关心随之而来的实时“通知”,它很快而且很有效。

如果您想要更可靠的选择,我建议您创建一个init.d具有目标要求的脚本,network-online.target该脚本在网络上线之前不会触发您的初始化脚本。这是最快、最可靠的选择。

我使用systemd所以无法编写或验证正确的init.d脚本 atm,请尝试遵循本指南并查看它是否有效:https://www.debian-administration.org/article/28/Making_scripts_run_at_boot_time_with_Debian

答案2

您需要告诉ssh在目标盒子上创建一个终端设备,这样write才能工作。您可以使用-t标志来执行此操作。两次。

ssh -tt 'laptop_user'@'laptop_ip' "echo '### RaspberryPi 2 online ###' | /usr/bin/write 'laptop_user' pts/0"

相关内容