显示标签为“技术”的博文。显示所有博文
显示标签为“技术”的博文。显示所有博文

2014年4月26日星期六

VirtualBox 安装 OS X Mavericks 的注意事项

  1. 引导和开机
    OS X Mavericks 需要 Chameleon 2.2 版本,目前 2.2 版本仍未正式发布,可下载 svn 版。
    安装流程推荐使用 UniBeast、Hackboot_Mav.iso、MyHack 的其中一种。
    如果用懒人包,请用 Hackboot_Mav.iso。
  2. 开机卡住的问题
    -v 参数启动以便查看调试信息,如果看到 Missing bluetooth controller transport,尝试用 -f 参数启动。此方法对于 Hackboot 有效。
    彻底解决的方法是删除蓝牙驱动的 kext。
  3. 不识别声卡的问题
    先确认 VirtualBox 设置里,虚拟机声卡型号是“Intel HD 音频”。
    用 MultiBeast Mavericks 版安装 VoodooHDA 声卡驱动,重启。
    进入系统偏好设置,把声音输出设备设置为扬声器或耳机。(扬声器和耳机分别试一下。)
    如果声音卡顿,不要惊慌,很多人都遇到这个问题了。据说虚拟机开启单核心CPU,在屏幕上播放动画或不停地移动鼠标能缓解问题。
    或许你还可以试试用网络把音频传输到宿主机
  4. 简单配置分辨率
    宿主机上执行命令: vboxmanage setextradata 虚拟机名字 CustomVideoMode1 1440x900x32
    OS X 开机时指定参数 "Graphics Mode"="1440x900x32"
    如果想永久生效,修改 org.chameleon.Boot.plist,自行 Google。
  5. 打开“关于本机 (About this Mac)”时崩溃的问题
    宿主机上执行命令: vboxmanage setextradata 虚拟机名字 "VBoxInternal/Devices/pcbios/0/Config/DmiExposeMemoryTable" 1
    顺便推荐用 MultiBeast 的 Customize 菜单装一个 System Definition。
  6. 设置 App Store 仅下载更新,不要自动安装。
    有的更新会导致 Hackintosh 系统崩溃。更新前请善用 Google。确定安全再更新。
  7. 推荐教程
    mac os10.9Vmware虚拟机镜像 (我说楼主你能在意一下大小写吗?)
OS X Mavericks in VirtualBox

2013年10月25日星期五

闯过了腾讯CodeStar第一季《前端特工》

无聊打开 w.qq.com 准备登陆QQ聊天,发现页面源代码里面原来藏着注释:
<!--

【云云无情,腾腾有爱】

如果你没有100个“往来”好友,那就来腾讯领红包吧!红包精彩,腾讯更精彩!
http://www.ipresst.com/jointencent

-------------华丽的分割线-------------

【前端特工】

“据内线消息,TX公司将于近期推出一个新的HTML5重磅产品。
公司担心该产品会带来威胁,特命你潜入TX,探查底细……”
http://codestar.alloyteam.com

-->
于是就打开看看。
貌似是一个闯关游戏。一步步走,最后通过了。
具体怎么通过的就不详细说了,事后在网上发现了另一位博主写的记录,有兴趣的点击看看就好了。

然后是吐槽:
第一关的时间戳,我用 date +%s 命令获取 UNIX 时间戳然后填进去怎么都不对啊!后来发现 JavaScript 的时间戳等于 UNIX 时间戳乘以 1000……
第二关动用 Google 大法,轻松找到使用CSS3绘制腾讯QQ的企鹅Logo一文,顺利通过。
第三关最坑了!调试了很长时间都没有搞定,结果一次偶然,我的坦克把敌方坦克撞到了战场的角落,并且因为我程序的 bug,导致继续往墙壁顶,活生生地把敌方坦克撞死了……
第四关是考JavaScript,小菜一碟。
第五关是数塔问题。(没错,就是我当年NOIP做过的数塔问题!)找到当年做过的源代码,跑一遍,OK!
然后,然后就没有然后了。

来个图纪念一下!
通关界面

2013年10月3日星期四

“程序员遇到一个问题”系列

