K.I.S.S. – 简单哲学 Linux, Freedom, Arch, Python, Gtk+, C … Keep It Simple, Stupid!

2七/097

Bash 4.0 新功能概览

Bash 是 Linux 平台下使用最多的 ,虽然 Bash 4.0 早已经发布了,然而毕竟是主要版本,各大发行版都对其采用了谨慎的态度。就在昨天(2009.7.1),Arch 将 Bash 加入了 Core 仓库,这意味着 Bash 4 已经被 Arch 认可为稳定版本了。

那么,Bash 4 为我们带来了那些改进呢?我们来看一下。

新的或者改进的命令或关键字

  1. 新的"coproc"关键字:Bash 4 引入了“协同进程”(coprocesses)的概念,这允许你在后台打开程序,并与它的输入输出数据流进行交流。
  2. 新的"mapfile"内置命令:直接将文本文件读入到数组里面,它允许你设置读入的行数,还允许指定回调函数,这在显示进度条的时候很有用。
  3. 对"case"关键字的修改:新增 ;& 终止符,用于执行下一个动作列表而不是终止 case 结构;新增 ;;& 终止符,用于继续检测下一个表达式(pattern)。
  4. 对"declare"内置命令的修改:-p 现在显示所有已声明的属性和值。-l、-u 分别用来声明内容为小写、大写的变量。- 用于声明标题化的变量。-A 用于声明联合数组。
  5. 对"read"内置命令的修改:-t 指明超时时间,可以是分数。-i 可以用一些文本来预加载输入缓冲区(当启用 Readline 时,使用 -e)。
  6. 对"help"内置命令的修改:帮助文本的格式更好,更加易读。-d 显示帮助摘要,-m 显示 manpage 风格帮助。
  7. 对"unlimit"内置命令的修改:除了 POSIX 模式下的 512 字节块大小限制之外,新增两种:-b 为最大 Socket 缓冲区大小,-T 为最大线程数。

扩展(Expansions)

  1. 大括号扩展:产生一行数字的时候允许前置 0。
  2. 参数扩展:通过添加操作符,使参数在扩展时改变大小写。
  3. 子字符串扩展:当在位置参数中使用子字符串扩展时,以 0 开始的索引将使 $0 前缀在列表中,而不是以前的 $1。
  4. 文件名替换:新的 选项 globstar,将对 ** 进行递归的文件名替换;新选项 dirspell 将启用文件夹名拼写修正。

联合数组(Associative Arrays)

联合数组是一个以任意字符串索引的数组,例如:

declare -A ASSOC

ASSOC[First]="first element"
ASSOC[Hello]="second element"
ASSOC[Peter Pan]="A weird guy"

