Linux配置 自启动,碰到一些问题

news/2024/7/5 7:38:52

最近在搞一个arm-linux,发现自动运行与手动运行,竟然效果是不一样,在解决问题的同时,也顺便把Linux启动相关一些知识梳理一遍。

  • 问题1:在/etc/init.d/ 新建一个S90startapp, 并且添加启动程序的路径。

此时,会发现该程序启动失败,并提示如下信息:

qt.qpa.plugin: Could not find the Qt platform plugin "eglfs" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: linuxfb, minimal, offscreen, vnc, wayland-egl, wayland.

大概的意思:程序是Qt的,不能 在wayland下运行程序

如果将启动链接放在S50launcher 里面,是可以正常启动的。

那么问题来了,如果添加自定义启动配置,要怎么配置。

先来看看,可以使用的S90startapp 配置 :

#
# Start app launcher...
#

case "$1" in
  start)
                printf "Starting Application launcher: "         

                export XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/var/run}
                export QT_QPA_PLATFORM=${QT_QPA_PLATFORM:-wayland}  #关键是这句话,要添加环境变量
                            
                /userdata/tmp/AppServer &
                
        ;;
  stop)
                killall AppServer               
                printf "stop finished"
        ;;
  *)
        echo "Usage: $0 {start|stop}"
        exit 1
        ;;
esac
exit 0

时间解决的关键是要添加:

export QT_QPA_PLATFORM=${QT_QPA_PLATFORM:-wayland}

当然如果偷懒,这个环境变量放在 /etc/profile 里也是可以(这样就是全局行为)

奇怪的是,明明在S50launcher里面以及设置过该环境变量,这里为什么还要设置?

这个就是要关于 export这个命令,如果是该shell下执行的export 也就是仅仅该shell下生效,当切换或重新打开shell,那么export之后的内容都是无效的。

Linux,一般来说都是通过rcS来加载Sxx的启动脚本。因此,分析下rcS:

#!/bin/sh


# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do

     # Ignore dangling symlinks (if any).
     [ ! -f "$i" ] && continue

     case "$i" in
        *.sh)
            # Source shell script for speed.
            (
                trap - INT QUIT TSTP
                set start
                . $i
            )
            ;;
        *)
            # No sh extension, so fork subprocess.
            $i start   #这里,也就是说每加载一个Sxx文件,会调用该脚本的start,每次都是fork subprocess方式加载(重新开启进程)
            ;;
    esac
done

说明:环境变量是不通用的,也不存在继承关系,前面执行过的脚本配置,在后面不一定起作用

知道原理,其实就好解决了,疑惑也解开了。

梳理:

  1. 系统启动后,执行/etc/init.d/rcS
  2. rcS 加载 /etc/init.d/S?? 开头脚本。每次都是fork方式加载
  3. 因此如果临时修改环境变量,那么仅对本脚本生效
  4. 可以将环境变量放在 /etc/profile
  • 问题2:自动其他程序的时候,会出现如下warning:

sh: warning: setlocale: LC_ALL: cannot change locale (zh_CN.utf8)

大概意思,在shell下不能切换本地语言为zh_CN.utf8

实测:这句话,仅仅是warning,对功能并不影响(也不影响qt界面显示中文);

网上也搜索一堆,但都是要装个语言包之类的,显然不是arm-linux下解决办法。

竟然是应用程序引起这个warning,所以花了点时间,找下哪个fun产生的。通过不懈努力,后来发现

每当执行一边:popen,就会触发以上warn信息

FILE *pp = popen(cmd, "r");

翻阅了网上一些资料,发现popen是启动 sh -c 执行对应CMD的,也就是fork 出子进程方式进行,由于此时fork跟父进程一致,才导致该warning出现

解决办法:反正cmd也不会用到中文的,

索性就用:LC_ALL=C 就可以了。也就是说在S50launcher 里export LC_ALL=C就可以

扩展S50launcher知识:

#
# Start linux launcher...
#

# Load default env variables from profiles(e.g. /etc/profile.d/weston.sh)
. /etc/profile    #将profile里设置