今天在 #archlinux-cn @ irc.freenode.net 讨论 CMake 在多任务同步进行时会产生混乱的输出的问题,于是谈到下面这句话:
One day, a programmer met one problem. He said, 'I will solve it with threads.' Then has he problems two now.
接着,biergaizi 找到了“程序员遇到一个问题”系列的出处,大家或是引用,或是原创,写了很多。
One day, a programmer met a problem. He said, 'I will solve it with Java.' Then he has a ProblemFactory.

One day, a programmer met one problem. He said, 'I will solve it with regular experssions.' Then he has two problems now.

'I know, I’ll use Python.' Now they import solution and have a beer.

'I know, I’ll use LISP.' Now their problem is recursive.

One day, a programmer met a problem. He said, 'I will use pointers in C.' Now thSegment Fault (core dumped)

One day, a programmer met an encoding problem. He said, 'I will switch from UTF-8 to GBK.' 锟斤铐锟斤铐锟斤铐锟斤铐锟斤铐锟斤铐锟斤铐锟斤铐

2013年7月27日星期六

多人服务器的软件包和服务管理

现维护一台服务器,有很多人要登录,需要管理好软件包和服务。
为了避免服务器重启之后挨个通知大家的问题,我写了一个简单的服务管理脚本。有一些简陋(直接用 rc.local 而不是服务),也有一些 bug(比如关机脚本在某些发行版上不执行),但是安全性是有保障的。
那么软件包呢?服务器是 Debian 的,很多软件包在源里没有,或者版本太旧。这就需要用户自己编译。于是在 .bashrc 中写:
export PATH="$HOME/.local/bin:$HOME/.local/sbin:$PATH"
export LD_LIBRARY_PATH="$HOME/.local/lib"
export LD_RUN_PATH="$HOME/.local/lib"
export PREFIX="$HOME/.local"
export LDFLAGS="-L$HOME/.local/lib"
export CFLAGS="-I$HOME/.local/include"
export CPPFLAGS="-I$HOME/.local/include"
不对所有软件包生效(比如 cmake 生成的软件包,但是有解决方法),但是大部分的都可以这么做了。
可能读者朋友已经使用类似的方法了,这篇文章是个备忘。

2013年6月6日星期四

我的 ArchLinux ABS 包定制

Arch Linux 有 ABS (Arch Build System) 就是好。如果自带的包不满意,比如需要什么功能没有编译进去,可以自己编译。
下面贴上我自己定制的几个 ABS 包,以 PKGBUILD patch 的形式提供。算作备忘,也算是分享。

  1. ffmpeg 加入一些因版权问题没有自带的解码器,比如我经常需要压制 mp4 视频,需要 aac 编码器:
    文件名:ffmpeg.diff
    --- a/ffmpeg/PKGBUILD 2013-06-06 01:43:40.319846062 +0800
    +++ b/ffmpeg/PKGBUILD 2013-05-26 21:35:51.118143876 +0800
    @@ -57,7 +57,9 @@
         --enable-shared \
         --enable-vdpau \
         --enable-version3 \
    -    --enable-x11grab
    +    --enable-x11grab \
    +    --enable-nonfree \
    +    --enable-libfaac
      
     
       make
    
    
  2. Timidity++ 允许播放超过 1,048,575 个音符的 MIDI 文件
    文件名:timidity++-maxalloc.diff
    --- a/timidity/timidity.h 2012-06-01 11:40:44.000000000 +0800
    +++ b/timidity/timidity.h 2013-06-06 01:48:14.186722904 +0800
    @@ -436,7 +436,7 @@
     /* you cannot but use safe_malloc(). */
     #define HAVE_SAFE_MALLOC 1
     /* malloc's limit */
    -#define MAX_SAFE_MALLOC_SIZE (1<<23) /* 8M */
    +#define MAX_SAFE_MALLOC_SIZE (1<<26) /* 64M */
     
     #define DEFAULT_SOUNDFONT_ORDER 0
     
    
    文件名:timidity++.diff

    --- a/timidity++/PKGBUILD 2013-06-06 01:45:15.627480183 +0800
    +++ b/timidity++/PKGBUILD 2013-06-06 01:56:25.255489134 +0800
    @@ -14,13 +14,16 @@
                 'xaw3d: for using the Xaw interface')
     backup=('etc/timidity++/timidity.cfg')
     source=(http://downloads.sourceforge.net/timidity/TiMidity++-${pkgver}.tar.xz \
    +        timidity++-maxalloc.diff
             timidity.cfg timidity.service)
     sha1sums=('15ec27f1ea3e718a8d61603521fc16df5c0dd24b'
    +          'SKIP'
               '660b3afbb720d26e8f008034cee66dd8da082d6e'
               'f0351b9eb8928d3d82c380107654a7dbe7cd2d54')
     
     build() {
       cd "${srcdir}/TiMidity++-${pkgver}"
    +  patch -p1 <"${srcdir}/timidity++-maxalloc.diff"
       sed -i -e 's/tcl8.5/tcl8.6 tcl8.5/' -e 's/tk8.5/tk8.6 tk8.5/' configure
       sed -i 's/my_interp->result/(char *) Tcl_GetObjResult(my_interp)/' interface/tk_c.c
       ./configure --prefix=/usr --mandir=/usr/share/man --with-default-path=/etc/timidity++/ \
    
  3. lib32-fontconfig 中保留 fc-cache fc-list fc-match 等命令。
    文件名:lib32-fontconfig.diff
    --- a/lib32-fontconfig/PKGBUILD 2013-06-05 06:07:34.000000000 +0800
    +++ b/lib32-fontconfig/PKGBUILD 2013-06-05 22:44:01.613122245 +0800
    @@ -54,7 +54,10 @@
     
       make DESTDIR="${pkgdir}" install
     
    -  rm -rf "${pkgdir}"/usr/{include,share,bin} "$pkgdir"/{etc,var}
    +  rm -rf "${pkgdir}"/usr/{include,share} "$pkgdir"/{etc,var}
    +  for i in "${pkgdir}"/usr/bin/fc-*; do
    +    mv "$i" "$i"32
    +  done
       mkdir -p "$pkgdir/usr/share/licenses"
       ln -s $_pkgbasename "$pkgdir/usr/share/licenses/$pkgname"
     }
    
