使用 Docker 完成 GNS3 网络实验

Dockerfile 及 Compose-file 下载:https://github.com/iamNCJ/gns3-docker 众所周知 GNS3 是全球有名的一大坨屎网络软件模拟器。广大 cs 学子为了混到学分熟练掌握计算机网络知识,常年使用 GNS3 做实验到要死要活。GNS3 采用了典型的 C/S 架构设计,其运行时需要一个 gns3-server 作为其后端,并通过 web api 在客户端和服务器之间进行通信。一个标准的 GNS3 桌面程序中一般包含了一个 local-server,随程序一起启动。但是在本地直接开启 server 的时候,往往容易受到外部网络的干扰,而虚拟机又显得过于笨重了,因此很自然的想到使用 Docker 来解决这个问题。 首先在 Docker Hub 上找了一圈,没找到特别好的 GNS3 的 image,索性自己写了一个 Dockerfile,反正也没几行。 开起来之后发现 Cloud Node 没法给 VPC 分配 IP 地址。 PC1> ip dhcp DDD Can't find dhcp server 这是因为 Docker 的网络接口中,容器的 IP 都是由 deamon 在创建分配的,也就是说 Docker 的虚拟网卡并不会提供 DHCP 服务,这也解释了为啥 VPC 得不到来自 Cloud Node 分发的 IP 地址。 既然 Docker 没有提供 DHCP Server,那么我们可以直接创建一个新的网络接口,然后将一个单独的 DHCP Server 放进这个网络里即可。...

December 27, 2020 · 1 min · 91 words · NCJ

树莓派4打造旁路路由

相关仓库: iamNCJ/Openwrt-Pi4 最近尝试改造自己的路由器,无奈家里的路由器都比较老,而且没有USB插口,不是很好刷 OpenWrt ,于是想到直接将树莓派作为自己的旁路路由,在树莓派上运行 Openwrt 系统,来实现如全局代理等功能。 首先尝试官网的 snapshoot 版本,感觉效果一般,然后看网上有人说在 Docker 里运行 OpenWrt ,测试感觉能用,但是非常不稳定,于是索性自己编译一个。 使用的上游是 lede 大的固件,然后针对树莓派4,直接使用64位系统,榨干性能,开启了 Docker 支持,这样其他的功能基本还是不受影响(我已经将所有树莓派上自己用的的服务基本都容器化了),再加上现在的树莓派4已经有了千兆网口,整个体验效果是非常的好。 编译的时候本地编译,毕竟 9700K ,但是出于好玩尝试了网上的 GitHub Actions 编译脚本,感觉这个脚本马马虎虎,而且没有办法增量编译,所以只适合喜欢薅羊毛的人,有条件的话还是本地编译比较好。 现在家里的网络舒服多了,挂一张内网的测速,librespeed speedtest,千兆网还是很稳的。(librespeed 在树莓派上最好从源码 Dockerfile 自己build镜像,linuxserver 提供的 armv8 镜像非常不稳定) 本地互联网和境外代理也都很稳 最后本着开源精神,将树莓派4专用的 OpenWrt 固件的编译 .CONFIG 文件以及编译好的镜像开源,想使用可以点击这里查看配置或直接下载镜像安装,欢迎PR。

March 17, 2020 · 1 min · 39 words · NCJ

GitHub Actions无法上传到Release的问题

最近在尝试使用 Github Actions 自动编译、发布树莓派Openwrt固件的时候,遇到了 Release 发布失败的问题。 可以看到 Create Release 这一步发生了错误 Bad credentials ,这个错误一般是调用 GitHub Release API 的时候 TOKEN 错误导致的,但是在我们这里是 GitHub 自动生成的 TOKEN ,照说应该一点问题都没有才对啊。 后来查找资料得知是因为 GitHub 为 Actions 的每一个 Workflow 都会申请一个临时的 TOKEN ,但是这个TOKEN 只有一个小时的失效,而我们的编译持续了一个半小时,此时的 TOKEN 已经失效了, 因此不再有效。 GitHub给出了一个解决的办法,就是创建不同的 Workflow,先单独编译,编译完成之后再将固件传到一个第三方的位置(比如你的云盘),然后再单独一个 Workflow 进行发布。 另外一种办法就是使用永久的 TOKEN ,但是对于公开仓库这显然不安全,所以可以考虑创建一个 private repo 在里面编译然后通过永久 TOKEN 上传到公开仓库的 Release 里。

