deepin-terminal改造风云再起
1. 创作背景
使用deepin-terminal的时候,我发现一些小的问题。
在论坛的帖子(https://bbs.deepin.org/zh/post/224502)也总结反馈了这些问题
- 终端标签变色
- 远程管理标签标题跟右键选项显示异常
- 截图发送到微信之后,再切换到终端时,双击复制无法将内容置入剪切板
经过我虚拟机全新安装deepin20.2.3后,几轮测试下来发现
终端标签变色的问题,应该只是个特性,发生在如果标签1有工作正在进行,或者有更新,比如sudo apt update
或者ssh 连接超时被close时,而此时你正在标签2工作,那么这个变色会提醒你,标签1的工作结束了,或者有更新
截图发送到微信,然后切换到终端,双击复制,概率性无法复制的问题,应该是个稳定的bug。这个bug我也反馈给官方了,不清楚是否后续会解决。
今天来说的是远程管理
2. 远程管理的bug描述
deepin-terminal提供的远程管理,一般会要求我们输入名称,地址 ,帐号,密码这些。正常情况下,如果这些都是正常的,远程连接不会存在问题。连接上以后,标签标题会变成远程主机的用户@主机名,而终端右键也出现“上传文件”和“下载文件“的选项。
正常的情况我们就不说了,说说不正常的情况
2.1 点击远程连接时,突然不想连接了,或者密码错误了,ctrl+c终止连接失败
这种情况发生在,比如管理员重新设置了远程连接的密码,而你的远程连接并未更新,那么你使用这个连接远程主机时,必然会提示你输入密码,3此输入不正确,那么就无法登陆。如果你输入1次,发现不正确,直接ctrl+c了,那么此时标签的标题已经被设置为远程主机的主机名@主机地址了,而右键选项也多出了“上传文件”和“下载文件”的选项。
在未成功登陆远程主机的情况下,这种显示的变化,显然是个BUG。如何解决,且等下文分析
2.2 输错了服务器的IP,因为网络路由不正确,连接失败
如果你不小心直接输错了远程主机的IP地址,而且点击登陆时发现根本没法登陆,报一些比如No route to host的信息,告诉你没有到远程主机的路由。而此时标签的标题已经被设置为远程主机的主机名@主机地址了,而右键选项也多出了“上传文件”和“下载文件”的选项。
在未成功登陆远程主机的情况下,这种显示的变化,显然是个BUG。如何解决,且等下文分析
2.3 修改了ssh配置文件,比如修改了LogLevel导致退出远程主机后显示异常
如果你是一个不喜欢被繁杂的信息打扰的人,修改了/etc/ssh/ssh_config里面,把LogLevel设置为quit,那么当你使用deepi-terminal的远程管理登陆远程主机时,标签标题和右键选项均可以正常显示,但是你工作结束,通过exit命令,logout命令或者直接ctrl+d登出时,你会发现你的标签和右键选项还在。
在成功退出远程主机后,终端标签标题跟右键选项没有变化,这显然是个BUG。如何解决,且等下文分析
3. 如何解决
具体的解决,肯定是要修改代码的啦
3.1 先分析一下为何如此
分析deepin-terminal的源码得知,当你使用远程管理登陆远程节点时,deepi-terminal实际上载入和执行了一段标准的expect脚本,该脚本是一个免交互的脚本。deepin-terminal会把远程管理面板里面的信息同步到这段expect里面,替换到设置的“宏”,然后执行它们。
同时deepin-terminal启动了一个定时器触发,0.1s的时间,判断这个远程管理是否存在expect的进程信息,如果有就把当前标签的连接,设置为远程标签的格式,还有其他信息,比如编码,和右键选项。
试想,如果expect执行的ssh超时还没有到,标签已经变化,而ssh连接失败后,变化的标签会变回去吗?
答案是不一定的。这就是上面的2.1和2.2描述的bug原因。
至于2.3的描述,就要看deepin-terminal退出远程时,是如何把标签重新设置为本地的。它是通过截获收发数据的字符串,判断其是否包含"Connected to "和"closed."或者"Permission denied"来判断终端断开了远程连接。
inline void TermWidget::onTermWidgetReceivedData(QString value)
{
/******** Modify by ut000610 daizhengwen 2020-05-25: quit download****************/
if (value.contains("Transfer incomplete")) {
QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier);
QApplication::sendEvent(focusWidget(), &keyPress);
}
if (value.endsWith("\b \b #")) { // 结束的时候有乱码的话,将它清除
QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_U, Qt::ControlModifier);
QApplication::sendEvent(focusWidget(), &keyPress);
}
/********************* Modify by ut000610 daizhengwen End ************************/
// 退出远程后,设置成false
if ((value.contains("Connection to") && value.contains(" closed.")) || value.contains("Permission denied"))
QTimer::singleShot(100, this, &TermWidget::onExitRemoteServer);
}
而我修改了LogLevel为quit,这个配置在我登出远程节点时,只显示Logout或者中文“登出”,”注销“等字样,并不存在”Connection to"的字样,因此终端就认定这个操作不是退出远程,自然它的标签标题跟右键菜单是不会变化的了。
3.2 再看看如何处理
直接看修改结果吧,对于2.1和2.2的bug描述,直接修改源码文件:deepin-terminal/src/assets/other/ssh_login.sh
修改为:
# Spawn and expect
if { $authentication == "no" } {
eval spawn $ssh_cmd $ssh_opt -t $remote_command exec \\\$SHELL -l
} else {
eval spawn $ssh_cmd $ssh_opt -i $private_key -t $remote_command exec \\\$SHELL -l
}
#fix bug:修复在登陆过程中直接ctlr+c终止登陆时,终端标签和右键选项变成远程的现象.
trap {
send_user "Connection to closed.\n"
exit
} SIGINT
if { [string length $password] } {
expect {
timeout {send_user "ssh connection time out, please operate manually\n"}
-nocase "yes/no" {send "yes\r"; exp_continue}
-nocase -re "password:|enter passphrase for key" { send "$encoded_password\r" }
"No route to host" { send "Connection to closed.\n";exp_continue} #修改远程地址错误导致的终端标签和右键选项变成远程
"Connection to closed." { exit }
}
}
interact
大概意思就是通过expect捕获2.1和2.2描述的bug或者crtl+c信号,向终端抛出"Connection to closed."字样,让终端捕获这个字样后,把当前标签设置为本地标签即可,就不会显示为远程的样式了
而对于2.3的bug描述,还是修改/etc/ssh/ssh_config的LogLevel参数吧,修改为LogLevel=ERROR即可,另外一种动作比较大就是修改源码,把"登出",“注销”,"logout"等字样包含在对终端退出远程的判断,不过这个成本比较大了,意义也不是很大。暂且不做了。
4. 总结
花了2天时间摸索和测试吧,总的来说,达到了验证,修改和修复这些bug的目的。估计没有多少人会触发这样的bug,但是至少可以学习deepin-terminal的工作原理不是,赚到了。
deepin-terminal改造风云再起的更多相关文章
- mac-改造你的terminal
今天在知乎上看到了一篇关于<程序员如何优雅使用Mac>,里面介绍了不少Mac的高端使用技巧,其中关于terminal的部分更是深深的吸引了我,于是我也开始了我的terminal改造计划. ...
- deepin linux 安装 mysql
一:安装mysql 打开deepin terminal: 在此过程中会提示输入两次密码,就是输入 root 账号密码,两次输入密码一样就可以了.然后一路Y安装成功. 一旦安装成功,MySql服务器会自 ...
- windows cmd color setup
设置颜色的话,一般可定会有foreground和background color设置:(其实color /?直接看一下就好了) Color Background Foreground Black 0 ...
- Terminal的快捷键 for Terminal for Mac OS 10.10, Linux/GNU(Ubuntu, deepin, elementory os,CentOS)
对于习惯用windows键盘的,突然转成Mac蓝牙键盘真的有点不习惯,尤其是多了⌘这个键,还有Alt键也成了Option 但是对于Windows下熟悉的快捷键,它们真的失效了,还好Ubuntu也常用, ...
- Ubuntu 12.04 改造指南
文章转自:http://www.lupaworld.com/article-217719-1.html 升级12.04已经有一段时间了.作为一个从08年就开始用Ubuntu的老用户,我觉得作为一个LT ...
- deepin-terminal改造之路
目录 1. 背景介绍 2. 下载源码 3. 依赖检查及安装 4. 改造之路 4.1 终端透明度快捷键 4.1.1 设置面板增加选项内容 4.1.2 添加配置解析内容 4.1.3 功能实现 4.1.4 ...
- deepin gala窗口管理器关闭动画
deepin中有两个管理器,一个基于metacity,另一个基于gala,可以用super+tab来进行切换.metacity是不带动画的,而 gala是带动画效果的.但这里有个问题,不知道有些同学上 ...
- 在deepin 15.5中安装vs code并配置c/c++环境
原文地址:https://blog.csdn.net/DefetC/article/details/79946100 参考了以下几篇文章: https://www.zhihu.com/question ...
- deepin下codeblocks更改调试终端
codeblocks建立控制台程序生成完毕后,发现自带的调试终端xterm不能进行复制粘贴操作参考了Ubuntu的更换调试终端的方法,就是把deepin下的deepin-terminal 用作调试终端 ...
随机推荐
- etcd学习(3)-grpc使用etcd做服务发现
grpc通过etcd实现服务发现 前言 服务注册 服务发现 负载均衡 集中式LB(Proxy Model) 进程内LB(Balancing-aware Client) 独立 LB 进程(Externa ...
- PAT乙级:1077 互评成绩计算 (20分)
PAT乙级:1077 互评成绩计算 (20分) 在浙大的计算机专业课中,经常有互评分组报告这个环节.一个组上台介绍自己的工作,其他组在台下为其表现评分.最后这个组的互评成绩是这样计算的:所有其他组的评 ...
- 《手把手教你》系列技巧篇(十)-java+ selenium自动化测试-元素定位大法之By class name(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍By ClassName.看到ID,NAME这些方法的讲解,小伙伴们和童鞋们应该知道,要做好Web自动化测试,最好是需要了 ...
- docker上运行mysql服务器
1.搜索MySQL镜像 $ docker search mysql INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED docker.io docker.i ...
- noip模拟测试22
考试总结:这次考试题,有好多部分分,导致了我在考试过程中一心想拿到这些部分分,对于正解没有留出时间进行思考,这是一个教训,在以后的考试中我一定要留出足够的思考时间,不要被部分分限制.还有,我的部分分也 ...
- QGIS打印布局中绘制多个子图
QGIS如何绘制多图 数据准备 这是一份英国大曼彻斯特地区的数据,里面包含了教育.收入.人口密度.绿地比例.城市比例等数据,我们准备把这些数据在地图上呈现出来,为此,我们需要做在地图中绘制6幅子图,这 ...
- .net 知新:【4】NuGet简介和使用
在包管理以前我们在项目中引用第三方包通常是去下载dll放到项目中再引用,后来逐渐发展成各种包管理工具,nuget就是一种工具,适用于任何现代开发平台的基本工具可充当一种机制,通过这种机制,开发人员可以 ...
- VIM的命令历史
例如有一段文本,将所有CTRL替换为ctrl,将所有A替换为a,也就是执行了:%s/CTRL/ctrl/g和:%s/A/a/g两条命令,然后进行了很多其他编辑,最后关闭VIM. 后来又有一段文本,也需 ...
- ACM学习笔记:二叉堆
title : 堆 date : 2021-8-3 tags : ACM,数据结构 什么是堆 堆是一棵具有特定性质的二叉树,堆的基本要求是堆中所有结点的值必须大于等于(或小于等于)其孩子结点的值,这也 ...
- Java之Listener
Java之Listener Listener监听器 监听器有很多种,大部分还是在GUI用的比较多,这里简单记录一点关于HttpSessionListener的 统计session count List ...