2011年3月30日星期三
find的正则表达式
水木上有人问:SHELL如何只list名称是8个数字的文件夹?用ls [0-9](重复9次),或者结合grep可以做到。但是用find怎么做呢?研究了一会儿才给出答案:
find . -type d -regextype posix-egrep -regex '.*/[0-9]{8}'find的-regex不是搜索,而是要匹配整个的路径,所以正则表达式前面要加.*/。默认的正则表达式类型是Emacs类型的。虽然Emacs的正则表达式支持\{\}的重复,但是在find的info里面写到是不支持的,要改成posix-egrep类型的正则表达式就可以用{}了。
2011年3月23日星期三
DBus揭密
昨晚折腾够呛,看代码找GNOME的休眠命令。正好看到Rex写的一篇“基本的 DBus 偵錯技巧
”,用D-Bus提供的工具来解剖程序,要比看代码操作容易多了。比如用如下命令:
以前看到D-Bus这个东西,总觉得挺抽象、比较底层,没有去研究过,看了Rex的这篇文章,结合自己昨天看代码的经历,一下就对D-Bus去神秘化了。
”,用D-Bus提供的工具来解剖程序,要比看代码操作容易多了。比如用如下命令:
dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower.Hibernate即可执行休眠操作。不过这个操作是试图直接休眠,要比在GNOME中的休眠少一些操作,例如检查能不能休眠、休眠前锁定屏幕等。
以前看到D-Bus这个东西,总觉得挺抽象、比较底层,没有去研究过,看了Rex的这篇文章,结合自己昨天看代码的经历,一下就对D-Bus去神秘化了。
2011年3月22日星期二
寻找GNOME的休眠命令
为了试验Mac OS X Snow Leopard,把笔记本电脑硬盘全部格式化了。后来又重装了Ubuntu 10.10,但是休眠功能不行了。试着装了hibernate包,再休眠又可以了,在屏幕上可以看到hibernate包的s2disk命令存储内存印象的进度。卸载了hirbernate包,又不能休眠了。可是重装前的Ubuntu 10.10,不用装hibernate也可以休眠的。
记得上大学时候在实验室很旧的计算机上装的Breezy Badger(Ubuntu 5.10),是可以休眠的,可是自己的电脑就没法休眠。现在家用的台式机也是Ubuntu 10.10,没有装hibernate也可以休眠。
我就想知道在GNOME里面点击“Hibernate”后,到底执行了什么命令来休眠?装了hibernate用的是它的s2disk,那么不装的时候呢?我想一切皆有缘由的。
先Google了一下,和/usr/lib/indicator-session/gtk-logout-helper(由indicator-session提供)有关系。apt-get了indicator-session和indicator-applet的源代码,但是没有找到线索。倒是/usr/bin/gnome-session-save --shutdown-dialog(由gnome-session-bin提供)可以弹出关机的提示框:
用apt-get下载源代码,用grep大法搜索hibernate,在gnome-session的gsm-manager.c里面找到了如下的代码:
static void
manager_attempt_hibernate (GsmManager *manager)
{
gboolean can_hibernate;
GError *error;
gboolean ret;
can_hibernate = up_client_get_can_hibernate (manager->priv->up_client);
if (can_hibernate) {
/* lock the screen before we suspend */
manager_perhaps_lock (manager);
error = NULL;
ret = up_client_hibernate_sync (manager->priv->up_client, NULL, &error);
if (!ret) {
g_warning ("Unexpected hibernate failure: %s",
error->message);
g_error_free (error);
}
}
}
里面的up_client_hibernate_sync应该就是执行具体休眠操作的函数了。可是这个函数从哪里来呢?我没有什么浏览源码的工具,只有find、grep和vim。其实Google基本就够了,直接Google搜索这个函数名,哦,原来是upower的函数。再apt-get下来upower的源代码,这个函数在upower的libupower-glib/up-client.c里面,是这么写的:
gboolean
up_client_hibernate_sync (UpClient *client, GCancellable *cancellable, GError **error)
{
gboolean ret;
GError *error_local = NULL;
g_return_val_if_fail (UP_IS_CLIENT (client), FALSE);
g_return_val_if_fail (client->priv->proxy != NULL, FALSE);
ret = dbus_g_proxy_call (client->priv->proxy, "Hibernate", &error_local,
G_TYPE_INVALID, G_TYPE_INVALID);
if (!ret) {
/* DBus might time out, which is okay */
if (g_error_matches (error_local, DBUS_GERROR, DBUS_GERROR_NO_REPLY)) {
g_debug ("DBUS timed out, but recovering");
ret = TRUE;
goto out;
}
/* an actual error */
g_warning ("Couldn't hibernate: %s", error_local->message);
g_set_error (error, 1, 0, "%s", error_local->message);
}
out:
if (error_local != NULL)
g_error_free (error_local);
return ret;
}
dbus_g_proxy_call函数执行了实际的休眠操作,Google一下立刻得到其文档。至于这个“Hibernate”的method怎么调的,我不懂DBus,没搞清楚。歪打正着地在src/linux/up-backend.c里面找到了答案:
找到这个休眠命令的过程很纠结。以后要提高开发本领,至少是读代码的本领,才能在类似的postmortem分析中快速找到答案。
记得上大学时候在实验室很旧的计算机上装的Breezy Badger(Ubuntu 5.10),是可以休眠的,可是自己的电脑就没法休眠。现在家用的台式机也是Ubuntu 10.10,没有装hibernate也可以休眠。
我就想知道在GNOME里面点击“Hibernate”后,到底执行了什么命令来休眠?装了hibernate用的是它的s2disk,那么不装的时候呢?我想一切皆有缘由的。
先Google了一下,和/usr/lib/indicator-session/gtk-logout-helper(由indicator-session提供)有关系。apt-get了indicator-session和indicator-applet的源代码,但是没有找到线索。倒是/usr/bin/gnome-session-save --shutdown-dialog(由gnome-session-bin提供)可以弹出关机的提示框:
用apt-get下载源代码,用grep大法搜索hibernate,在gnome-session的gsm-manager.c里面找到了如下的代码:
static void
manager_attempt_hibernate (GsmManager *manager)
{
gboolean can_hibernate;
GError *error;
gboolean ret;
can_hibernate = up_client_get_can_hibernate (manager->priv->up_client);
if (can_hibernate) {
/* lock the screen before we suspend */
manager_perhaps_lock (manager);
error = NULL;
ret = up_client_hibernate_sync (manager->priv->up_client, NULL, &error);
if (!ret) {
g_warning ("Unexpected hibernate failure: %s",
error->message);
g_error_free (error);
}
}
}
里面的up_client_hibernate_sync应该就是执行具体休眠操作的函数了。可是这个函数从哪里来呢?我没有什么浏览源码的工具,只有find、grep和vim。其实Google基本就够了,直接Google搜索这个函数名,哦,原来是upower的函数。再apt-get下来upower的源代码,这个函数在upower的libupower-glib/up-client.c里面,是这么写的:
gboolean
up_client_hibernate_sync (UpClient *client, GCancellable *cancellable, GError **error)
{
gboolean ret;
GError *error_local = NULL;
g_return_val_if_fail (UP_IS_CLIENT (client), FALSE);
g_return_val_if_fail (client->priv->proxy != NULL, FALSE);
ret = dbus_g_proxy_call (client->priv->proxy, "Hibernate", &error_local,
G_TYPE_INVALID, G_TYPE_INVALID);
if (!ret) {
/* DBus might time out, which is okay */
if (g_error_matches (error_local, DBUS_GERROR, DBUS_GERROR_NO_REPLY)) {
g_debug ("DBUS timed out, but recovering");
ret = TRUE;
goto out;
}
/* an actual error */
g_warning ("Couldn't hibernate: %s", error_local->message);
g_set_error (error, 1, 0, "%s", error_local->message);
}
out:
if (error_local != NULL)
g_error_free (error_local);
return ret;
}
dbus_g_proxy_call函数执行了实际的休眠操作,Google一下立刻得到其文档。至于这个“Hibernate”的method怎么调的,我不懂DBus,没搞清楚。歪打正着地在src/linux/up-backend.c里面找到了答案:
#define UP_BACKEND_SUSPEND_COMMAND "/usr/sbin/pm-suspend"原来用的硬盘上的pm-hibernate命令(由pm-utils包提供)。这个命令的落实,在/usr/lib/pm-utils/pm-functions脚本里面可以找到:
#define UP_BACKEND_HIBERNATE_COMMAND "/usr/sbin/pm-hibernate"
#define UP_BACKEND_POWERSAVE_TRUE_COMMAND "/usr/sbin/pm-powersave true"
#define UP_BACKEND_POWERSAVE_FALSE_COMMAND "/usr/sbin/pm-powersave false"
do_hibernate()好了,就此打住了。至于HIBERNATE_MODE的设置,再不往下追究了,否则就没完没了了。
{
[ -n "${HIBERNATE_MODE}" ] && \
grep -qw "${HIBERNATE_MODE}" /sys/power/disk && \
echo -n "${HIBERNATE_MODE}" > /sys/power/disk
echo -n "disk" > /sys/power/state
}
找到这个休眠命令的过程很纠结。以后要提高开发本领,至少是读代码的本领,才能在类似的postmortem分析中快速找到答案。
2011年3月19日星期六
更舒服地阅读man
很多man页我都没有读完过,只是用作参考。一个原因是很多man页太长了。某天发现了man的-t参数,可以把man页处理成Postscript文件,方便打印了。我用
用PS文件看,可以看到页数,定位、阅读的时候是以页作为单位的,可以放大、缩小,缩小后可以一眼扫到很多东西。这些要素让man页的阅读体验大大增强,效率得到了提高。虽然我们都很习惯在终端阅读man了,但是这种阅读方式明显是有缺陷的。
我干脆写了一个叫pdfman的脚本,用来生成man页的PS文件并调用Evince打开这个PS文件。PS文件在Evince中是无法选取和查找的,所以要看PDF的话,就要先用ps2pdf把PS文件转换为PDF文件。
我现在如果要细读man页,就用pdfman,打印出来就更好读了;如果是查找个参数什么的,就用正常的man,因为最常用的可能就是用'/'来查找关键字了,less里面很方便。
所以,是时候用PS来看man了!
man -t 7 regex > regex.ps生成了PS文件,打开一看才Letter纸上两页过一点。原来在less里面看,看不出有多长,如果要翻页几次,就觉得挺长的了,现在转成PS发现一点并不长。于是打印出来精读了两遍,很受用。
用PS文件看,可以看到页数,定位、阅读的时候是以页作为单位的,可以放大、缩小,缩小后可以一眼扫到很多东西。这些要素让man页的阅读体验大大增强,效率得到了提高。虽然我们都很习惯在终端阅读man了,但是这种阅读方式明显是有缺陷的。
我干脆写了一个叫pdfman的脚本,用来生成man页的PS文件并调用Evince打开这个PS文件。PS文件在Evince中是无法选取和查找的,所以要看PDF的话,就要先用ps2pdf把PS文件转换为PDF文件。
我现在如果要细读man页,就用pdfman,打印出来就更好读了;如果是查找个参数什么的,就用正常的man,因为最常用的可能就是用'/'来查找关键字了,less里面很方便。
所以,是时候用PS来看man了!
2011年3月14日星期一
GNOME显示器分辨率的设置
最近在笔记本上外接了我已经退休的15寸CRT显示器,这样切换屏幕面积变大,多窗口使用比较方便。这台显示器最大支持1024x768@85Hz,但是“显示器首选项”里面比这个分辨率高的还有三个,最高是1280x1024@60Hz。这个刷新率比较低,不太习惯。
每次在“显示器首选项”里面关闭CRT再打开的时候,默认的分辨率就是最高的,还要用鼠标去选择1024x768的分辨率和85Hz的刷新率才行。我想把高的三个删掉,但是在Xorg.conf、在gconf-editor里面都没有找到。最后只好来地毯式搜索了:
tux@dell:~$ find . -name '.*' | grep -R 1280结果是空的。
再来:
root@dell:/home/tux# find /etc -type f -print0 |xargs -0 grep -R 1280第一个就抓到了,原来在/etc/gnome-settings-daemon/xrandr/monitors.xml里面。因为在“显示器首选项”里面选了设为默认,需要认证sudo,所以设置应当是保存在了系统目录里面。
/etc/gnome-settings-daemon/xrandr/monitors.xml: 1280
…………
但是打开这个文件就发现,里面保存的是各模式的组合,而不是这些模式本身。研究发现GNOME是从xrandr获取的可用模式:
tux@dell:~$ xrandr这些模式是GNOME实时获得的,貌似不是从什么配置文件获得的。顺便把一个3年多前问这个问题的帖子也给回答了。:-)
Screen 0: minimum 320 x 200, current 2390 x 768, maximum 8192 x 8192
VGA1 connected 1024x768+1366+0 (normal left inverted right x axis y axis) 306mm x 230mm
1280x1024 60.0
1280x960 60.0
1152x864 75.0
1024x768 85.0* 75.1 70.1 60.0
832x624 74.6
800x600 100.0 85.1 72.2 75.0 60.3
640x480 100.0 85.0 72.8 75.0 60.0
720x400 70.1
640x350 70.1
LVDS1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 309mm x 174mm
1366x768 60.0*+
1360x768 59.8 60.0
1024x768 60.0
800x600 60.3 56.2
640x480 59.9
DP1 disconnected (normal left inverted right x axis y axis)
右边屏幕分辨率:1280x1024 |
右边屏幕分辨率:1024x768 |
2011年3月11日星期五
SSH上不去
新建了个测试用户,结果远程登录上不去。看了这个用户没有家目录,还以为这样不行呢。但建了也上不去。是不是设置了knockd?没有。是不是端口改成了不是22的?也不是。最后打开IBM DW上的《保护 SSH 的三把锁》这篇文章,因为我照着这个配置过。一看还有一把锁是用PAM限制登录用户,原来我用PAM设置了两个用户能用SSH登录上来。有时候做了一些不常用的配置,时间长了就记不清了。出了问题想不起来就有点麻烦了。
sudoers的语法
以前没有学习过sudoers配置文件的语法,给自己的普通账号赋予所有的权限,例如:
关键的语句是User Specification,指定了谁在哪里以什么身份可以做什么:
可以通过前面提到的四种别名进行更细的设置,详见sudoers(5)。
tux ALL=(ALL) ALL或者
%wheel ALL=(ALL) ALL或者
%admin ALL=(ALL) ALLUbuntu下都不用修改,因为安装时候添加的用户已经给放到了admin组。但要是多用户的服务器,这么做就不够了。sudo的配置文件提供了精细的配置选项,可以为用户、运行身份、机器和命令设置多个别名,分别是:User_Alias、Runas_Alias、Host_Alias和Cmnd_Alias。
关键的语句是User Specification,指定了谁在哪里以什么身份可以做什么:
tux | ALL= | (ALL) | ALL |
谁(用户) | 在哪里(机器) | 什么身份(运行身份) | 做什么(命令) |
2011年3月10日星期四
rsync同步的问题
我用自己写的台式机和笔记本之间进行同步的脚本,把笔记本上昨晚下载的Redhat Enterprise Linux 6.0的DVD镜像同步到台式机。脚本里面是用rsync同步,但是发现这个DVD光盘不在要同步文件列表里面。是不是文件太大了呢?打开rsync的man,看到里面有个-max-size选项,指定传输文件的最大尺寸。我指定到很大之后,还是没有这个DVD镜像。把rsync的源代码包下载下来,也没有找到这个值的默认设置。
我的rsync选项是:
以前加上--update选项是为了避免在一端新修改的文件在被另一端的覆盖。但是从这事情看,这样可能让同步内容不能完整传送过去。我现在去掉了--update选项,这样总是会完全同步的,但在确认前始终要检查一遍要执行的操作。
我的rsync选项是:
OPTIONS="--archive --delete --backup --backup-dir=/home/tux/.rsync/backup/ --suffix=@ --partial --partial-dir=.rsync-partial --update --progress --itemize-changes"我检查可疑的选项。看到--update选项的作用是如果目标文件的修改时间比源文件新则跳过。我打开台式机的目录一看,里面已经有这个DVD了,是刚刚复制、粘贴一半又取消剩下的十几兆大的一个文件。把这个文件删除了,再同步就可以了。
以前加上--update选项是为了避免在一端新修改的文件在被另一端的覆盖。但是从这事情看,这样可能让同步内容不能完整传送过去。我现在去掉了--update选项,这样总是会完全同步的,但在确认前始终要检查一遍要执行的操作。
2011年3月7日星期一
yum的autoremove功能
Debian下apt-get有个autoremove功能,可以卸载不再需要的被依赖(depended)包:
目前可以安装yum-plugin-show-leaves插件,在yum输出的最后显示新的leaves(不被其它包依赖):
不过这个东西也不靠谱,vim安装的依赖包可不止最后的gpm-libs、ruby-libs和vim-common这三个,我在yum.log里面又找到了好多:
前12个都是vim依赖的包,我要都在命令行指定删除。这很麻烦的。
找到一篇文章,yum里面已经提供了类似的功能,不过在Fedora 14里面还没有出现。但愿这个功能能够普及。
autoremove但是yum没有这个命令,而且也没有这样的功能。比如我刚刚安装了vim-enhanced,同时新安装了一堆被依赖包,这些包都是只被vim-enhanced依赖的。yum remove vim-enhanced只会卸载vim-enhanced,而不会卸载这些依赖包,这样卸载完后这些包都成了无用的包。
autoremove is used to remove packages that were automatically
installed to satisfy dependencies for some package and that are no
more needed.
目前可以安装yum-plugin-show-leaves插件,在yum输出的最后显示新的leaves(不被其它包依赖):
不过这个东西也不靠谱,vim安装的依赖包可不止最后的gpm-libs、ruby-libs和vim-common这三个,我在yum.log里面又找到了好多:
前12个都是vim依赖的包,我要都在命令行指定删除。这很麻烦的。
找到一篇文章,yum里面已经提供了类似的功能,不过在Fedora 14里面还没有出现。但愿这个功能能够普及。
2011年3月4日星期五
不给力的因特尔
在VirtualBox里面安装Fedora 14 x86_64版本失败,显示如下错误:
This kernel requires an x86-64 CPU, but only detected an i686 CPU.VirtualBox的文档说允许64位客户机要打开APIC支持,我打开后还是出现一样的错误。再看文档,原来需要硬件虚拟化支持:
Unable to boot - please use a kernel appropriate for your CPU.
VirtualBox's 64-bit guest support (added with version 2.0) and multiprocessing (SMP, added with version 3.0) both require hardware virtualization to be enabled. (This is not much of a limitation since the vast majority of today's 64-bit and multicore CPUs ship with hardware virtualization anyway; the exceptions to this rule are e.g. older Intel Celeron and AMD Opteron CPUs.)我的本本是Dell Inspiron 14v,CPU是因特尔奔腾T4500,不支持VT-x技术。以前攒台式机的时候就要求CPU一定得支持硬件虚拟化,调研发现Intel偏低端的CPU就是不支持VT-x,而AMD就厚道多了,64位的CPU基本都支持AMD-V,最后选择了AMD的CPU。
Unattended Upgrades
Ubuntu下的unattended-upgrades包可以自动安装安全更新。apt包提供的/etc/cron.daily/apt文件可以识别unattended-upgrades的设置,该设置在/etc/apt/apt.conf.d/10periodic中定义。默认是不启用的,要添加
在GNOME菜单的“软件源”中,若勾上“不确认就安装安全更新”,则立刻在10periodic文件中添加该行。
多说一句的是,10periodic文件是由update-notifier-common包提供的:
APT::Periodic::Unattended-Upgrade "1";到10periodic中方可。
在GNOME菜单的“软件源”中,若勾上“不确认就安装安全更新”,则立刻在10periodic文件中添加该行。
多说一句的是,10periodic文件是由update-notifier-common包提供的:
# apt-file search 10periodic
update-notifier-common: /etc/apt/apt.conf.d/10periodic
订阅:
博文 (Atom)