后续还会继续追加……比如开启 Pidgin 的视频聊天功能等。

2012年7月9日星期一

豆瓣FM中的彩蛋

打开豆瓣电台,在最右下角能看到“豆瓣实验室
打开后你会在页面左侧看到这个水滴图片(点击查看大图):
熟悉Linux的人都知道这个是一段代码,我把这代码抄了下来(原图第6行中有一个“-c”是错的,应该是“-e”,可能是因为字体太小,不清楚的缘故)
while [ $? -eq 0 ]; do nc -vlp 8888 -e '(r=read; e=echo; $r a b c; z=$r; while [ ${#z} -gt 2 ]; do $r z; done; f=`$e $b|sed "s/[^a-z0-9_.-]//gi"`; h="HTTP/1.1"; o="$h 200 OK"; c="Content"; hd="$c-Type: text/html; charset=utf-8"; if [ -z $f ]; then ($e "$o"; $e $hd; $e; ls | (while $r n; do if [ -f "$n" ]; then $e "<a href=\"/$n\">`ls -gh $n`</a><br>"; fi; done);); elif [[ $f=~eggs ]]; then ($e "$o"; $e $hd; $e; curl http://labs.douban.com/doublo/eggs?k=`$e $f | sed "s/eggs//gi"` 2>/dev/null;); elif [ -f $f ]; then $e "$o"; $e "$c-Type: `file -ib $f`"; $e "$c-Length: `stat -c%s $f`"; $e; cat $f; else $e -e "$h 404 Not Found\n\n404\n"; fi)'; done

这很明显是一个Bash脚本,运行。
这时候用浏览器打开http://localhost:8888
你会看到当前目录的文件列表。
随便点开一个文件,结果是:We need a number after eggs!
那么我们试试看http://localhost:8888/1,返回结果:Next fibonacci!
那肯定下面就是http://localhost:8888/2了,返回还是:Next fibonacci!
按顺序尝试斐波那契数列:1 2 3 5 8 13 21

一直到21的时候,页面显示:
哦!恭喜你中蛋啦!

总结:现在的彩蛋已经不是那么傻瓜化了,已经很有技术含量了。

2012年6月28日星期四

在虚拟磁盘映像上安装 ArchLinux