March 16, 2020 · 1 min · 50 words · NCJ

Running ROS on WSL

简短版 如果根本没有出现图形界面,请禁用OpenGL的外部转发,全部在WSL内进行渲染: export LIBGL_ALWAYS_INDIRECT=0 如果出现了图形界面,但是中间是黑屏,可以通过--verbose检查 如果是gazebo 7 (ROS Kinetic默认),大概率是第一次模型没有下下来,自己手动下载模型放到/.gazebo/models/目录下即可 如果是gazebo 9 (ROS Melodic),大概率是gazebo server的IP问题,在环境里设置一下gazebo server的IP即可: export GAZEBO_IP=127.0.0.1 闲来无事玩ROS,配环境。一杯茶,一把琴,一个环境配一宿。(不是 言归正传,感觉周围好多人都开始玩ROS,我也玩玩,然而拦在很多人面前的第一道坎竟是安装。事实上ROS官方对于正常的使用者已经提供了清晰明了的安装指南,只要前往官网进行操作即可。 但是我显然不是正常人并没有安装Ubuntu,原因很多,之前还专门写文喷过Ubuntu,但是招架不住这次很多老师指定安装ROS Kinetic,ROS的上一个LTS版本,而这个版本只能安装在Ubuntu 16.04下,于是,我就动了WSL的邪念。 WSL好处很多,你可以直接在Windows下“无缝”使用一个Linux发行版(虽然跟内核有关的东西都被砍掉了),而且WSL的主题安装之后,你可以同时安装很多个发行版,甚至还能通过Raft WSL等工具管理不同发行版的不同快照,这次我就索性直接在WSL里同时安装了两个不同的Ubuntu发行版,分别来安装ROS Kinetic和Melodic版本。 WSL的安装在此略过,网上教程一搜一大把,我就不过多赘述,但是在WSL下,跑通gazebo,麻烦事还是很多的,下面开始排坑。 首先,你得再安装一个Ubuntu的发行版,直接去商店下载就好。 然后安装一下ROS,视网络情况而定,大概10~30分钟的样子。 中间有一步sudo rosdep init可能会因为网络原因很慢,解决办法就是开proxy export https_proxy=xxx sudo -E rosdep init -E的意义就是将你现在设置好的proxy环境带入sudo中 然后你需要准备一个X Server,我使用的是Xming,其他的X Server不保证兼容性。 通过XLaunch启动X Server,注意要关闭Native opengl,不然WSL会试图讲渲染工作交给外部的X Server,但是我试验了一下似乎不太行,干脆就强制使用软OpenGL算了。(再次尝试发现不关也行,主要不在WSL里面指定外部OpenGL就行 划红线的这项要取消勾选 测试一下 roslaunch turtle_tf turtle_tf_demo.launch # on another terminal rosrun rviz rviz -d `rospack find turtle_tf`/rviz/turtle_rviz.rviz 发现可视化工具rviz是可以正常使用的 但是故事没有结束,事实上ROS里面还有一个重要的仿真环境gazebo 我们来测试一下 gazebo 然后发现 中间的仿真是黑的??? 很多人就会就此得出结论——WSL不能运行gazebo,我以前也这么以为,直到最近…… Gazebo 7 我们来试图寻找一下错误的原因...

February 20, 2020 · 2 min · 335 words · NCJ

OOP with Java

1 IO 打印 System.out.println() 输入 import java.util.Scanner; Scanner in = new Scanner(System.in); int a = in.nextInt(); in.close(); public static void main(String[] args)是程序的入口 2 类与包 类 构造函数与C++一样 成员访问权限默认都是friendly,同一个包内可以自由访问 public class必须单独一个文件 包 包是java对于类的一种管理机制,包的结构与文件目录的结构一致 文件第一行package xxx声明包,同时目录结构也要变为xxx/xyz.java 包下还可以有包,Display.led,文件结构Display/led 访问其他包里的对象需要import <package_name>.<class_name>或者每次都在前面加<package_name>. (有点类似namespace) import <package_name>.*也是允许的,但是不推荐 类变量&类函数 static static 一个类共用一个 与C++里的static不太一样 类函数 static 里没有this指针(与C++一样),可以单独调用,也可以通过对象调用 3 容器 import java.util.xxx ArrayList类似vector 对象数组中每一个元素都是对象的管理者而非对象本身,也就是说你在创建数组之后还需要再创建每一个对象。 “对象管理者”的概念 (类似指针) 有序容器的迭代遍历 for ( X x : List ) {...} HashSet 类似 Set HashMap 类似 map 注意不能放int,必须放对象(包裹类型)Integer...

February 6, 2020 · 1 min · 212 words · NCJ

[吐槽向] Ubuntu Server 安装指南

吃饱了撑的,非要在台式机上安装Ubuntu Server 好吧,主要是之后可能要玩ROS,ML的环境也是Ubuntu相对来说容易配置一些,所以还是Ubuntu方便一点。但是最近Ubuntu的一次内核更新引入了一个bug(具体参考https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1860306),导致我的Ubuntu在启动后图形界面会处于卡死状态,无法进行操作。虽然通过ssh将启动目标改为了terminal,勉强能够使用,但是显卡的驱动坏了,一时半会也没修好,一气之下索性想重装一个Ubuntu Server,告别Linux桌面环境。 然后就发现Ubuntu Server的安装脚本就是一坨屎,首先是18.04版本的live iso不支持nvme硬盘,Stack Overflow上查了一圈发现要么换上古的16.04,要么换mini.iso纯网络安装,要么用19.10,想了想20.04应该快出来了,索性直接用非LTS版本到时候滚过去吧。然后安装19.10的时候,发现脚本居然不支持自定义修改分区,要么全盘,要么在进脚本之前自己改好分区表,绝了。(快快投奔Arch 然后自己改好分区表,进入脚本,标记好EFI分区和根目录,开始安装,duang,ERROR,垃圾脚本,上网搜了一下错误信息发现又是一个bug…… 结论:Ubuntu Server的安装脚本设计的时候就没考虑作为第二个系统进行安装,各种异常处理做的也是极其不到位,如果你想Windows+Ubuntu Server,请先安装Ubuntu Server…… 于是开始曲线救国,先安装Desktop,然后转为Server(不愧是我 网上各种奇葩方法…… sudo apt purge xorg-* sudo apt remove gnome-* && sudo apt autoremove sudo apt remove ubuntu-desktop && sudo apt autoremove …… 看着就不优雅 自然想到tasksel 取消勾选Desktop,选上Basic Server,跑完进度条就好了 重启 然后你就发现你上不了网了(狗头 试了一下/etc/network/interfaces发现不行,ip link set eno2 up也不行,然后知道了Ubuntu的网络是由Network Manager管理的,tasksel可能在卸载Desktop的时候给你卸掉了,但Server安装的时候又没给你装回来…… 所以正确方法是:使用tasksel操作完之后,再安装Network Manager…… 踩坑结束……

January 27, 2020 · 1 min · 51 words · NCJ

小米Mix 2s多系统安装教程

折腾了两天,总算成功实现了安卓手机的多系统,在此记录一下,权且做一个教程,给其他热爱折腾的人做一点参考。 首先要说明的是安装双系统乃至多系统,尤其是在手机上,对于很多人来说绝对是非常鸡肋的,而且安装的过程肯定会造成原先数据的丢失等等,安装之后也不能保证所有功能的正常(比如视频),但是对于爱玩机的人来说,能够经常体验不同的ROM还是很重要的。我之所以想安装多系统,就是因为发现了两个都让我非常喜欢的ROM——Pixel Experience 和 Simplicity。这两个ROM可谓是两个极端,一个是纯原生安卓的体验,手感非常的好,吊打国内的各大ROM(这才是安卓啊),另一个则是浓厚的极客气息(自带Magisk、Busybox,以及各种底层破解……),在分别体验了两个ROM之后,我发现对它们都是爱不释手。小孩子才做选择,成年人全都要,多启动的想法自然而然地萌生了出来。 我的设备是Xiaomi Mix 2s (polaris) 国行6+64GB,其他设备的用户本教程可能并不适用,仅供参考 免责声明:本人不对任何教程中的操作造成的数据丢失以及设备损坏负责,请在操作前做好数据备份 一、常见方案 折腾前当然要看看有啥现成的轮子了,大致研究了一下界内的方案,基本都在XDA的这篇文章里讲到了,这里简单概括一下。 MultiROM 官方Wiki 作用于bootloader之后,可以用于引导不同的系统(含Linux),XDA称这是“已知的最好的多系统解决方案”。 https://forum.xda-developers.com/xiaomi-mi-mix-2s/how-to/multirom-multirom-polaris-t3957428 DualBoot Patcher 官网 非常有名的安卓引导工具,XDA高级成员,陈小龙大牛开发&&维护,但是在安卓10到来之后,开发者停止维护了。主要是由于新版安卓在架构上的一些调整造成了开发的困难。但是我想要安装Pixel Experience正是基于安卓10的,所以这个方案不行。 GRUB for Android GRUB是x86架构上知名的引导程序,那么GRUB4Android顾名思义也是一个原生bootloader的替代品。现在这个项目已经衍生为了EFIDroid,但是看了一下官网最后一次更新是2016年,现在貌似也没有对Mix 2s进行适配,所以就放弃了。 综合以上,我最后选择MultiROM作为多系统的解决方案。 二、安装MultiROM版TWRP 在安装ROM之前,我们首先需要对引导程序进行一些处理。 1. 解锁BootLoader BootLoader是嵌入式设备在操作系统内核运行之前运行的一段程序,它相当于控制了整个启动的大方向,厂商往往会在BootLoader里加入一些检查代码,限制非官方的系统的启动。因此如果想要进行刷机、root等操作,必须将厂商的限制解除。 由于BootLoader与硬件强绑定,因此必须通过厂商的官方途径(或者万能的淘宝)进行解锁。小米官方提供了解锁方式,傻瓜操作,在此略过。 2. 刷入Recovery 安卓刷机一般使用TWRP,这是一个开源的第三方Recovery,可以用于替换官方的Recovery,从而更方便地进行刷机等操作。 刷入的过程非常简单,重启手机进入fastboot模式之后,连接手机与电脑,使用ADB进行以下操作: fastboot devices # 检查设备连接状态 fastboot flash recovery your-TWRP.img # 将TWRP烧入Recovery 现在,TWRP已经在你的手机的Recovery分区下了。 3. 安装MultiROM补丁 但是原版的TWRP并不支持多系统,因此我们需要安装TWRP之后打补丁,并替换MultiROM专用的TWRP版本。 而且因为嵌入式的强硬件相关性,我们需要根据自己的设备选择专用的MultiROM补丁,很幸运的是Mix 2s已经有人进行了适配,所以我们直接用轮子就好了。 我们打开相关页面,下载multirom_14-08-19.zip和recovery_3.3.1_17-08-19.img两个文件,储存在手机根目录或者U盘里,然后重启手机进入Recovery模式。 使用TWRP先刷入MultiROM补丁到原始ROM(操作与刷入Magisk类似,使用Install ZIP),再将recovery分区替换为MultiROM专用TWRP(使用Install Image)。 完成后再次重启手机,即可看到MultiROM已经安装完毕,此时理论上就可以使用MultiROM安装第二个ROM了。 三、安装第二个ROM 此时进入Recovery分区,也能通过点击右上角的菜单进入MultiROM的配置菜单 点击Add ROM,ROM类型选择Android,安装地点选择内置储存Internal Storage 选择你想要安装的ROM即可。 教程结束。显然不会这么简单,如果你安装的两个ROM都是安卓9及以下,而且是比较轻量化的ROM或者官方系统,那么以上应该就够了。但是如果你是安装安卓10或者含有root或者大量魔改的ROM,那么你的工作,才刚刚开始…… 四、安装Pixel Experience 根据XDA论坛上提供MultiROM的大神的介绍,安卓10需要作为主ROM进行安装,具体可能与安卓10的加密机制有关。(具体原因尚不清楚,但是在安装完基于安卓10的系统后,文件系统是被加密的,需要安装MultiROM的补丁才能禁用掉加密)。...

January 26, 2020 · 2 min · 221 words · NCJ

校网环境下的私人服务器解决方案

CS狗一枚,几乎每天都需要携带电脑。最近感觉轻薄本性能不太够用,但是游戏本又太厚太重、散热续航也不太行,于是想到在寝室部署一台台式机,然后远程访问计算资源的方案。考虑到校网拓扑的复杂以及供电等原因,最近先进行了一些理论验证,并成功组建了一个个人网络以及一些个人网络服务。以下是过程的简单记录。 一、路由器的必要性与选购 在ZJU,寝室要想访问外网,只有两个方案——学校的WiFi或者有线网VPN拨号。考虑到ZJUWLAN严重的丢包问题,以及时不时被踢下需要重新验证的问题,我毫不犹豫地选择了有线网。 但是由于学校的另一条规定——每个VPN账号只能在一台电脑上登录,而我手上的需要联网的设备远不止两台,因此路由器的出现就很有必要了。 使用路由器的另一个好处是如果VPN掉线会自动重新拨号,在之后的服务搭建中,虚拟服务器功能也起到了极大的作用。因此路由器是非常必要的。 至于选购的话,其实只要支持L2TP即可,不过最近很多家用路由器都取消了这个功能,所以采购的时候还是留点心为好,至少不要以为所有路由器都支持这玩意。 二、网络拓扑的设计以及IP地址的获取 1. 有线连接与无线连接的选择 寝室需要一直联网的设备: Windows电脑一台 树莓派3b+ 这两个设备均采用有线连接,特别是Windows电脑,因为RDP需要传输图像,并且出于鲁棒性考虑同时也连接了无线网,以免出现有线网卡莫名出故障导致无法访问的意外 树莓派连有线是因为需要高带宽,毕竟作为下载机(校内P2P下载) 当我回到寝室时,可能iPhone和小米都要联网,以及我的kindle和Ubuntu笔记本 这些设备直接使用无线网连接好了,毕竟连接外网的带宽也就12Mbps,有线网带宽可谓是绰绰有余 2. 不使用DMZ的原因 不安全,直接把某一台电脑的所有端口直接暴露在外网中是一件极其危险的事情 DMZ只能转发请求到一台设备,但是我的Windows和Pi都需要跑服务,各自有不同的端口需要转发,这是DMZ不支持的 因此,我选择使用虚拟服务器进行配置 3. 虚拟服务器实现端口转发 目前需要的服务: 服务 端口号 Windows上的RDP 3389 Windows上WSL中的Jupyter Lab 8080 Windows上WSL的SSH 22 Pi上的FTP 21 Pi上的BT下载监控 9091 Pi上的Web服务 8080 Pi上的SSH 22 将相应端口进行分别转发即可 对于Windows上Lab和Pi上Web等端口相同的问题,直接在外网设置不同的端口,再分别转发即可,甚至出于安全考虑,更加推荐避免内外端口一致,以防闲的没事的人(暗指某室友)突然访问你的各种服务……(当然他要是知道了我的IP还是可以一个端口一个端口逐个扫描……) 好在他并不知道我的IP,甚至如果我在外面的话,自己都不太方便知道自己的IP…… 这就引出了下面的重磅话题—— 4. 查看IP地址的方法 不要问我为什么不申请固定IP……(手慢无 被申请完了……) 另外申请的固定IP其实是比公网IP低一级的,而对于我这种直接通过VPN拨号访问外网的用户,即使申请到了固定IP也是没法用到L2TP拨号中的,因为我是直接连到学校总对外网关上的,跳过了宿舍网关这一层(这也导致直接通过宿舍有线网是无法ping通我的) 同时,每次路由器掉线重拨后,IP地址都会变。这就令人十分窒息,因为有时候就算早上出门前瞅一眼路由器的IP,中午的时候它可能就又变了…… 于是就有了以下几种可能的方案: 1. 在大致的网段范围内逐个扫描 效率多低、多慢就不用说吧…… 2. 定时推送最新IP 推送的方式有无数种,如QQ、微信、邮件等,此处不赘述 对于推送的时间,之前设想的是每天早上上电之后推送,但是现在发现IP居然可以一日多变…… 半小时一推的话,如果IP变化恰好处在了06:30:19之类的时间,那就干等半小时吧 5min一推怕是跟骚扰信息一样…… 比较好的方案应该是5min获取一次IP,然后跟上次的比对,如果不同再推送 但是 如何获取IP呢? 不要以为这个问题很简单,如果你试着ifconfig的话,会发现得到的是自己小网络里面的ip…… 如果用网上给出的方法,用爬虫爬一些IP查询网站,会发现给你的是公网IP,而不是学校网关分配给你的那个…… 哦豁! 我目前的想法是,直接爬虫登录路由器管理页面,然后找出里面的IP信息…… 如果有更好的方案,请让我知道,谢谢 3. 内网穿透 域名我是有的,构建的流程也基本上清楚,但是如果内网的IP总是在变的话,也没法穿透……...

July 10, 2019 · 1 min · 95 words · NCJ

记一次奇葩的爬虫踩坑经历

2020.05.31更新:发现自己以前好菜啊……( 慢慢来吧…… 摘要: 想利用爬虫实现半夜自动抢图书馆座位的功能,这样晚上就可以多睡一会了…… 但是提交申请时发现有一个参数很诡异…… 下面就是研究这个参数的生成方式,过程很奇葩 主要还是因为我是新手 研究过程曲折但是很有趣,因此记录一下 如果你是大佬或者懒得往下慢慢看,那我直接告诉你结论好了——就是网站自己的js代码没有生成这个参数,这个参数只能是jQuery本身在提交GET请求时额外添加的,后来发现这参数其实就是时间戳…… 登陆已经解决,是一个POST,抓对包之后几乎没什么门槛 提交预约申请使用了Ajax异步技术,因此只需要模拟js脚本提交GET请求即可 抓包分析看到"act":"set_resv",&act=set_resv 在源码VM310中搜索set_resv,看到第537行有对于fRsv()的调用 pro.j.rsv.fRsv("set_resv", $("form:first", dlg), function () { if (uni_calendar_dft_opt.submitSuc) { uni_calendar_dft_opt.submitSuc(dlg, obj); } else { var msg = '申请提交成功,是否跳转查看预约信息?'; if (parseInt(obj.minUser) > 1) { msg += "<br/><br/><div style='font-weight:bold;'>" + uni.translate("注意!生效后需至少") + "<span style='color:red;font-size:bold;'>" + obj.minUser + "</span>" + uni.translate("人刷卡,否则将记为违约!") + "</div>"; } uni.confirm(msg, function () { $("#user_center").trigger("click"); }, function () { uni.reload(); }); $(".group_id", dlg).val(""); $(".group_name", dlg).html("小组未创建"); dlg....

April 4, 2019 · 3 min · 545 words · NCJ

在WSL上安装GNOME桌面方法的正解

网上的教程千篇一律安装的是Unity桌面,而Unity真心难用!自己折腾了一下成功了,简单记录一下方法,帮大家踩踩坑 Step1. 通过tasksel安装Ubuntu Desktop 通过任务的方式安装Ubuntu Desktop tasksel有一个基于curses的GUI 用空格选择Ubuntu Desktop,回车安装即可 这样装下来的Ubuntu Desktop是Gnome版的,CSDN上流传的那些指令装下来的全是Unity环境 tasksel安装的好处是无需过多关心包依赖等问题,缺陷在于会安装很多我们不想要的包,比如libreoffice,但是这些多余的包可以日后卸载 Step2. 安装并启动Xming 启动完整桌面环境时用这个(其余的参数都不用改!包括Display number!) 如果你只是想用用单个程序的GUI界面,选Multiple windows就好了 Step3. 启动GNOME桌面 注意四点: Gnome目前还不稳定,因此启动前最好确保dbus服务正在运行,最简单的方式就是start或者restart一下 需要指定桌面端口以及会话类型(X11) 要加sudo,因为Gnome启动时,dconf也会启动,而后者要在用户根目录下的.cache内创建一个文件夹dconf,估计是想存放一些配置参数之类的,不用sudo的话会在这一步进入死循环,如图 因为已经是超级用户了,所以进入gnome环境后你的身份就是root,不用多说了吧,干啥都悠着点好了…… 上命令: sudo service dbus start sudo DISPLAY=:0 XDG_SESSION_TYPE=x11 gnome-session 好了,现在该怎么折腾就怎么折腾吧……(比如把libreoffice等用Ubuntu Software卸载掉) Step4. 简化日后操作 为了日后简单起见,其实可以通过向.bashrc中写入export DISPLAY=:0.0的方式,让每次启动bash时都运行这句话。毕竟开gnome完整桌面环境的频率还是没有开单个GUI程序的频率高,因此加上这一步可以简化日后在Xming中启动单个GUI程序的指令 echo "export DISPLAY=:0.0" >> ~/.bashrc 此后我们再想启动gnome桌面时,直接输入以下命令就好 sudo service dbus restart sudo XDG_SESSION_TYPE=x11 gnome-session 而单个程序就更简单了,比如 gedit 展现一下“混合系统”的效果…… 踩坑完毕

April 3, 2019 · 1 min · 57 words · NCJ