case "$1" in
  start)
                printf "Starting launcher: "
                export LC_ALL=C    #设置语言,也就是本shell生效
                #export LC_ALL='zh_CN.utf8'  #原先设置

                # Uncomment to disable mirror mode
                # unset WESTON_DRM_MIRROR

                export XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/var/run}
                export QT_QPA_PLATFORM=${QT_QPA_PLATFORM:-wayland}  #设置qt运行在wayland
                echo 3 > /sys/class/graphics/fb0/blank

                weston --tty=2 --idle-time=0&
                {
                        # Wait for weston ready
                        while [ ! -e ${XDG_RUNTIME_DIR}/wayland-0 ]; do
                                sleep .1   #等待wayland启动成功
                        done
                        #/usr/bin/QLauncher &     #原先桌面程序,可以屏蔽掉                    
                        #/userdata/tmp/AppServer &  #添加自己的启动程序
                        echo 0 > /sys/class/graphics/fb0/blank   
                }&
        ;;
  stop)
                killall AppServer   #当系统重启或退出的时候,调用stop
                killall weston
                printf "stop finished"
        ;;
  *)
        echo "Usage: $0 {start|stop}"
        exit 1
        ;;
esac
exit 0

梳理:

当系统启动时候,调用 /etc/init.d/rcS 然后调用各个Sxx 的脚本 "start)"

当系统推出时候,调用 /etc/init.d/rcK 然后调用各个Sxx脚本的 "stop)"


http://lihuaxi.xjx100.cn/news/903459.html

相关文章

论文投稿指南——中文核心期刊推荐(社会学)

【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…

剑指Offer专项突击版题解八

71.按权重生成随机数 思考:说到平均的生成随机数,想到了水塘抽样法和彩票调度法。 水塘抽样算法适合于样本不确定,乃至于是变化的,每个样本的概率是一样的。 // 样本nums[],每个元素的被抽到的概率是一样的 index : 0 for i : 1;…

(十五)、从插件市场引入问题反馈页面【uniapp+uinicloud多用户社区博客实战项目(完整开发文档-从零到完整项目)】

1,插件市场问题反馈页面 插件市场链接 dloud插件插件市场中找到问题反馈插件: 首先确保登录了dcloud账号。 使用hbuilderX导入插件到自己项目中。 选择合并导入。 从插件市场导入意见反馈页面的路径地址如下: 2,点击跳转到…

千锋教育嵌入式物联网教程之系统编程篇学习-04

目录 alarm函数 raise函数 abort函数 pause函数 转折点 signal函数 可重入函数 信号集 sigemptyset() sigfillset sigismember()​ sigaddset()​ sigdelset()​ 代码讲解 信号阻塞集 sigprocmask()​ alarm函数 相当于一个闹钟,默认动作是终止调用alarm函数的进…

时序预测 | Python实现TCN时间卷积神经网络时间序列预测

时序预测 | Python实现TCN时间卷积神经网络时间序列预测 目录 时序预测 | Python实现TCN时间卷积神经网络时间序列预测预测效果基本介绍环境准备模型描述程序设计学习小结参考资料预测效果 基本介绍 递归神经网络 (RNN),尤其是 LSTM,非常适合时间序列处理。 作为研究相关技术…

New和Malloc的使用及其差异

1,new的使用关于new的定义:new其实就是告诉计算机开辟一段新的空间,但是和一般的声明不同的是,new开辟的空间在堆上,而一般声明的变量存放在栈上。通常来说,当在局部函数中new出一段新的空间,该…

华为OD机试 - 最短耗时(JS)

最短耗时 题目 给定一个正整型数组表示待系统执行的任务列表, 数组的每一个元素代表一个任务,元素的值表示该任务的类型。 请计算执行完所有任务所需的最短时间。 任务执行规则如下: 任务可以按任意顺序执行,且每个任务执行耗时间均为1个时间单位。两个同类型的任务之间必…

Java面向对象的特性:封装,继承与多态

Java面向对象的特性 在学习Java的过程是必须要知道的Java三大特性:封装、继承、多态。如果要分为四类的话,加上抽象特性。 封装 1.封装概述 是面向对像三大特征之一(封装,继承,多态) 是面向对象编程语言对客…