Yakuake + dtach vs Screen + urxvt
Screen 无疑是每一个经常使用终端的用户的必备工具。它拥有许多非常实用的功能:
- 管理会话,可以 detach 一个会话,让它在后台运行,并在其他时间/地点 attach 原来的会话。这对于经常远程登录的用户来说非常方便。登录以后,运行一些程序, Screen 会保证在你注销以后程序仍然能继续运行,并且下次登录进来可以 attach 到原来的终端会话上 (也许那里正有一个运行了几个月的 Emacs 在等着你) 。
- 多标签功能。 Screen 可以为一个用户管理多个会话,并且每个会话里面都可以有许多“子会话”,就像许多 Tab 一样,而 Screen 强大的可定制功能让它可以真正显示一个“标签栏”,这正弥补了许多终端模拟器没有多标签功能的缺点。而且这些标签都是在 Screen 会话的管理下的,在另外的地方 attach 到这个会话上会得到同样的一系列标签。并且可以通过 Shell 里面的 Escape Sequence 来动态更改标签的标题。非常方便。
- 屏幕分割、历史存储、搜索以及复制粘贴。这些功能在一个 X 下的终端模拟器里面可以很轻松地完成,不过如果通过远程登录或者在一个纯字符界面下, Screen 就帮了大忙了。
- 快捷键、命令以及其他功能。
这里是一个典型的 Screen 会话的截图。这是我很喜欢的 rxvt-unicode 和 Screen 的搭配。
rxvt-unicode (urxvt) 本身是一个非常不错的程序,同时,它还有一个不错的功能,只要开启 secondaryScroll
URxvt.secondaryScroll: true
Screen 的历史就可以进入 urxvt 的历史里,换句话说,既可以使用 Screen 的回滚功能来查看历史,也可以使用 urxvt 提供的可以用鼠标拖拽的滚动条来查看历史。不过这样也有一些不方便的地方,因为 Screen 里面是可以有多个 tab 的,在 Screen 里面切换 tab 对于 urxvt 来说是不可见的 (听说 eterm 能和 Screen 交互,把 screen 的 tab 用 eterm 自己的标签栏表现出来,不过我没有尝试过) ,所以多个 tab 的历史会混杂进同一个 urxvt 的历史。这也是我尝试 yakuake + dtach 来代替 Screen 的一个直接原因。
Yakuake 是 KDE 下的一个基于 Konsole 的非常 Cool 的一个终端程序。它平时隐藏起来,当你按下快捷键 (默认是 F12
) 时从屏幕顶端滑下。非常方便,有种呼之即来,挥之即去的感觉。当然这并不是我选择 Yakuake 的主要原因,因为我使用 jump-or-exec
可以在 urxvt 上实现类似的功能 (事实上我为很多程序如 Emacs 、 QTerm 和 Firefox 等都配备了 jump-or-exec 的功能,因为我只需要它们的一个实例就够了) ,虽然不及 Yakuake 那么 Cool 。
Yakuake 基于 Konsole ,也就有了 Konsole 的许多优点:多标签、动态更改编码、字体以及颜色配置等。另外,新版本的 Yakuake 还支持屏幕分割功能。历史回滚和复制粘贴这种基本功能自然也不用说了。这些都实现了 Screen 提供的那些功能,唯一的例外就是会话管理。本来作为一个笔记本用户,很少从别的地方远程登录到自己的笔记本上,而且我也绝大部分时间都使用 X 界面,会话管理并不是必要。不过有时候会做一些奇怪的事情有可能让 X 崩溃掉,如果没有会话管理的话,X 崩溃掉了终端里面的程序自然要跟着退出了。正好有一个叫做 dtach 的程序,专门实现了 Screen 的 detach 和 attach 的功能,而抛弃了 Screen 的其他的“累赘”的功能。
现在看来 Yakuake 和 dtach 搭配起来好像是完美的 Screen + urxvt 的替代品一样。dtach 并不像 Screen 那样管理会话和历史,所以所有终端历史进入 Yakuake 的历史里面,使用 Yakuake 的滚动条来回滚查看。不过也由于 dtach 不管理会话,不能像 Screen 那样维护一个多标签。本来可以让 Yakuake 在每次新开 tab 的时候执行 dtach 新启动一个会话,但是 attach 原有的会话有些麻烦,始终不如 Screen 那样方便。后来我仔细想了想,其实执行重要的任务 (就是 X 崩溃了也要继续运行的) 的话,三个 tab 就够了。
于是我只要在启动的时候加载三个由 dtach 管理的会话即可,如果 shell 不够用了,我可以开更多的 tab ,它们不由 dtach 管理,我只要记住重要的任务在 dtach 会话下运行即可。事实上大部分时候包括重要的和不重要的工作,三个 shell 都够用了。
我使用这样一个脚本来启动 Yakuake
#!/bin/sh
if [ -z "$1" ]
then
DIR=$PWD
else
DIR=$1
fi
if dcop | grep -q yakuake
then # yakuake running
dcop yakuake DCOPInterface slotAddSession
dcop yakuake DCOPInterface slotRunCommandInSession "cd $DIR"
else
yakuake
# load my dtach sessions
while ! dcop | grep -q yakuake
do
sleep 0.5
done
dcop yakuake DCOPInterface slotRunCommandInSession
"export DTACH=dtach && dtach -A ~/.dtach/term-0 /bin/zsh"
sleep 0.5
dcop yakuake DCOPInterface slotSetSessionTitleText "[kid]"
dcop yakuake DCOPInterface slotAddSession
dcop yakuake DCOPInterface slotRunCommandInSession
"export DTACH=dtach && dtach -A ~/.dtach/term-1 /bin/zsh"
sleep 0.5
dcop yakuake DCOPInterface slotSetSessionTitleText "[kid]"
dcop yakuake DCOPInterface slotAddSession
dcop yakuake DCOPInterface slotRunCommandInSession
"export DTACH=dtach && dtach -A ~/.dtach/term-2 /bin/zsh"
dcop yakuake DCOPInterface slotSetSessionTitleText "[kid]"
dcop yakuake DCOPInterface slotSelectSession 0
fi
# show yakuake
if [ "false" = `dcop yakuake 'yakuake-mainwindow#1' shown` ]
then
dcop yakuake DCOPInterface slotToggleState
fi
如果 Yakuake 已经在运行了,则打开一个 tab , cd
到指定目录或当前目录 (这非常有用,用这个脚本替换掉 konsole 的话,就可以在 konqueror 文件管理器里面按 F4
来快速在 Yakuake 里面开一个新 tab 并转到该目录了) ,如果没有运行则启动它,并加载三个默认的 dtach 会话。其中与 Yakuake 的交互通过 dcop 来进行。KDE 提供的 dcop 让我们可以很轻松地在脚本里面调用 KDE 程序提供的复制功能。我把这个脚本链接到 ~/.kde/Autostart/
下面,在 KDE 启动的时候自动启动它。
Konsole 同样允许通过 Shell 里面的 escape sequence 来改变标题栏和标签栏。Yakuake 继承了更改标签栏的功能,但是由于 Konsole 内部实现的一些原因 (Konsole 正要经历巨大修整,参见 Konsole 大整修) Yakuake 不能使用 Konsole 的那种方法来设置标签标题。不过可以 hack 一下在更改标题的同时更改标签栏标题,下面是针对 Yakuake 2.8 的 patch :
diff -ur src/main_window.cpp src.orig/main_window.cpp
--- src/main_window.cpp 2007-06-01 00:29:06.000000000 +0800
+++ src.orig/main_window.cpp 2007-06-01 00:10:27.000000000 +0800
@@ -342,8 +342,6 @@
connect(session, SIGNAL(destroyed(int)), this, SLOT(slotSessionDestroyed(int)));
connect(session, SIGNAL(titleChanged(const QString&)), this, SLOT(slotUpdateTitle(const QString&)));
- connect(session, SIGNAL(titleChanged(int)), this, SLOT(slotUpdateTitle(int)));
-
widgets_stack->addWidget(session->widget());
sessions_stack.insert(session->id(), session);
@@ -783,10 +781,6 @@
title_bar->setTitleText(title);
}
-void MainWindow::slotUpdateTitle(int id)
-{
- slotRenameSession(id, sessions_stack[id]->title());
-}
void MainWindow::slotIncreaseSizeW()
{
diff -ur src/main_window.h src.orig/main_window.h
--- src/main_window.h 2007-06-01 00:12:58.000000000 +0800
+++ src.orig/main_window.h 2007-05-06 08:32:58.000000000 +0800
@@ -217,8 +217,7 @@
void slotUpdateSize();
void slotUpdateSize(int new_width, int new_height, int new_location);
void slotUpdateTitle(const QString& title);
- void slotUpdateTitle(int id);
-
+
void slotIncreaseHeight();
void slotDecreaseHeight();
void slotSessionDestroyed(int id = -1);
Only in src: Makefile.am
Only in src: Makefile.in
diff -ur src/session.cpp src.orig/session.cpp
--- src/session.cpp 2007-06-01 00:13:48.000000000 +0800
+++ src.orig/session.cpp 2007-05-06 08:32:58.000000000 +0800
@@ -395,7 +395,6 @@
{
session_title = title;
emit titleChanged( session_title);
- emit titleChanged( session_id);
}
}
diff -ur src/session.h src.orig/session.h
--- src/session.h 2007-06-01 00:14:11.000000000 +0800
+++ src.orig/session.h 2007-05-06 08:32:57.000000000 +0800
@@ -72,8 +72,8 @@
signals:
void destroyed(int id);
void titleChanged(const QString&);
- void titleChanged(int);
-
+
+
private:
void createInitialSplits(SessionType);
void split(QWidget* active_terminal, Orientation o);
之后在 Shell 的提示符里面做点手脚就自动更新标签栏了。我用的是 Zsh ,下面的配置可以在标签栏标题里面显示当前目录。如果是在一个 dtach 管理的会话里,则用方括号“[]”括起来 (在前面的启动 Yakuake 的脚本里面设置了 DTACH
环境变量用于识别是否在 dtach 会话里) :
if [[ -z "$DTACH" ]];
then
P_TITLE=$'%{e]0;%1/a%}'
else
P_TITLE=$'%{e]0;[%1/]a%}'
fi
有 Zsh 提供的功能,可以在执行某条命令之前先做一些动作,比如更新标签栏以显示出当前正在执行的命令:
CMD=${1[(wr)^(*=*|sudo|-*)]}
if [[ -z "$DTACH" ]]
then
echo -n "e]0;$CMDa"
else
echo -n "e]0;[$CMD]a"
fi
下面是我的 Zsh 的提示符的完整配置:
#!/bin/zsh
autoload colors zsh/terminfo
if [[ "$terminfo[colors]" -ge 8 ]]; then
colors
fi
if [[ "$TERM" = "dumb" ]]
then
prompt='%(?..(%?%))%n@%1/ %(!.#.$) '
else
local P_GREEN="%{$terminfo[bold]${fg[green]}%}"
local P_CLEAR="%{$terminfo[sgr0]%}"
local P_ERROR="%{$terminfo[bold]${fg[red]}%}%(?..(%?%))$P_CLEAR"
local P_USER="%(!.${bg[green]}${fg[black]}ROOT.%n)$P_CLEAR@"
local P_DIR="%1/"
local P_PRO=" %(!.#.$) "
local P_TITLE
if [[ "$TERM" = "screen" ]]; then
P_TITLE=$'%{ek%1/e\%}'
elif [[ "$TERM" = "xterm" ]]; then
if [[ -z "$DTACH" ]];
then
P_TITLE=$'%{e]0;%1/a%}'
else
P_TITLE=$'%{e]0;[%1/]a%}'
fi
else
P_TITLE=""
fi
prompt="$P_ERROR$P_USER$P_GREEN$P_DIR$P_CLEAR$P_PRO$P_TITLE"
fi
preexec () {
local CMD=${1[(wr)^(*=*|sudo|-*)]}
if [[ "$TERM" == "screen" ]]; then
echo -n "ek$CMDe\"
elif [[ "$TERM" == "xterm" ]]; then
if [[ -z "$DTACH" ]]
then
echo -n "e]0;$CMDa"
else
echo -n "e]0;[$CMD]a"
fi
fi
}
如下是一个效果截图。
我已经用了大约一个周了,感觉非常好,几乎从原来的 Screen + urxvt 平滑过渡过来。不过我也并不能说哪种方案更好。如果你绝大部分时间都是在 X 下渡过 (特别是,如果你使用 KDE) ,而且不经常远程登录的话,推荐使用 Yakuake + dtach 获得更好的用户体验。否则,还是推荐使用 Screen ,因为它具有更强大的会话管理能力。
分享到:
相关推荐
Yakuake是基于KDE Konsole技术的下拉终端仿真器。
Yequake是为Emacs设计的一个下拉式框架,灵感来源于Linux下的Yakuake终端模拟器。Yakuake以其独特的自上而下滑出的界面而闻名,这种设计在多任务处理时尤其方便,用户可以快速访问并隐藏终端,而不需要切换窗口或...
ATerm,Urxvt,Rxvt,XTerm和其他libXt终端:将生成的文本复制到~/.Xresources文件(您可能必须创建它)并运行xrdb ~/.Xresources 。 Gnome Terminal,Guake:将生成的脚本保存到set_colors.sh中,使该文件可执行$...
:pencil: Arch Linux / KDE / yakuake /我的Zsh / VS代码 :seedling: 为做准备 :man: 代词:他/他 :key: GPG键: :sparkles: 我的追随者 :bar_chart: 每周开发细目 JavaScript 6 hrs 5 mins ████...
屋久(Yakuake)皮肤(在屋久(Yakuake)文件夹中) Plasma 5桌面主题(在plasma5文件夹中) 安装 有关安装说明,请参阅每个组件的README文件。 笔记 这是一个正在进行的工作。 如果您发现任何问题,请提交问题,...
微风主题的Yakuake和Konsole个人资料。 漫画无Fantasque Sans Mono作为字体,具有多字母Reimu或Flandre背景。 Klipper配置为包含Bilibili,Github和zim / markdown的Web内容。 KDE配色方案:深色但浅色的textview。...
$ sudo apt install yakuake | $ sudo apt install kazam | $ sudo apt install speedtest-cli | $ sudo apt install tmux | $ sudo apt install htop | $ sudo apt install ncdu Linux Trick-01:以root用户...
在Linux环境中,我们可以使用诸如Gnome Terminal、Konsole、 terminator或Yakuake等终端模拟器,它们都支持自定义主题。而对于iTerm2用户,安装新的主题非常简单。通常,你只需要将下载的主题文件移动到正确的位置,...
如果您需要功能完善的等效功能,则可以使用guake或yakuake(尽管看起来集成度较低)。 当然,我欢迎您提出建议,但请不要要求任何人都不需要的超高级设置,因为代码已经足够复杂,可供审阅者处理。 目前,