如果你是一个疯狂的 OS 爱好者,你可能硬盘里面安装了十几个 Linux 发行版,一定要分十几个区么?下面介绍如何在虚拟磁盘镜像上安装 ArchLinux。
在开始之前,强烈建议先阅读官方的安装指南
首先,用 ArchLinux 的安装光盘开机(不管你是用光盘还是U盘,或者是 GRUB 链式引导,只要开了就行)。如果你用的是2012年6月4日以后的安装光盘,需要先初始化软件包验证密钥,执行下列命令即可:
pacman-key --init
pacman-key --populate archlinux #一路敲 y,如果卡住不动,你可以晃晃鼠标消磨时间(顺便给 gpg 提供随机种子)

然后就可以开始了。
  1. 创建镜像
    先挂载上 host 镜像的盘(用 Windows 的估计都会选 NTFS 的),这里我们举例将第一磁盘第五分区作为 host 盘,采用 NTFS-3G 来负责挂载,其他格式的将 ntfs-3g 换成 mount 即可。
    mkdir /host
    ntfs-3g /dev/sda5 /host
    然后创建镜像,这里用 ext4 格式,大小为 8G,放在 diskimg 目录下,自己根据需要修改。
    truncate -s 8G /host/diskimg/archlinux.img
    mkfs -t ext4 -F /host/diskimg/archlinux.img
    modprobe loop #如果你没有用官方的安装盘,需要这行
    mount -o loop /host/diskimg/archlinux.img /mnt
  2. 准备 pacman
    mkdir -p /mnt/var/lib/pacman
    编辑 /etc/pacman.d/mirrorlist,选择自己喜欢的镜像,把它复制下来放在第一行。
    nano /etc/pacman.d/mirrorlist #当然如果你擅长 Vi,也可以用 vi
    然后同步数据库(别忘了配置网络)
    pacman -Sy
    pacman -Sy -r /mnt #顺便也把新系统的数据库同步了
  3. 安装基础系统
    pacman -Sr /mnt base ntfs-3g net-tools wireless_tools #你可能还想安装一下别的,比如说网络组件
    然后有一点耐心,一共80多兆,下载完后自动安装。其中安装 linux 包的时候会出现问题,等一会我们再弄。
  4. 配置系统
    nano /mnt/etc/rc.conf
    nano /mnt/etc/mkinitcpio.conf
    怎么配置不用我说了吧,指南上面有。
  5. 配置引导参数和引导钩子
    先将 /boot 拷出来
    mv /mnt/boot /host/diskimg/archboot
    ln -s /host/diskimg/archboot /mnt/boot
    然后是关键的一步
    依次创建这些文件(斜体字部分是根据自己的情况修改的):

    /mnt/usr/lib/initcpio/hooks/looproot
    # vim:set ft=sh:
    run_hook ()
    {
            # Now mount the host filesystem
            mkdir /host
            # mount -t ntfs /dev/sda5 /host
            ntfs-3g /dev/sda5 /host
    
            # And the loop filesystem
            losetup /dev/loop0 /host/diskimg/archlinux.img
            mount -t ext4 /host/diskimg/archlinux.img /new_root
            mount --bind /host /new_root/host
    }
    
    /mnt/usr/lib/initcpio/install/looproot
    #!/bin/bash
    
    build() {
        SCRIPT="looproot"
    }
    
    help() {
        cat <<HELPEOF
    HELPEOF
    }
    
    # vim: set ft=sh ts=4 sw=4 et:
    
    /mnt/etc/rc.d/functions.d/omitntfs
    #!/bin/sh
    
    omitntfs() {
        sync
        add_omit_pids $(fuser /dev/sda5 2>/dev/null | awk '-F ' '{ print $1 }')
    }
    
    # remove fuseblk from the original NETFS variable
    NETFS="nfs,nfs4,smbfs,cifs,codafs,ncpfs,shfs,fuse,glusterfs,davfs,fuse.glusterfs"
    
    add_hook shutdown_prekillall omitntfs
    add_hook single_prekillall omitntfs
    
    修改 /mnt/etc/mkinitcpio.conf
    MODULES 里面加上 loop fuse
    BINARIES 里面加上 /usr/bin/ntfs-3g(如果你不用 NTFS,并且挂载时需要辅助程序的,加进来)
    HOOKS 最后加上 looproot
    修改 /mnt/etc/fstab
    # 
    # /etc/fstab: static file system information
    #
    # <file system> <dir>   <type>  <options>       <dump>  <pass>
    /dev/loop0      /       ext4    loop            0       1
    /dev/sda5       /host   ntfs    defaults        0       0
    
    创建目录 /mnt/host
  6. Chroot 进新系统
    for i in dev proc sys host; do mount --bind /$i /mnt/$i; done
    modprobe dm-mod #如果你要安装 GRUB 的话需要这行
    chroot /mnt
    passwd #先给 root 设置个密码
  7. 创建启动内存盘
    mkinitcpio -p linux
  8. 安装引导器(谨慎!一定要按照自己的情况来更改参数以免发生意外!
    mkdir /host/boot
    grub-install --target i386-pc --boot-directory /host/boot /dev/sda
    ln -s /host/boot/grub /boot/grub
    grub-mkconfig -o /host/boot/grub/grub.cfg
    最后还有一点要声明的是,要在内核启动选项后面加上 root=/dev/loop0似乎不加也行,但我不敢保证,如果有人成功了就留言通知我一声。
  9. 重新启动
    exit
    umount /mnt/dev /mnt/proc /mnt/sys /mnt/host /mnt /host
    reboot
  10. 继续定制系统
    现在开机,启动过程中会提示错误,然后掉进紧急 shell 当中,不要慌,因为我们 hook 了开机流程,导致自带的脚本执行出错。直接敲 exit 或者按快捷键 ^D 就行了。以后每一次开机都会提示错误,网络上能找到避免的方法,但是我不建议,因为每一次 mkinitcpio 升级之后都会还原。
    这时候你已经登入了新的系统,用 root 登录,密码你前面已经设置过了。

    登录进去之后干什么?这你还用问?

2012年6月22日星期五

10 个痛恨 Linux 的理由

  1. 首当其冲的还是内核问题。
    还记得当年 Linus Torvalds 和 Minix 的作者的那次争论么?或许是为了图省事,Linux 被做成了宏内核。导致了内核过于臃肿。即使是性能提升了,也导致了很多问题。
    1. 内核模块是和内核绑定的。这导致了很恶心的现象,每一次发布内核都需要发布内核模块,而每一次编译内核都要花掉 2/3 的时间在上面。
      你会说,我用发行版提供的内核包,不用自己编译。那问题是,截止 3.4.3 版本,Linux 内核(包括内核模块的二进制包)的大小已经达到了 56.75MiB,至少给网速慢的用户带来了升级上的负担。
      如果,你另外安装了什么驱动(比如 Nvidia 的闭源驱动),每一次更新内核都需要重新编译。你会忘记吗?你应该有过这样的经历。
    2. 内核过于臃肿带来了第二个问题。如果一个驱动崩掉了,整个系统估计也就 Kernel Panic 了。幸好现在的 Linux 提供了一些保护机制,让你至少还可能接着用一段时间,保存手头的工作。
      而我遇到的问题更麻烦,那是在 BtrFS 不太稳定的一段时间里。每当 BtrFS 崩溃,系统就会自动跳回 console,然后提示 btrfs-**** 进程崩溃,给出 backtrace。这时候内核还是在运行的状态,用 Magic SysRq 还能完美重启。而有一次直接 Kernel Panic 了,在 Xorg 下连提示都没有给我,就直接死了,Magic SysRq 都不能用。
  2. 系统调用的命名问题,这是一个历史问题。
    你可以觉得当年 Unix 的 creat() 函数名字很恶心,因为Unix 的创始人认为当年用的电脑键盘使用起来非常费劲,所以宁可省去一个字母(天哪,省别的字母多好,省去这一个字母有什么用?)。但是 POSIX 为什么不说“creat() is deprecated, use create() instead”呢,至少这不会造成小学生的英语水平下降呀。
    如果这个你还能接受的话,那就见识一下 dup() dup2() dup3() 三兄弟吧。你知道它们是干什么的呢,参数怎么用呢?什么?你说还有 man 手册来查?我告诉你,Windows 里面的 MSDN 手册比 Linux 里面的 man 好用多了,而且支持现代化的超链接。
    以前看到一个 Windows 的批评者说 Windows 里面的 CreateWindowEx() 函数参数太多,难以记忆。那我只好用两个观点来反驳了——Linux 里面的 dup*() 家族就不麻烦了?并且哪个人在写 Windows 软件的时候不用 MSDN 做参考(或者参数补全功能)?
    因此,我还是偏好于 Windows 的 API 命名风格(Windows 值得欣赏的估计也只有 API 了),那么 creat() dup() dup2() dup3() 就会叫做 CreateFile() DuplicateHandle() DuplicateHandleTo() DuplicateHandleToEx() 了(而事实上 Windows 本身的 CreateFile() 和 DuplicateHandle() 都实现了 creat() dup3() 的功能,将一些参数填成零也就实现了 dup() 和 dup2() 的功能)
    (引用 @红繁君 的一句话:谁能记住 mktemp mkstemp mkstemps tmpnam tempnam tmpfile 的区别,请举手。)
  3. Linux 前端缺乏创新意识,这也是 Linux 始终无法打入桌面领域的原因。
    这些年 Linux 在桌面市场也在不断发展,但是永远无法撼动 Windows 霸主的地位。不是说 Windows 完美无暇,而是说 Linux 永远跟着别人的脚步在走。
    比如 Gnome 推出了 Gnome-shell,结果遭来了一大堆骂声。批评者说,“难道 Linux 的桌面版以后都要向手机界面迈进?”我只想反问,Linux 社区的激进的极客精神哪里去了?毕竟我也比较喜欢 Gnome-shell,除了一些很小的问题之外还是非常优秀的桌面环境(我也不否认 KDE 和 LXDE 等)。
  4. Linux 的 Kernel Panic 处理很恶心。
    如果你正在图形环境下工作,这是不幸地发生了 Kernel Panic,会有什么现象呢?
    根据内核版本和 X Server 版本的不同,可能你会被拖回 console,然后面对黑底白字和满眼的 backtrace,弄得你手足无措。而也有的就直接死掉了,连提示都没有!(除非你当时在 Virtual Terminal 下,还能看到 backtrace)
    如果是 OS X 或者是 Windows 发生了内核崩溃,不仅会提示你发生了错误,还会把 memory dump 存在硬盘里,这比简简单单地把 backtrace 打在屏幕上要好得多吧。况且如果 backtrace 超过了 24 行,那 backtrace 有什么用!
    据说 Windows 8 开始要改善系统蓝屏的用户体验,不仅是蓝屏的背景颜色有所改变,而且提示文字支持了中文。Linux 什么时候能做到呢?
  5. Linux 对用户不完全友好,对开发者友好。
    虽然人们曾经的“Linux 不用户友好”的概念已经被有些发行版推翻(比如大名鼎鼎的 Ubuntu),但是做的还不够。(不过也难说 Windows 能友好到什么程度,OS X 那才是真正地注重“用户体验”)
    用户体验不是华丽的特效,也不是提供厚厚的操作手册;而是用户永远能在他认为该出现的地方找到他要的功能
    Ubuntu 虽然提供了软件中心(就这还是照苹果抄来的),但是没有提供自动清理软件包缓存的功能,导致缓存吃硬盘空间。当然,Windows 也有不清理 Temp 文件夹的坏习惯,但这不是 Ubuntu 不清理缓存的借口。而相反,ArchLinux 不清理缓存则是注重用户体验。(如果你用过 ArchLinux,你就知道这话的道理了)
    而至于对开发者伪友好,举一个例子就可以说明了。Linux 虽然提供了大量的开发工具,但是从来没有一个得心应手的 IDE,如果说 Linux 的开发者不喜欢 IDE 的话,那么考虑对于一个新手来说 IDE 是不是很重要。一个刚刚从别的平台迁过来的开发者,如果没有 IDE,会很不适应,然后被轻易吓跑。
  6. 图形工具包的不统一。
    这可以追溯到当年 GTK+ 和 QT 闹对抗的时代。然而有的人却找借口说,X 当年的设计就是这样的,“提供机制,而不是策略”,所以让别人自己设计图形工具包。这个说法并没有错,但造成了很多不便。开发者纠结该用什么库,是 GTK+ 还是 QT,还是 TK、FLTK、wxWidget,还是干脆只用 X。而对于用户 ,不仅需要安装一大堆的库,而且要忍受不同库之间的界面样式、主题不同之苦。开发者如果想调用用户的文件浏览器来显示某个目录的内容,就要枚举 Nautilus、Dolphin、PCMan……虽然 freedesktop 缓解了一些问题,但是没有真正解决。
    同样的问题也发生在 ALSA 和 OSS 之间,但我认为这是好事,因为促成了竞争(前提是 ALSA-OSS 兼容包的存在)。
  7. 进程通信的支持问题。
    曾经有一个人说,Linux 里面有万能的管道,Linux 所有的进程通信只需要管道就够了。
    现在,dbus 的出现说明了这种论断是错误的。首先,管道只有单向性,只能去不能回。并且,管道只能传输文本流,对于别的类型,转换的时候既会丢失精度,也降低了效率。当然我不是完全否定管道的,因为即使管道的一端换成了同样功能的软件也能照样运行。(用 less 来替换 more 就是一个很好的例子)
  8. 人们明知道内核过于臃肿不是好事,却仍在变本加厉。
    KMS 是最好的例子。上次听说某显卡驱动为了增强性能以及与内核的集成性,由 UMS 改为了 KMS。与其将更多的东西往内核里塞,不如从内核里拿出东西出来。
    本身内核就应该提供一些对于用户态驱动的接口,让驱动除了使用 int $0x80 以及直接在编译时和内核连接之外有别的、更好的选择。
  9. 对未来的考虑欠缺
    你应该知道 /dev/?d* 表示硬盘,比如 /dev/sda1 表示第一块(SATA 接口)硬盘。那么问题是,如果你安装了 27 块硬盘,该怎么编号呢?Red Hat 的解决办法和 Microsoft Excel 对于第 26 列之后的编号一样:sda sdb sdc ... sdz sdaa sdab ... sdaz sdba ...
    那么带来的问题是,如果原来有一个 Bash 脚本,枚举每一个磁盘,可以用
    for i in /dev/sd? ,现在只可以用
    for i in $(ls -1 /dev/sd* | tr -d [:digit:] | sort -u)
    了(如果有人想到了更简洁的方法请告诉我)
    当年 /dev/pts1 改成 /dev/pts/1 就是因为考虑得不够长远(改过之后也带来了不同发行版和类 Unix 系统分支之间的不兼容性),Intel 也犯过这样的错误,MBR 的设计者也是,甚至 IPv4 的制定者,甚至是“千年虫”也是因为这个导致的。Linux 现在为什么不可以汲取这样的教训呢?比如 Hurd 使用 /dev/hd0s1 的表示,用数字,枚举起来很方便,特别是在 Bash 脚本中。
  10. Hurd 才是 GNU 的未来。
    GNU/Hurd 在 Linux 开始之前就已经动工了,现在 Linux 都更新到 3.x 版本了,Hurd 连一个正式版本都没有释出,这也难怪 Hurd 没有成为开源社区的主流。
    但是的确如此,Hurd 才是 GNU 的未来,Mach 微内核的优雅设计,GNU 自身的支持,更好的安全性能,等等……
    但是毕竟 Hurd 还没有正式做出来,所以这只是痛恨 Linux 的理由,而不是不用 Linux 的理由。
总结:无论如何痛恨 Linux 这个操作系统,都是希望让它做得更好。并且鉴于目前在开源社区里没有更好的替代品(难道有大多数人在家里用 BSD 或者是 Minix 作日常使用么),我们也只能继续使用 Linux,并且向开源社区提供力所能及的帮助。

2011年8月15日星期一

[转] Linux 双网卡网络共享配置心得

一、网络拓补结构:

服务器:
两网卡的设置: eth0:202.96.168.100
掩码:255.255.255.0
网关:202.96.168.68
与 Internet 相联

eth1:192.168.1.1
掩码:255.255.255.0
与局域网相联
客户机子网段:192.168.1.0/255

二、服务器设置

2.1、用NAT方法 在服务器上执行下面几条命令:
echo "1" > /proc/sys/net/ipv4/ip_forward #打开IP转发,1表示转发;0表示不转发
上面这个命令也可以通过修改 /etc/sysctl.conf 实现,在文件中加上下面一行: net.ipv4.ip_forward = 1

其余命令是:iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

三、客户机设置: eth0:192.168.1.10 掩码:255.255.255.0 网关:192.168.1.1
四、iptables 命令参考:

iptables 命令格式

iptables [-t nat] CMD [chain] [rule-matcher] [-j target]

nat:表示操作nat表 CMD:为操作命令 chain:为链名 rule-matcher:为规则匹配器 target:为目标动作

iptables -t nat -F #清除原有的nat表中的规则

iptables -F #清除原有的filter有中的规则

iptables -P FORWARD ACCEPT #缺省允许IP转发

五、配置感想 按照 NAT 的方法,很快配置完成,并且可以顺利上网。对于那些对于网络配置没什么特殊要求的用户,可以选用NAT方法,简单实用。 补充: 如果想在代理机器重启后,仍然能够上网,就需要将这些命令写入到某些文件中,具体如下:
/etc/rc.d/rc.local 文件中加上下面一行
echo "1">> /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

打开 /proc/net/ip_conntrack 可以看到连接情况


2009年7月21日星期二

用 PHP 发送跨域 HTTP 请求


<?php
$f = fsockopen("www.google.com"80);
fputs($f, "GET /search?q=PHP+site:m13253.blogspot.com HTTP/1.1\r\n");
fputs($f, "Host: www.google.com\r\n");
fputs($f, "Connection: close\r\n");
fputs($f, "\r\n");
fputs($f, chr(26));
while(!feof($f) && ($s=fgets($f))!="\r\n" && $s!="\n" && $s!="\r");
while(!feof($f))
        echo(fgetc($f));
fclose($f);
?>

这段代码是用PHP连接 http://www.google.com/search?q=PHP+sitein:m13253.blogspot.com
发送这样的请求:

GET /search?q=PHP+sitein:m13253.blogspot.com HTTP/1.1
Host: www.google.com

Connection: close



然后等待服务器返回
如果成功,服务器会返回一个HEADER(依照具体情况而定)


HTTP/1.1 200 OK
Date: *******************
Server: *****************
Content-type: *********
Content-length: *******


再加上一个空行,然后是网页正文。
网络上有些脚本没有过滤HTTP HEADER
但是现在只能获取HTTP 200 OK状态的内容,
无法判断重定向。

建议使用Apache + PHP 5运行。
------------------------------- 我 是 分 隔 线 -------------------------------
第1次修改后的版本:
<?php
define("host""www.google.com");
define("url""/search?q=PHP+site:m13253.blogspot.com");
$f = fsockopen(host80);
if($f)
{
        fputs($f, "GET ".url." HTTP/1.1\r\n");
        fputs($f, "Host: ".host."\r\n");
        fputs($f, "Connection: close\r\n");
        fputs($f, "\r\n");
        while(!feof($f) && ($s=fgets($f))!="\r\n" && $s!="\n" && $s!="\r");
        while(!feof($f))
                echo(fgetc($f));
        fclose($f);
}
else
{
        echo("Error while connecting host \"".host."\"");
}

?>


第2次修改后的版本:
<?php
function customError()
{
}
set_error_handler("customError");
if(isset($_REQUEST[
"host"]))
{
        $host = $_REQUEST["host"];
        if(isset($_REQUEST["url"]))
                $url = $_REQUEST["url"];
        else
                $url = "/";
}
else
{
        $host = 
"
www.google.com";
        if(isset($_REQUEST["url"]))
                $url = $_REQUEST["url"];
        else
                $url = "/search?q=PHP+site:m13253.blogspot.com";
}
try
{
        $f = fsockopen($host, 80, $errorno, $errorstr, 20);
        if($f)
        {
                fputs($f, "GET ".$url." HTTP/1.1\r\n");
                fputs($f, "Host: ".$host."\r\n");
                fputs($f, "Connection: close\r\n");
                fputs($f, "\r\n");
                if(!feof($f))
                {
                        $httpstatus = fgets($f);
                        $httpstatusok = true;
                        if(str_replace("\r"""str_replace("\n"""strtoupper(substr($httpstatus, strpos($httpstatus, " ")))))!="200 OK")
                        {
                                $httpstatusok = false;
                                echo(nl2br(htmlspecialchars($httpstatus)));
                        }
                        while(!feof($f) && ($s = fgets($f))!="\r\n" && $s!="\n" && $s!="\r")
                                if(!$httpstatusok)
                                        echo(nl2br(htmlspecialchars($s)));
                        if(!$httpstatusok)
                                echo("<br />\r\n<hr />");
                        while(!feof($f))
                                echo(fgetc($f));
                }
        fclose($f);
        }
        else
        {
                throw new Exception();
        }
}
catch(Exception $e)
{
        echo("Unable to connect host \"".htmlspecialchars($host)."\" and request for page \"".htmlspecialchars($url)."\"");

}
?>