开发环境 :
处理器: AM335x
SDK:06_03_00_106
一设置程序开机自启动
1、编写测试程序
1)编写测试程序 test.c
#include <stdio.h>
#include <unistd.h>
void main () {
while (1) {
printf("this is a test programmer !\n");
sleep(1);
}
}
2) 生成可执行文件 test ,并拷贝到板子的 “/usr/share/” 目录下;
2、创建启动脚本
1)进入 “/etc”目录下,创建脚本文件 “rc.local”,脚本内容如下:
#!/bin/sh
start() {
/usr/share/test & #在这里添加要开机启动的程序
}
stop() {
killall test
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "valid arg:[start|stop|restart]"
;;
esac
exit 0
2)添加可执行权限
root@am335x:/etc# chmod u+x /etc/rc.local
3)重新启动系统,查看 test 程序 是否运行
[ OK ] Mounted /run/media/mmcblk0p2.
[ OK ] Mounted /run/media/mmcblk0p1.
https://blog.csdn.net/u010354054
am335x login: root
root@am335x:~# ps -aux | grep test
root 165 0.0 0.4 1712 1040 ? S 04:31 0:00 /usr/share/test
root 705 0.0 0.6 3304 1520 ttyO0 S+ 04:32 0:00 grep test
root@am335x:~#
这里我们可以看到 “/usr/share/test” 的程序已经在后台运行了。
3、原因详解
具体的systemd 的使用,网上的资料大把大把的,这里我不在做过多的说明。
1)首先我们看一下," /lib/systemd/system/rc-local.service " 的单元文件:
root@am335x:/lib/systemd/system# cat rc-local.service
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if /etc/rc.local is executable.
[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no
2)该注释中有一段说明如下:
# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if /etc/rc.local is executable.
3)具体意思如下:
如果 /etc/rc.local 是可以被执行的文件,那么 rc-local.service 会被
systemd-rc-local-generator 自动放入到 multi-user.target 目标当中。所以这里,我们只要创 rc.local 文件,并赋予其执行权限,系统启动后会自动执行这个脚本,那么这个脚本的内容中就是执行我们要上电启动的程序。
4、参考链接
参考链接
1.https://blog.csdn.net/sayyy/article/details/79276575
2.https://my.oschina.net/StupidZhe/blog/4411429
二、实现程序自启动后,打印(printf)输出信息
1、具体操作
- 根据第一章节中,调用我们开机程序 test 的服务是 “rc-local.service” 服务。所以,这里我们打开 "/lib/systemd/system/rc-local.service " 文件,并在 “[Service]” 添加下面这句话:
StandardOutput=tty
- 添加完成后的 “rc-local.service”,如下:
#....略去部分注释
# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if /etc/rc.local is executable.
[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no
StandardOutput=tty
- 重启系统,观察终端是否显示"this is a test programmer !"(test 程序中有这句话输出):
[ OK ] Started Getty on tty1.
[ OK ] Started NFS status monitor for NFSv2/3 locking..
[ OK ] Started Serial Getty on ttyO0.
[ OK ] Started thermal-zone-init.service.
https://blog.csdn.net/u010354054
this is a test programmer !
am335x login: this is a test programmer !
this is a test programmer !
https://blog.csdn.net/u010354054
am335x login: this is a test programmer !
rootthis is a test programmer !
[ 31.128168] EXT4-fs (mmcblk0p2): mounting ext3 file system using the ext4 subsystem
[ 31.249616] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
this is a test programmer !
root@am335x:~# this is a test programmer !
killthis is a test programmer !
allthis is a test programmer !
test
this is a test programmer !
root@am335x:~#
这里我们会发现,重启系统后一直在打印 信息,直到 杀死 test 进程。
2、知识解析
1.systemd 文件系统中,日志的查看需要通过 “journalctl” 命令去查看。所以,默认所有的服务均可 必须通过journalctl -u [service name] 去查看。
执行" journalctl -u rc-local" 来查看 rc-local.serivce 的日志记录:
root@am335x:~# journalctl -u rc-local
-- Logs begin at Sun 2020-04-19 07:05:10 UTC, end at Sun 2020-04-19 07:07:44 UTC. --
Apr 19 07:05:17 am335x systemd[1]: Starting /etc/rc.local Compatibility...
Apr 19 07:05:20 am335x systemd[1]: Started /etc/rc.local Compatibility.
Apr 19 07:07:44 am335x rc.local[240]: this is a test programmer !
Apr 19 07:07:44 am335x rc.local[240]: this is a test programmer !
root@am335x:~#
2.指定标准输出
首先这里说一下,指定systemd的标准输出(其他的不做讲解,后面会给出参考的链接,大家可以自己去查)通过参数 StandardOutput=
来指定的,其后可以跟以下几个参数: null, tty, journal, syslog, kmsg等(还可以跟更多的参数,这里就不详举了,更详细的请移步金步国)。
null 表示 /dev/null , 也就是所有输出都会被丢弃。
tty : TTY(由 TTYPath= 设置)。 如果仅用于输出,那么进程将无需取得终端的控制权, 亦无需等待其他进程释放终端控制权。
journal :systemd 日志服务(通过 journalctl访问)。
注意,所有发到 syslog 或 kmsg 的日志都会隐含的复制一份到 journal 中。
syslog :日志服务。
注意,此时所有日志都会隐含的复制一份到 journal 中。
kmsg :内核日志缓冲区(通过 dmesg 访问)。
注意,此时所有日志都会隐含的复制一份到 journal 中。
所以,这里我们指定StandardOutput=tty
就可以让程序自启动后并通过终端打印出信息
3、参考链接
1、金步国作品集
2、https://www.thinbug.com/q/37585758
3、https://qastack.cn/unix/20399/view-stdout-stderr-of-systemd-service