当前自己使用的服务器内存比较小,需要扩容,只是服务器比较老了,内存扩展困难,但是服务器的负载并不高。因此可以尝试使用内存压缩的方式来适当扩展内存。
安装
软件包封装好了对应的东西(甚至是systemctl服务),并不需要自己写脚本
$ sudo apt install zram-config
重启之后,一个内存大小一半的 ZRAM 就出现了。
Ubuntu(友邦拓,网友也喜欢称之为“乌班图”)是一个以桌面应用为主的Linux操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想.
当前自己使用的服务器内存比较小,需要扩容,只是服务器比较老了,内存扩展困难,但是服务器的负载并不高。因此可以尝试使用内存压缩的方式来适当扩展内存。
软件包封装好了对应的东西(甚至是systemctl服务),并不需要自己写脚本
$ sudo apt install zram-config
重启之后,一个内存大小一半的 ZRAM 就出现了。
安装必要的依赖:
# 安装 podman $ sudo apt install podman # 准备本地目录映射 $ mkdir /home/data/.tomcat $ mkdir /home/data/.tomcat/webapps $ mkdir /home/data/.tomcat/logs
官方镜像会在报错的时候暴露 Tomcat 9 版本号,错误堆栈,构成安全隐患,我们需要通过构建自定义镜像解决此问题:
$ touch Dockerfile
内容如下:
# 详细启动日志在 /usr/local/tomcat/logs 目录下 From docker.io/library/tomcat:9 # xml 编辑工具,方便我们后续修改 tomcat 的xml配置文件 # RUN apt update && apt install -y xmlstarlet # 增加 <Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" /> 阻止错误日志输出 RUN sed -i "s/<\/Host>/ <Valve className='org.apache.catalina.valves.ErrorReportValve' showReport='false' showServerInfo='false' \/>\n\t<\/Host>/" /usr/local/tomcat/conf/server.xml # 配置AJP协议 # 如果只希望通过 AJP访问,可以参考如下命令 移除原有的 AJP 协议配置 # RUN xmlstarlet ed -L -P -S -d '/Server/Service/Connector' /usr/local/tomcat/conf/server.xml # 增加新的协议配置 RUN sed -i "s/<\/Service>/ <Connector port='8009' protocol='AJP\/1.3' address='0.0.0.0' redirectPort='8443' secretRequired=''\/>\n <\/Service>/" /usr/local/tomcat/conf/server.xml # 移除 xml 编辑工具 # RUN apt -y autoremove --purge xmlstarlet
构建镜像:
$ sudo podman build -t tomcat-9 .
设置容器开机自启:
$ sudo podman stop tomcat-9 $ sudo podman rm tomcat-9 # 启动一个 tomcat 容器 8080 HTTP 访问端口 8009 AJP访问端口 # sudo podman run -d --name tomcat-9 -p 8080:8080 -p 8009:8009 -v /my/local/path:/usr/local/tomcat/webapps localhost/tomcat-9 $ sudo podman run -d --name tomcat-9 -p 8080:8080 -p 8009:8009 -v /home/data/.tomcat/webapps:/usr/local/tomcat/webapps -v /home/data/.tomcat/logs:/usr/local/tomcat/logs localhost/tomcat-9 # 查看该容器 $ sudo podman ps # 如果需要进入容器查看执行情况,参考如下命令 # sudo podman exec -it tomcat-9 bash # 每次都启动新容器方式创建servcie //--new参数,每次启动都删除旧容器,启动一个新容器 $ sudo podman generate systemd --restart-policy=always -n --new -f tomcat-9
查看启动文件:
$ cat container-tomcat-9.service
内容如下:
# container-tomcat-9.service # autogenerated by Podman 3.4.4 # Sun Mar 10 12:31:31 CST 2024 [Unit] Description=Podman container-tomcat-9.service Documentation=man:podman-generate-systemd(1) Wants=network-online.target After=network-online.target RequiresMountsFor=%t/containers [Service] Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always TimeoutStopSec=70 ExecStartPre=/bin/rm -f %t/%n.ctr-id ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon --replace -d --name tomcat-9 -p 8080:8080 -p 8009:8009 -v /home/data/.tomcat/webapps:/usr/local/tomcat/webapps -v /home/data/.tomcat/logs:/usr/local/tomcat/logs localhost/tomcat-9 ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all [Install] WantedBy=default.target
Systemd 配置:
# 保存到/etc/systemd/system/ $ sudo mv container-tomcat-9.service /etc/systemd/system/ # 刷新配置文件,让其生效 $ sudo systemctl daemon-reload # 设置容器开机自启,并且现在启动 $ sudo systemctl enable --now /etc/systemd/system/container-tomcat-9.service # 如果需要进入容器查看执行情况,参考如下命令 # sudo podman exec -it tomcat-9 bash # 测试,重启虚拟机 $ sudo reboot # 启动或重启服务 # systemctl --user start container-tomcat-9.service # systemctl --user restart container-tomcat-9.service # 如果启动失败,观察服务日志 # sudo journalctl -f
后续 WAR 包存储到 /home/data/.tomcat/webapps 目录下即可进行正常访问。
最近家里安装降噪棉的时候使用了钉书钉,结果安装的时候,意外震坏了一块八年历史的老西数硬盘,造成数据丢失。
话说,西部数据的硬盘耐用性真的很成问题,家里至少已经坏了五块硬盘了,四块都是西部数据的。
于是另购了一块希捷的银河系列 16TB 硬盘,打算跟现存的一个刚刚替换的西部数据的 12TB 红盘(质保期之内坏了,走售后,花了一个多月换了一张盘,估计寿命也是堪忧),组一个 Raid 1 软阵列,到时候万一再有硬盘损坏,至少可以保住数据。
当前设备是使用 HP Gen8 上安装的 ubuntu 22.04.3 系统,四个盘位,其中两个从群晖上替换下来的 4TB 硬盘直接挂载到两个盘位上,依旧保持群晖的 Raid 1 软阵列。另外两个盘位,就是我们需要新组的软件 Raid 1 的位置了。
网上搜索了半天,都是需要通过命令行,逐个磁盘分区,分区之后再使用 mdadm 通过命令行组建阵列,虽然难度不大,但是操作比较繁琐,还是希望能在 UI 界面上点击一下鼠标搞定。
可以使用 storaged-project/blivet-gui 这个开源项目完成这个需求。
在云服务器 ECS Linux 系统中,通常我们在执行一些运行时间比较长的任务时,必须等待执行完毕才能断开 SSH 连接或关闭客户端软件,否则可能会导致执行中断。
本文介绍几种保障程序在用户退出登录后持续运行的方法。
nohup 的作用顾名思义,它使得后面的命令不会响应挂断(SIGHUP)信号。也就是说,通过远程登录执行 nohup 后,即使退出登录后,程序还是会正常执行。通常情况下,nohup 命令最后会跟上 & 字符,表示将这个命令放至后台执行,这样才能真正做到将这个命令放至后台持续的执行。
操作示例:
1. 正常的执行命令为 bash hello.sh,执行结果为每秒输出一行的小程序:
2. 在命令头尾分别加上 nohup 和 &,变为 nohup bash hello.sh &,可以看到 nohup 输出了一行信息,再按一下回车键就跳回了 shell 命令行,此时命令已经在后台执行了,nohup 将命令的输出重定向至当前目录的 nohup.out 文件中。同时注意到 nohup 会将对应程序的 PID 输出,PID 可用于需要中断进程时 kill 进程。
3. 通过 tail -f nohup.out 可以持续的查看 nohup.out 的输出,达到监视程序的效果。
4. 在命令中也可以使用重定向将程序的输出改为自己想要的文件名,如 nohup bash hello.sh >hello.log &,则程序的输出就会写到 hello.log 文件中。
5. 若程序不会自动退出,那么此时需要使用 kill 命令来结束进程。比如,可以使用命令 kill -TRM <PID> 来操作,其中 PID 即为之前 nohup 输出的值,在此例中该值为 1231。
使用限制:
nohup 通常用于执行无干预的自动化程序或脚本,无法完成带有交互的操作。
Linux 系统默认未自带 screen 工具,需要先进行安装:
1. 创建 screen 窗口
$ screen -S name # name可以设置为ssh、ftp,用于标注该 screen 窗口用途 # 示例: screen -S ftp
2. 列出 screen 进程,并进入所需 screen
$ screen -ls ##列出 screen 进程列表
然后进行所需操作,比如运行脚本、执行程序等等。
如下图示例:创建ftp连接后台下载传输文件
3. 退出保存
前述 ftp 操作示例开始传输后,在窗口中键入Ctrl+a 键,再按下 d 键,就可以退出 SSH 登录,但不会影响 screen 程序的执行。
4. 保存会话以便继续执行
可以利用 screen 这种功能来管理的远程会话。操作步骤概述:
家里运行了一些服务,希望在外面也可以方便的访问它们。
旧办法是通过路由器端口映射到内网端口,但这种方式已经很难满足我的场景,因为例如hadoop服务会开放很多web页面端口,实在难以逐一映射。
于是我选择了在家里自建VPN服务器,然后只把VPN服务的端口映射到路由器,这样只要在外面连接VPN即可像在家里一样任意访问内部网络了。
openconnect是开源VPN项目,包含了服务端和客户端(PC/MAC/Android),是商业产品思科cisco anyconnect的开源版本。
为什么选择它呢?因为它能够从服务端自定义下发路由规则到客户端,这样就可以控制客户端哪些流量需要送往VPN隧道、哪些流量不需要经过VPN隧道,实现类似于同时兼顾访问家庭内网和公司内网的目的。
搭建方式参考官方手册:https://gitlab.com/openconnect/recipes,我以debian为例进行安装配置,非常方便:
$ sudo apt-get update $ sudo apt-get install ocserv
这样就安装完成openconnect服务端了。
接下来配置VPN服务端,分为2大部分:
首先搞证书,按官方教程来即可:https://gitlab.com/openconnect/recipes/-/blob/master/ocserv-configuration-basic.md#certificate-management-self-signed
第一步:
$ mkdir ~/certificates $ cd ~/certificates
第二步(原样敲入即可,信息都不重要):
# vim ca.tmpl cn = "Your CA name" organization = "Your organization name" serial = 1 expiration_days = 3650 ca signing_key cert_signing_key crl_signing_key
第三步(原样敲入即可,信息都不重要):
# vim server.tmpl cn = "Your hostname or IP" organization = "Your organization name" serial = 2 expiration_days = 3650 signing_key encryption_key tls_www_server
第四步(生成CA证书):
$ certtool --generate-privkey --outfile ca-key.pem $ certtool --generate-self-signed --load-privkey ca-key.pem --template /etc/ssl/ca.info --outfile ca-cert.pem
第五步(用CA签VPN证书):
$ certtool --generate-privkey --outfile server-key.pem $ certtool --generate-certificate --load-privkey server-key.pem --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem --template server.tmpl --outfile server-cert.pem
把VPN证书拷到ocserv配置目录下:
$ sudo cp server-cert.pem server-key.pem /etc/ocserv/
先修改登录方式,采用用户密码进行登录:
$ sudo vim /etc/ocserv/ocserv.conf auth = "plain[passwd=/etc/ocserv/ocpasswd]" #设置用户密码
创建密码文件
$ sudo touch /etc/ocserv/ocpasswd
创建用户
$ sudo ocpasswd -c /etc/ocserv/ocpasswd user
删除用户(如果需要的话),此处只是留下删除用户的命令,不是要求必须执行,否则刚刚创建的用户就被删除了:
$ sudo ocpasswd -c /etc/ocserv/ocpasswd -d user1
然后VPN监听端口有需要可以改一下:
tcp-port = 443 udp-port = 443
然后就是VPN网段的配置了,我家里是192.168.1.x网段,我们要让VPN使用一个不同的网段,因为VPN server要给每个连接过来的VPN client分配一个VPN网段的IP,如果这个IP和192.168.1.x网段的某个IP冲突就有问题了,所以一定是不同网段的,同样道理也不能和客户端所在的局域网段冲突。
ipv4-network = 192.168.50.0 ipv4-netmask = 255.255.255.0
所以我配置了192.168.50.x的一个冷门网段,足够分配254个VPN client,为什么不是255个呢?因为VPN服务端会先占1个IP。
暂时我们配置这些,现在我们启动ocserv来介绍一下VPN是如何工作的。
大家自行在路由器映射VPN端口到公网,然后下载openconnect gui客户端(https://openconnect.github.io/openconnect-gui/),然后连接这样的地址:
https://公网IP:路由器映射端口
即可连接到家里内网的VPN服务端,输入任意正确的linux账号密码即可登录。
连接成功后,在客户端打开命令行查看路由表(我是windows电脑,使用route print命令),会发现2条本就存在的路由记录:
0.0.0.0 0.0.0.0 192.168.2.1 192.168.2.103 25 192.168.2.0 255.255.255.0 在链路上 192.168.2.103 281
这是因为windows电脑也在家里,所以本身就被局域网下发了默认网关路由到192.168.2.1路由器、以及192.168.2.x网段的路由记录,这台电脑的自身IP是192.168.2.103。
但是连接VPN后,则多了2条VPN网段的记录:
0.0.0.0 0.0.0.0 192.168.50.1 192.168.50.250 2 192.168.50.0 255.255.255.0 在链路上 192.168.50.250 257
又来了一条优先级更高(2)的默认网关路由,指向了192.168.50.1,也就是VPN server的IP地址,同时也多了一条192.168.50.x 这个VPN网段的路由记录,此时电脑上也出现了一张虚拟的网卡,其IP就是192.168.50.250,这是VPN server给分配的,由VPN client负责虚拟出本地网卡。
此时发往192.168.50.x网段的流量会直接从VPN网卡送出,发往其他IP的流量也会命中192.168.8.1的默认网关(同样是从VPN网卡送出),而不是电脑所在局域网原本下发的192.168.2.1的默认网关。
所以VPN网卡已经劫持了所有外出流量,经过VPN虚拟网卡封包为物理IP送往VPN server,再由VPN server拆包后得到真实IP地址,继续进行转发。
此时VPN server也多了一条该客户端的路由记录:
root@debian:/home/work# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.2.201 0.0.0.0 UG 0 0 0 ens18 192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 ens18 192.168.50.250 0.0.0.0 255.255.255.255 UH 0 0 0 vpns0 # macOS # netstat -nr
也就是192.168.50.250这个vpn client的流量全部送给vpns0虚拟网卡,也就是说回给该vpn client的包也需要经过vpn server的虚拟网卡封包送走。
vpn基本就是这个原理。
不要以为理解上面就万事大吉了,当VPN client请求baidu.com时,baidu的IP地址会命中默认网关发往192.168.50.1默认网关,经过封包送到VPN server的监听端口。
然后VPN server会把封包拆开,linux协议栈看到真实目标IP是baidu.com,那么显然该IP地址不是本机,需要forward给百度,此时需要linux的netfilters进行流量forward才能再次送给192.168.2.1家庭物理网关到达百度,这一步需要我们在服务端开启ipv4 forward特性:
sudo vim /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv6.ip_forward=1
然后执行sysctl -p生效。
请使用以下命令检查服务器的主网卡接口
$ ip addr
例如,可以检查到网卡接口名字是eth0,则执行
$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
这里命令-A
表示添加到nat
表的POSTROUTING
链。这样就可以把VPN网络连接到Internet,并且把你的网络对外隐藏起来。这样Internet只能看到你的VPN服务器IP,但是不能看到你的VPN客户端IP,类似于你家中路由器隐藏起家庭网络。
现在可以检查一下NAT表的POSTROUTING链,可以看到目标是anywhere的源为anywhere的都执行MASQUERADE。
$ sudo iptables -t nat -L POSTROUTING
显示输出:
Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- anywhere anywhere
为了持久化iptables规则(默认重启后就没了),所以我们需要安装一下工具:
sudo apt install iptables-persistent
然后保存一次:
sudo netfilter-persistent save
更高级的特性就是配置ocserv.conf的路由下发,下发一些路由规则到VPNclient ,这样可以控制哪些网段的流量不要发给VPN隧道,可以兼顾客户端本地局域网和家庭局域网两路一起访问的需求,但是这个要求客户端本地局域网段、VPN网段、家庭局域网段三者不能冲突。
大家可以试一下ocserv.conf中的route和no-route配置项,比如我希望VPN client不要让公司网段走VPN,那么就可以加一条这样的配置(假设公司网段是172.26.201.x):
no-route = 172.26.201.0/255.255.255.0
这样VPN client侧的虚拟网卡就会判断目标IP是这个网段的就不发往VPN server了,而是走本地其他路由规则寻址。
如果你家里的网络是路由器/旁路由FQ或者绿色dns的话,那么可以令vpn server的默认网关指向fq路由器,同时让vpn client使用你家里的绿色dns,这样就可以让vpn客户端透明fq了。
比如我家里旁路由上有绿色DNS,所以我可以令ocserv.conf下发它的IP地址作为客户端使用的DNS服务器地址(家里的192.168.2.201运行着绿色DNS,然后vpn client可以通过隧道访问到它):
在ocserv.conf中指定dns服务器地址,下发给vpn client:
dns = 192.168.2.201
这样vpn client就会请求192.168.2.201进行域名解析,得到无污染IP。
理解上述原理需要对路由表、netfilters有清晰认识,否则可能比较困难,希望对你有点帮助。
https://github.com/don-johnny/anyconnect-routes
国内IP不进行代理,参考如下开源项目:
https://github.com/CNMan/ocserv-cn-no-route
1. 对于 ubuntu 22.04 系统,目前(2023.09.01) 系统自带的 ocserv 1.1.3 会在启动之后崩溃,出现如下日志:
$ sudo tail -f /var/log/kern.log Sep 1 11:01:39 localhost kernel: [ 62.471583] traps: ocserv-worker[9587] general protection fault ip:7fa35c1db898 sp:7ffdf42e29a0 error:0 in libc.so.6[7fa35c1db000+195000] $ ocserv --version ocserv 1.1.3 Compiled with: seccomp, tcp-wrappers, oath, radius, gssapi, PAM, PKCS#11, AnyConnect GnuTLS version: 3.7.3 (compiled with 3.7.1)
解决此问题的方法就是安装 ocserv 1.1.6以及以后的版本,可以从源代码编译安装。这里有个简单的解决方法,就是从 ubuntu 23.04 的安装源中下载已经编译好的安装包,直接进行安装,如下:
$ wget http://cz.archive.ubuntu.com/ubuntu/pool/universe/o/ocserv/ocserv_1.1.6-2_amd64.deb $ sudo dpkg -i ocserv_1.1.6-2_amd64.deb $ sudo systemctl restart ocserv
2. 对于腾讯云购买的海外 轻量应用服务器 需要在管理控制台配置防火墙规则,放开端口访问,否则无法进行正常的通讯访问。
在尝试安装 nvidia-docker 的时候(ubuntu 22.04系统Docker和Nvidia-docker的安装、测试,及运行GUI应用),执行如下命令增加 nvidia 源:
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \ && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \ && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
系统发出如下警告:
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
经过分析,是脚本中的如下部分导致:
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo tee /etc/apt/trusted.gpg.d/nvidia-docker.gpg
解决方法为修改为使用如下脚本:
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg $ sudo chmod 644 /etc/apt/trusted.gpg.d/nvidia-docker.gpg
完整修改后的脚本如下:
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \ && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ && sudo chmod 644 /etc/apt/trusted.gpg.d/nvidia-docker.gpg \ && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
$ sudo mkdir /home/data/.timemachine
netatalk
服务和 avahi-daemon
服务。$ sudo apt install netatalk avahi-daemon
netatalk
的配置文件:$ sudo nano /etc/netatalk/afp.conf
[TimeCapsule] path = /home/data/.timemachine time machine = yes ; 关闭spotlight索引,这个在Centos6上是不能开的,缺依赖,7上面可以开,但是不建议,吃资源 spotlight = no ; 指定某用户有读写权限 rwlist = senra ; 强制指定用户 force user = senra ; 限制TM存储容量,单位为MB vol size limit = 100000
$ sudo service netatalk restart
现在,你在 TimeMachine 上应该可以看到这个备份服务了,选择该备份服务就可以开始你的第一次备份了。
注意: Debian 12.5 系统上不能安装 netatalk
,原因是这个项目已经长时间没人维护了,后续建议直接使用 SMB 建立 TimeMachine 的备份服务器。
在今天晚上 ubuntu 22.04 执行如下升级命令之后
$ sudo apt-get dist-upgrade 正在读取软件包列表... 完成 正在分析软件包的依赖关系树... 完成 正在读取状态信息... 完成 正在计算更新... 完成 下列【新】软件包将被安装: cpp-12 gcc-12 libasan8 libgcc-12-dev libtsan2 下列软件包将被升级: apport apport-gtk dkms firmware-sof-signed libexpat1 libexpat1:i386 libexpat1-dev libflac8 libfreerdp-client2-2 libfreerdp-server2-2 libfreerdp2-2 libwinpr2-2 python3-apport python3-problem-report rsync xserver-common xserver-xephyr xserver-xorg-core xserver-xorg-legacy xwayland 升级了 20 个软件包,新安装了 5 个软件包,要卸载 0 个软件包,有 0 个软件包未被升级。
再次执行 flutter 的构建命令,报错。
操作过程如下:
$ flutter run Launching lib/main.dart on Linux in debug mode... Building Linux application... /usr/include/glib-2.0/glib/glib-typeof.h:39:10: fatal error: 'type_traits' file not found /usr/include/glib-2.0/glib/glib-typeof.h:39:10: fatal error: 'type_traits' file not found Exception: Build process failed $ flutter --version Flutter 3.3.9 • channel stable • https://github.com/flutter/flutter.git Framework • revision b8f7f1f986 (2 天前) • 2022-11-23 06:43:51 +0900 Engine • revision 8f2221fbef Tools • Dart 2.18.5 • DevTools 2.15.0 $ flutter clean $ flutter run Multiple devices found: Linux (desktop) • linux • linux-x64 • Ubuntu 22.04.1 LTS 5.15.0-53-generic Chrome (web) • chrome • web-javascript • Chromium 107.0.5304.110 [1]: Linux (linux) [2]: Chrome (chrome) Please choose one (To quit, press "q/Q"): 1 Running "flutter pub get" in xxxx... 6.2s Launching lib/main.dart on Linux in debug mode... CMake Error at /usr/share/cmake-3.22/Modules/CMakeTestCXXCompiler.cmake:62 (message): The C++ compiler "/usr/bin/clang++" is not able to compile a simple test program. It fails with the following output: Change Dir: /home/xxxx/xxxx/xxxxx/build/linux/x64/debug/CMakeFiles/CMakeTmp Run Build Command(s):/usr/bin/ninja cmTC_8cfda && [1/2] Building CXX object CMakeFiles/cmTC_8cfda.dir/testCXXCompiler.cxx.o [2/2] Linking CXX executable cmTC_8cfda FAILED: cmTC_8cfda : && /usr/bin/clang++ CMakeFiles/cmTC_8cfda.dir/testCXXCompiler.cxx.o -o cmTC_8cfda && : /usr/bin/ld: 找不到 -lstdc++: 没有那个文件或目录 clang: error: linker command failed with exit code 1 (use -v to see invocation) ninja: build stopped: subcommand failed. CMake will not be able to correctly generate this project. Call Stack (most recent call first): CMakeLists.txt:3 (project) Building Linux application... Exception: Unable to generate build files
解决方法是手工安装依赖:
$ sudo apt install lib32stdc++-12-dev
之后再执行构建命令。
家里有一台旧的联想T440笔记本,某天来了兴致安装了ubuntu 22.04,默认情况下指纹识别是无法使用的。
查看硬件属于 Elan 指纹识别设备,Ubuntu 自带的 Libfprint 已经提供了支持。
$ sudo apt install fprintd libpam-fprintd
执行
$ sudo pam-auth-update
将第一项,用空格勾选上,然后点“确定”。这样就授权指纹识别登录设备。
打开“设置---用户---指纹登录”,此时就可以打开了。点击“+”,录入第一个指纹吧
在 ubuntu 22.04 通过 snap 安装了 Flutter SDK(当前是Flutter 3.3.4),如果第三方的依赖了 CMake 3.10.2 更高的版本,会在编译的时候报错:
CMake 3.14 or higher is required. You are running version 3.10.2
这个报错的原因是由于 snap 安装的 Flutter SDK 构建了一个沙箱环境,在这个环境中的 CMake 是 3.10.2 版本,不管系统安装的是哪个版本的 CMake ,都是无效的。
要解决这个问题,或者等待 snap 的 Flutter SDK 更新版本,或者参照 Linux install Flutter 的说明,手工安装并配置 Flutter SDK 。
可以参考如下代码:
$ sudo snap remove flutter $ sudo apt-get install curl $ sudo apt-get install clang $ sudo apt-get install git $ sudo apt-get install ninja-build $ sudo apt-get install pkg-config $ sudo apt install gettext $ sudo apt-get install libgtk-3-dev $ sudo apt install libstdc++-12-dev $ git clone https://github.com/flutter/flutter.git -b stable $ export PATH="$PATH:`pwd`/flutter/bin" $ cd `pwd`/flutter/bin $ ./flutter doctor