重定向(Redirection

新的 &>> 符号将标准输出和标准错误输出追加到指定文件,与 >>FILE 2>&1 相同作用。而 |& 与 2>&1 | 相同作用。

新的 变量

  1. BASHPID:包含当前 的 PID。
  2. PROMPT_DIRTRIM:指明提示符下未缩短的路径的最高极。

新的 选项(默认关闭)

  1. checkjobs:在 退出时检查并报告运行中的任务。
  2. compat*:设置旧版 兼容性。

杂项

在没有找到命令时, 会试图调用 command_not_found_handle 这个函数,可以用这个功能显示更友好的出错信息。

set -e (errexit) 模式的行为已经发生变化,变得更加直觉化。

via: Bash 4 - a rough overview

相关文章:Bash 4.0 和 Readline 6.0 发布 / Bash 4.0 比较有用的功能

标签: 7 评论
3五/096

轻松建立 Ubuntu/Debian 源镜像

服务器上的源是 的,考虑到学校里面已经没有多少人使用 ,而使用 来做推广显然更加合适,同学们遇到什么问题,也可以得到更好的支持,于是决定把 源换成 的。
建立源,当然要用 rsync ,不过这里并非直接使用,而是用的 官网提供的一段脚本,叫做 anonftpsync,加上 作为定时任务做成的。
是 Linux 下的计划任务工具,可以按每小时、每天、每星期、每月执行任务,支持多用户多设置,很是方便。往下看之前,确认你安装了 rsync,并且开启了 守护程序。

下面说一下步骤:
首先,建立源目录。如果想放在 FTP 服务器上,应该建立在 FTP 目录里,比如:

mkdir /home/ftp/

由于脚本的需要,最好建立一个文件夹来记录最后同步的时间:

mkdir -p /home/ftp//project/trace/

然后建立脚本 anonftpsync。拷贝下面的脚本存放在稳妥位置。

#! /bin/sh -p
set -e

# EXCLUDE 是你要排除的文件和目录。
EXCLUDE="--exclude *alpha.deb \
    --exclude *alpha.udeb \
    --exclude binary-alpha/ \
    --exclude disks-alpha/ \
    --exclude *-alpha.gz \
    --exclude installer-alpha/ \
    --exclude binary-arm/ \
    --exclude *arm.deb \
    --exclude *arm.udeb \
    --exclude disks-arm/ \
    --exclude *-arm.gz \
    --exclude installer-arm/ \
    --exclude binary-m68k/ \
    --exclude *m68k.deb \
    --exclude *m68k.udeb \
    --exclude disks-m68k/ \
    --exclude *-m68k.gz \
    --exclude installer-m68k/ \
    --exclude binary-hppa/ \
    --exclude *hppa.deb \
    --exclude *hppa.udeb \
    --exclude disks-hppa/ \
    --exclude *-hppa.gz \
    --exclude installer-hppa/ \
    --exclude binary-ia64/ \
    --exclude *ia64.deb \
    --exclude *ia64.udeb \
    --exclude disks-ia64/ \
    --exclude *-ia64.gz \
    --exclude installer-ia64/ \
    --exclude binary-mips/ \
    --exclude *mips.deb \
    --exclude *mips.udeb \
    --exclude disks-mips/ \
    --exclude *-mips.gz \
    --exclude installer-mips/ \
    --exclude binary-mipsel/ \
    --exclude *mipsel.deb \
    --exclude *mipsel.udeb \
    --exclude disks-mipsel/ \
    --exclude *-mipsel.gz \
    --exclude installer-mipsel/ \
    --exclude binary-s360/ \
    --exclude *s360.deb \
    --exclude *s360.udeb \
    --exclude disks-s360/ \
    --exclude *-s360.gz \
    --exclude installer-s360/ \
    --exclude binary-s390/ \
    --exclude *s390.deb \
    --exclude *s390.udeb \
    --exclude disks-s390/ \
    --exclude *-s390.gz \
    --exclude installer-s390/ \
    --exclude binary-sh/ \
    --exclude *sh.deb \
    --exclude *sh.udeb \
    --exclude disks-sh/ \
    --exclude *-sh.gz \
    --exclude installer-sh/ \
    --exclude binary-sparc/ \
    --exclude *sparc.deb \
    --exclude *sparc.udeb \
    --exclude disks-sparc/ \
    --exclude *-sparc.gz \
    --exclude installer-sparc/ \
    --exclude /-1.3* \
    --exclude /Debian3.1* \
    --exclude local/ \
    --exclude stable/ \
    --exclude slink-proposed-updates/ \
    --exclude slink/ \
    --exclude bo/ \
    --exclude bo-unstable/ \
    --exclude bo-updates/ \
    --exclude binary-hurd-i386/ \
    --exclude *hurd-i386.deb \
    --exclude *hurd-i386.udeb \
    --exclude disks-hurd-i386/ \
    --exclude *-hurd-i386.gz \
    --exclude installer-hurd-i386/ \
    --exclude binary-powerpc/ \
    --exclude *powerpc.deb \
    --exclude *powerpc.udeb \
    --exclude disks-powerpc/ \
    --exclude *-powerpc.gz \
    --exclude installer-powerpc/ "
#--exclude /contrib/ --exclude /non-free/ --exclude source/\
#    --exclude Incoming/ \
#######################################

# TO 是目标目录
TO=/home/ftp/
# 以下两个合起来就是源地址: .ustc.edu.cn//
# 这里设置同步的服务器域名
RSYNC_HOST=.ustc.edu.cn
# 这里是同步服务器上源所在的目录
RSYNC_DIR=/

LOCK="${TO}/Archive-Update-in-Progress-`hostname -f`"

# Get in the right directory and set the umask to be group writable
#
cd $HOME
umask 002

# Check to see if another sync is in progress
if lockfile -! -l 43200 -r 0 "$LOCK"; then
  echo `hostname` is unable to start rsync, lock file exists
  exit 1
fi
trap "rm -f $LOCK > /dev/null 2>&1" exit  

set +e

#result=1
#while (( $result != 0 )) ; do
rsync -rltv --progress --delete \
     --exclude "Archive-Update-in-Progress-`hostname -f`" \
     --exclude "project/trace/`hostname -f`" \
     $EXCLUDE \
     $RSYNC_HOST::$RSYNC_DIR $TO > ${HOME}/log/rsync.log 2>&1
#result=$?
#done

date -u > "${TO}/project/trace/`hostname -f`"
savelog ${HOME}/log/rsync.log > /dev/null 2>&1

设置权限。确定脚本可以被执行,目标目录有写权限。

chmod +x anonftpsync
chmod 755 /home/ftp/

添加计划任务。这里使用 crontab 设置,-e 选项表示编辑设置:

crontab -e

输入下面的一行,表示每天凌晨 2:00 运行 /usr/local/bin/anonftpsync,添加完毕保存:

00 2 * * *   /usr/local/bin/anonftpsync

使用下面的命令查看是否添加成功:

crontab -l

重启 更改完设置需要重启 ,通常是:

/etc/init.d/ restart

Arch Linux 下是:

/etc/rc.d/crond restart

接下来就是等待咯,如果你迫不及待,可以直接运行脚本同步。
可以看到,建立一个 / 源并没有如何麻烦,这不得不归功于 linux 下工具和脚本的强大,呵呵~
如果有教育网的同学,可以加这个源,现在还在同步中,呵呵~每天从中国科技大学同步一次。从这里下载源列表:

ftp://.org/sources.list/

如果对 不够明白,可以参考:计划任务工具 cron 的配置和说明

17二/093

Linux下统计代码行数的方法

我们编程时常常想统计一下自己写过多少行代码了,这时候该怎么办呢?
虽然Vim等编辑器中有代码行数显示,但是不能一个个打开然后加起来吧?
这个时候需要用到wc这个工具,呵呵,别看名字不怎么样,功能可是很强大的哦。
用法:
当前目录下:

wc -l *. *.h

当前目录及子目录:

find . -name *. |xargs wc -l
find . -name *.cpp | xargs wc -l
find . -name *.h |xargs wc -l

很方便吧?
PS:我的Cugb Linker原来还不到600行……努力!

标签: 3 评论
13二/090

shell – 转换文件名大小写的方法

for file in `ls`
do
mv $file `echo $file|tr "[A-Z]" "[a-z]"`
done
11二/090

使用 screen 管理你的远程会话(转载)

原文:http://blog.zhangjianfeng.com/article/718

你是不是经常需要 或者 telent 远程登录到 Linux 服务器?你是不是经常为一些长时间运行的任务而头疼,比如系统备份、ftp 传输等等。通常情况下我们都是为每一个这样的任务开一个远程终端窗口,因为他们执行的时间太长了。必须等待它执行完毕,在此期间可不能关掉窗口或者断开连 接,否则这个任务就会被杀掉,一切半途而废了。

元凶:SIGHUP 信号

让我们来看看为什么关掉窗口/断开连接会使得正在运行的程序死掉。

在Linux/Unix中,有这样几个概念:

  • 进程组(process group):一个或多个进程的集合,每一个进程组有唯一一个进程组ID,即进程组长进程的ID。
  • 会话期(session):一个或多个进程组的集合,有唯一一个会话期首进程(session leader)。会话期ID为首进程的ID。
  • 会话期可以有一个单独的控制终端(controlling terminal)。与控制终端连接的会话期首进程叫做控制进程(controlling process)。当前与终端交互的进程称为前台进程组。其余进程组称为后台进程组。

根据POSIX.1定义:

  • 挂断信号(SIGHUP)默认的动作是终止程序。
  • 当终端接口检测到网络连接断开,将挂断信号发送给控制进程(会话期首进程)。
  • 如果会话期首进程终止,则该信号发送到该会话期前台进程组。
  • 一个进程退出导致一个孤儿进程组中产生时,如果任意一个孤儿进程组进程处于STOP状态,发送SIGHUP和SIGCONT信号到该进程组中所有进程。

因此当网络断开或终端窗口关闭后,控制进程收到SIGHUP信号退出,会导致该会话期内其他进程退出。

我们来看一个例子。打开两个终端窗口,在其中一个运行top命令。

[root@tivf09 root]# top

在另一个终端窗口,找到top的进程ID为5180,其父进程ID为5128,即登录

[root@tivf09 root]# ps -ef|grep top root      5180  5128  0 01:03 pts/0    00:00:02 top root      5857  3672  0 01:12 pts/2    00:00:00 grep top

使用pstree命令可以更清楚地看到这个关系:

[root@tivf09 root]# pstree -H 5180|grep top |-sshd-+-sshd---bash---top

使用ps-xj命令可以看到,登录(PID 5128)和top在同一个会话期,为会话期首进程,所在进程组PGID为5128,top所在进程组PGID为5180,为前台进程组。

[root@tivf09 root]# ps -xj|grep 5128  5126  5128  5128  5128 pts/0     5180 S        0   0:00 -bash  5128  5180  5180  5128 pts/0     5180 S        0   0:50 top  3672 18095 18094  3672 pts/2    18094 S        0   0:00 grep 5128

关闭第一个窗口,在另一个窗口中可以看到top也被杀掉了。

[root@tivf09 root]# ps -ef|grep 5128 root     18699  3672  0 04:35 pts/2    00:00:00 grep 5128

如果我们可以忽略SIGHUP信号,关掉窗口应该就不会影响程序的运行了。nohup命令可以达到这个目的,如果程序的标准输出/标准错误是终 端,nohup默认将其重定向到nohup.out文件。值得注意的是nohup命令只是使得程序忽略SIGHUP信号,还需要使用标记&把它放在后台运行。

nohup  [argument...] &

虽然nohup很容易使用,但还是比较”简陋”的,对于简单的命令能够应付过来,对于复杂的需要人机交互的任务就麻烦了。

其实我们可以使用一个更为强大的实用程序。流行的Linux发行版(例如Red Hat Enterprise Linux 4)通常会自带实用程序,如果没有的话,可以从GNU 的官方网站下载。

[root@tivf06 ~]# rpm -qa|grep  xscreensaver-4.18-5.rhel4.11 -4.0.2-5

开始使用

简单来说,是一个可以在多个进程之间多路复用一个物理终端的窗口管理器。中有会话的概念,用户可以在一个会话 中创建多个窗口,在每一个窗口中就像操作一个真实的telnet/连接窗口那样。在中创建一个新的窗口有这样 几种方式:

1.直接在命令行键入命令

[root@tivf06 ~]# 

将创建一个执行的全屏窗口。你可以执行任意程序,就像在窗口中那样。在该窗口中键入exit退出该窗口,如果这是该会话的唯一窗口,该会话退出,否则自动切换到前一个窗口。

2.命令后跟你要执行的程序。

[root@tivf06 ~]#  vi test.

创建一个执行vi test.的单窗口会话,退出vi将退出该窗口/会话。

3.以上两种方式都创建新的会话。我们还可以在一个已有会话中创建新的窗口。在当前窗口中键入-a ,即Ctrl键+a键,之后再按下键, 在该会话内生成一个新的窗口并切换到该窗口。

还有更高级的功能。你可以不中断窗口中程序的运行而暂时断开(detach)会话,并在随后时间重新连接(attach)该会话,重新控制各窗口中运行的程序。例如,我们打开一个窗口编辑/tmp/abc文件:

[root@tivf06 ~]#  vi /tmp/abc

之后我们想暂时退出做点别的事情,比如出去散散步,那么在窗口键入-a d会给出detached提示:
暂时中断会话
暂时中断会话

半个小时之后回来了,找到该会话:

[root@tivf06 ~]#  -ls There is a  on:         16582.pts-1.tivf06      (Detached) 1 Socket in /tmp/screens/S-root.

重新连接会话:

[root@tivf06 ~]#  -r 16582

看看出现什么了,太棒了,一切都在。继续干吧。

你可能注意到给发送命令使用了特殊的键组合-a。这是因为我们在键盘上键入的信息是直接发送给当前窗口,必须用其他方式 向窗口管理器发出命令,默认情况下,接收以-a开始的命令。这种命令形式在中叫做键绑定(key binding),-a叫做命令字符(command character)。

可以通过-a ?来查看所有的键绑定,常用的键绑定有:

-a ? 显示所有键绑定信息
-a w 显示所有窗口列表
-a -a 切换到之前显示的窗口
-a 创建一个新的运行的窗口并切换到该窗口
-a n 切换到下一个窗口
-a p 切换到前一个窗口(与-a n相对)
-a 0..9 切换到窗口0..9
-a a 发送 -a到当前窗口
-a d 暂时断开会话
-a k 杀掉当前窗口
-a [ 进入拷贝/回滚模式

常用选项

使用键绑定-a ?命令可以看到, 默认的命令字符(Command key)为-a,转义-a(literal ^a)的字符为a:
常用选项
Screen 常用选项

因为-a看作是命令的开始,所以如果你想要窗口接收到-a字符,就要输入-a a。也允许你使用-e选项设置自己的命令字符和转义字符,其格式为:

-exy x为命令字符,y为转义命令字符的字符

下面命令启动的会话指定了命令字符为-t,转义-t的字符为t,通过-t ?命令可以看到该变化。
自定义命令字符和转义字符
自定义命令字符和转义字符

[root@tivf18 root]#  -e^tt

其他常用的命令选项有:

- file 使用配置文件file,而不使用默认的$HOME/.screenrc
-d|-D [pid.tty.host] 不开启新的会话,而是断开其他正在运行的会话
-h num 指定历史回滚缓冲区大小为num行
-list|-ls 列出现有会话,格式为pid.tty.host
-d -m 启动一个开始就处于断开模式的会话
-r sessionowner/ [pid.tty.host] 重新连接一个断开的会话。多用户模式下连接到其他用户会话需要指定sessionowner,需要setuid-root权限
-S sessionname 创建会话时为会话指定一个名字
-v 显示版本信息
-wipe [match] 同-list,但删掉那些无法连接的会话

下例显示当前有两个处于detached状态的会话,你可以使用 -r 重新连接上:

[root@tivf18 root]#  -ls There are screens on:         8736.pts-1.tivf18       (Detached)         8462.pts-0.tivf18       (Detached) 2 Sockets in /root/..  [root@tivf18 root]#  -r 8736

如果由于某种原因其中一个会话死掉了(例如人为杀掉该会话),这时 -list会显示该会话为dead状态。使用 -wipe命令清除该会话:

[root@tivf18 root]# kill -9 8462 [root@tivf18 root]#  -ls   There are screens on:         8736.pts-1.tivf18       (Detached)         8462.pts-0.tivf18       (Dead ???) Remove dead screens with ' -wipe'. 2 Sockets in /root/..  [root@tivf18 root]#  -wipe There are screens on:         8736.pts-1.tivf18       (Detached)         8462.pts-0.tivf18       (Removed) 1 socket wiped out. 1 Socket in /root/..  [root@tivf18 root]#  -ls   There is a  on:         8736.pts-1.tivf18       (Detached) 1 Socket in /root/..  [root@tivf18 root]#

-d -m 选项是一对很有意思的搭档。他们启动一个开始就处于断开模式的会话。你可以在随后需要的时候连接上该会话。有时候这是一个很有用的功能,比如我们可以使用它调试后台程序。该选项一个更常用的搭配是:-dmS sessionname

启动一个初始状态断开的会话:

[root@tivf06 tianq]#  -dmS mygdb gdb execlp_test

连接该会话:

[root@tivf06 tianq]#  -r mygdb

管理你的远程会话

先来看看如何使用解决SIGHUP问题,比如现在我们要ftp传输一个大文件。如果按老的办法,登录到系统,直接ftp命令开始 传输,之后。。如果网络速度还可以,恭喜你,不用等太长时间了;如果网络不好,老老实实等着吧,只能传输完毕再断开连接了。让我们使用 来试试。

登录到系统,在命令行键入

[root@tivf18 root]# 

窗口中输入ftp命令,登录,开始传输。不愿意等了?OK,在窗口中键入-a d:
管理你的远程会话
管理你的远程会话

然后。。退出登录?随你怎样,只要别杀掉会话。

是不是很方便?更进一步,其实我们可以利用这种功能来管理你的远程会话,保存你所有的工作内容。你是不是每次登录到系统都要开很多窗 口,然后每天都要重复打开关闭这些窗口?让来帮你”保存”吧,你只需要打开一个窗口,创建需要的窗口,退出的时候-a d”保存”你的工作,下次登录后直接 -r 就可以了。

最好能给每个窗口起一个名字,这样好记些。使用-a A给窗口起名字。使用-a w可以看到这些窗口名字,可能名字出现的位置不同。使用putty:
putty
putty

使用telnet:
telnet
telnet

更多功能

提供了丰富强大的定制功能。你可以在的默认两级配置文件/etc/screenrc和$HOME/.screenrc中指 定更多,例如设定选项,定制绑定键,设定会话自启动窗口,启用多用户模式,定制用户访问权限控制等等。如果你愿意的话,也可以自 己指定配置文件。

以多用户功能为例,默认是以单用户模式运行的,你需要在配置文件中指定multiuser on 来打开多用户模式,通过acl*(acladd,acldel,aclchg…)命令,你可以灵活配置其他用户访问你的会话。更多配置文件内 容请参考的man页。

16一/090

CMake 项目卸载方法

默认不提供 uninstall 这个 target,想要的话,输入:

xargs rm < install_manifest.txt

对于不修改配置的项目足够了。
manifest.txt是生成的安装文件列表。