• Bash 补全技巧 - [LBE]

    2007-10-31

    原文:A Bash Completion Tip
    作者:mysurface
    译者:gosman(lianmingchang2008#gmail.com)
    来自:http://gosman.blogbus.com/
    版本:V 1.0.0
    时间:2007-10-31

    Bash 补全对 bash 用户来说是个强大的命令行技巧,按 tab 键就可以对命令行自动补全。不了解 bash 补全的话,可以参看 CLI magic: programmable bash completion

    Bash 补全的一个特色就是在用 tab 补全时能够隐藏未知的扩展名。比如要解压文件,可以输入

    tar -zxvf (tab) (tab)

    我不想列出那些扩展名不是 .tar.gz 的文件。因此,bash 补全智能地将其过滤。那我要分享的技巧又是什么呢?

    如何让某个命令列出其缺省不支持的扩展名呢?举个例子,用 kaffeine 播放视频文件时,我喜欢在终端启动 kaffeine,那样的话我可以在浏览文件立即播放。

    kaffeine 的 bash 补全缺省不支持 .flv。那要如何添加 flv 到 kaffeine 的 bash 补全呢?

    sudo vi /etc/bash_completion

    编辑 /etc/bash_completion,使用哪个编辑器不要紧,只要能搜索‘kaffeine‘就行了。

    更改的内容用粗体表示

    complete -f -X '!*.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|vcd|ps|pes|fli|flv|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp3|MP3|ogg|OGG|ogm|OGM|mp4|MP4|wav|WAV|asx|ASX|mng|MNG|srt)’ xine aaxine fbxine kaffeine

    重启终端,现在 kaffeine 的 bash 补全支持 .flv了。

  • 原文:Writing scripts that needs root permission
    作者:mysurface
    译者:gosman(lianmingchang2008#gmail.com)
    来自:http://gosman.blogbus.com/
    版本:V 1.0.0
    时间:2007-9-4

    当执行需要超级用户(root)权限的命令时,我会使用sudo。sudo提供了一种只要我的帐户密码就可以执行超级用户权限命令的简便方法。

    sudo和su是不一样的,可以参考这里

    但在写脚本时,不能直接使用sudo。例如,我写了个用我的DNS设置来修改/etc/resolv.conf的脚本。修改/etc/resolv.conf需要超级用户权限。但在脚本里,我不能直接使用sudo。

    下面的脚本就不能工作。

    
    #!/bin/bash
    # the lines below doesn't work!!!
    sudo echo "nameserver 202.188.1.5" > /etc/resolv.conf
    sudo echo "nameserver 202.188.0.133" >> /etc/resolv.conf
    cat /etc/resolv.conf
    
    

    可以将所有需要超级用户权限的命令写在一个脚本里,然后在外部用sudo执行此脚本。比如我的脚本是set_dns.sh。

    sudo ./set_dns.sh 

    上面的方法可以工作,但是我想在普通用户执行时会提示需要sudo密码呢?我找到了一个方法,下面的脚本就可以做到。

    
    #!/bin/bash
    if [ "$1" == 'done' ]
    then
        #the commands needs root permission list as below
        echo "nameserver 202.188.1.5" > /etc/resolv.conf
        echo "nameserver 202.188.0.133" >> /etc/resolv.conf
        cat /etc/resolv.conf
    else
        sudo $0 done
    fi
    
    

    我把它写成一个模板,只要替换'then'和'else'之间的那部分就行了。

  • 原文:smart grouping shorten long command line 2
    作者:mysurface
    译者:gosman(lianmingchang2008#gmail.com)
    来自:http://gosman.blogbus.com
    版本:V 1.0.0
    时间:2007-7-22

    该文章描述大括号在扩展数量范围中的应用,是"巧用分组缩短命令长度"的后续。

    有一批日志文件,只需分析其中的一部分。

    tcp_06062007_1.txt
    ...
    tcp_06062007_180.txt
    tcp_06062007_181.txt
    tcp_06062007_182.txt
    ...
    tcp_06062007_230.txt

    要归档182到192的日志文件。

    tar cjvf tcp_log.tar.bz2 tcp_06062007_{182..192}.txt

    记住不能使用中括号[],中括号是用于字符块的,[182-192]表示1、8、9、2之一而不是182到192。

    译注:这里{}为括号扩展,而[]是正则表达式,它们有根本区别。

  • 原文:record the terminal session and replay later
    作者:mysurface
    译者:gosman(lianmingchang2008#gmail.com)
    来自:http://gosman.blogbus.com
    版本:V 1.1.1
    时间:2007-5-12

    我在linuxinsight看到这神奇的东西。你可以录制输入、屏幕输出甚至运行的ncurses程序,会话和时序分别保存到两个文件。通过这两个文件,你可以使用scriptreplay播放录制的终端会话。

    录制会话:

    script -t 2> tutorial.timing -a tutorial.session

    输入'exit'结束录制。

    播放会话:

    scriptreplay tutorial.timing tutorial.session

    会话和时序文件都是可读的,如果不需要播放,只需:

    srcipt -a tutorial.txt

    也许你想知道srcipt怎么做到的?记录你的输入和屏幕输出?那岂不是密码也会被记录当使用sudo时?当然不是这样的,script只是保存对你可见的信息,而不是键盘输入。scriptreplay也是这样,只是播放录制的内容,而不会真正执行播放的命令。

    我发现录制和播放都需要两个文件(会话和时序),有点麻烦。因此写了个名为script.sh的bash脚 本,只产生一个文件(只是耍了个小把戏,看脚本就会明白的),录制和播放都比较方便。

    录制:

    ./script.sh -r

    播放:

    ./script.sh -p

    获得srript.sh并尝试,记得从tar包解压出来后需chmod +x使该脚本可执行。

    可以下载我的输出文件-matrix,并用script.sh播放。

    ./script.sh -p matrix

    Have Fun

    译注:ncurses的更多信息可以看:《NCURSES Programming HOWTO中文版(第二版)》,ncurses好像没有正规的中文名称,本文不做翻译,有人翻译为‘荧幕导向程序’,可作参考。

    更正:scriptplay更正为 scriptreplay(2006.5.12)

  • 原文:CLI Magic: command not found, suggest what to apt-get
    作者:mysurface
    译者:gosman(lianmingchang2008#gmail.com)
    来自:http://gosman.blogbus.com
    版本:V 1.1.0
    时间:2007-9-7

    最近我从 Ubuntu Edgy 升级到 Ubuntu Feisty,发现 Feisty 一个有趣的程序 command-not-found。当你输入系统中不存在的命令时,该程序就会提示包含该命令的安装包并提示用 apt-get 安装。

    以未安装的命令 trafshow 为例,输出为:

    The program 'trafshow' is currently not installed. You can install it by typing:
    sudo apt-get install netdiag
    Make sure you have the 'universe' component enabled
    bash: trafshow:找不到命令
    

    如果不行的话,请去掉 /etc/bash.bashrc 中以下语句的注释:

    # if the command-not-found package is installed, use it
    if [ -x /usr/bin/command-not-found ]; then
    function command_not_found_handle {
    /usr/bin/command-not-found $1
    return $?
    }
    fi
    

    command-not-found 命令是能返回提示语句的 Python 脚本。因此只要输入command-not-found <command name>就会输出提示语句,不管该命令安装与否。

    command-not-found gedit
    The program 'gedit' is currently not installed. You can install it by typing:
    sudo apt-get install gedit
    

    我们可以用 command-not-found 查找包含特定命令的安装包,与可以完成同样操作的dpkg -S相比,command-not-found查询更迅速。

    还可以在 bash 脚本中使用 command-not-found 命令。看下面这个简单脚本:

    #!/bin/bash
    Cmd=`which trafshow`;
    if [ -n $Cmd ]
    then
    command-not-found trafshow
    fi
    

    以上脚本查找 trafshow 的绝对路径,如果 tarfshow 没有安装,变量 Cmd 是个空值(null)就会返回 command-not-found 的提示语句。这样做的原因是在 bash 脚本中不会自动使用 command-not-found 特性。我的意思是在 bash 脚本中使用未安装的命令,不会输出 command-not-found 的提示语句。

    我不知道除了 Ubuntu Feisty 在别的发行版本中是否有 command-not-found,从Agile Testing那里知道可以在 Ubuntu Edgy中用 apt-get 安装 command-not-found。

    command-not-found 特性会减慢命令行的处理,因为每次输入未安装的命令时就会执行查找工作。Niath对 command-not-found 执行时间进行测试,结果是我们能接受的。