Linux 101 Hacks笔记(一)

话说之前的两周一直在做电子电工:串行序列信号延时时间测试系统 . 具体做什么的我也记不清了 . 不过我记得那两周我做完了两件事 , 第一件事是直接拿了超超主席的实习成果变为己有 ; 第二件事是在实验室的虚拟机上看完了<<Linux 101 Hacks>> ,点击这里下载原著;点击这里下载翻译版. 这篇博客就是一个总结(小学老师告诉我们要会总结 , 这样才会进步).

PS : 我这里记录的是我认为写的比较cool的Hacks , 并不一定适用于每位同学 ( 为了大多数人着想 , 我还是用母语吧 ) 

1 ) CDPATH :设置 cd 命令的基目录
如果你经常使用 CD 命令进入某一个特定目录下的子目录,你可以将 CDPATH 设置为该目录,当使用 cd 进入其下的子目录时,则不需要键入该目录名.
如果希望设置永久有效,可以将CDPATH 写入 ~/.bash_profile .
$export CDPATH=/etc
$cd logcheck
/etc/logcheck
[注: 以上为进入/etc 下的 logcheck目录,而不是当前目录下的 logcheck 目录]

这个技巧在如下情况中使用相当广泛:
Oracle的数据库管理员(DBAs)经常要在ORACLE的家目录($ORACLE_HOME)下工作,就可以将CDPATH变量设置为Oracle的目录.
Linux/Unix系统管理员经常要在/etc目录下工作,就可以将CDPATH变量设置成/etc.
开发者要经常在工程目录下工作,如/home/projects,就可以将CDPATH变量设置为 /home/projects.
普通用户经常要在他们的主目录下进行子目录之间的切换,就可以设置CDPATH变量为~(这是Linux/Unix中主目录的简单写法)

2) 使用 cd 和 alias 命令快速返回上级目录
至于怎么设置 , 怎么方便怎么设置 , 作者给出的几种方法我觉得这一种比较好 :
$alias cd1="cd .."
$alias cd2="cd ../.."
$alias cd3="cd ../../.."
$alias cd4="cd ../../../.."
$alias cd5="cd ../../../../.."

3) 用 “cd -” 在最近访问的两个目录之间切换
如下:
$ cd /tmp/very/long/directory/structure/that/is/too/deep
$ cd /tmp/subdir1/subdir2/subdir3
$ cd –
$ pwd
/tmp/very/long/directory/structure/that/is/too/deep

4) 用 “dirs”、”pushd”、“popd” 来操作目录栈
你可以将目录压入目录栈,也可以稍后将该目录弹出。在随后的示例中,将会用到以下三个命令:
dirs:显示目录栈
pushd:将目录压入目录栈
popd:将目录弹出目录栈

5) 用特定格式显示当前/未来/过去时间
显示时间后跳行 , 再显示目前日期
$date +%T%n%D

格式化输出
$date +%Y-%m-%d

输出昨天的日期( "1 day ago" 和+之间有空格 )
$date    -d "1 day ago" +%Y-%m-%d  

2秒后输出
$date    -d "2 seconds" +"%Y-%m-%d %H:%M.%S"

传说中的 1234567890 秒
$date -d "1970-01-01    1234567890 seconds"    +%Y-%m-%d %H:%m:%S

本年度的第几天
$date +%j   

从1970年1月1日至今的秒数
$date +%s

取出前1天的系统时间
$date -d "a day ago" +%Y%m%d

取出前2天的系统时间
$date -d "2 days ago" +%Y%m%d

取出1天后的系统时间
$date -d "a day " +%Y%m%d

取出2天后的系统时间
$date -d "2 days" +%Y%m%d

注意 :当你不希望出现无意义的 0 时(比如说 1999/03/07) , 则可以在标记中插入 – 符号 . 比如说 date+%-H:%-M:%-S会把时分秒中无意义的 0 给去掉 , 像是原本的 08:09:04 会变为 8:9:4 .

6) grep 命令
显示了所有在 “/etc/password” 下不含有“jaseywang”的内容
$grep -c jaseywang /etc/passwd

不含有 “jaseywang” 的行的总数
$grep -cv jaseywang /etc/passwd

利用 “-i” 搜索的时候会忽略大小写
$grep -i jaseywang /etc/passwd

在目录下搜索所有符合的条目
$grep -r jaseywang /home/jaseywang

只显示相应的目录 , 而不显示内容
$grep -rl jaseywang /home/jaseywang

7) find 命令
查找在“/etc”目录下所有文件名中含有“mail”的文件
$find /etc -name "*mail*"

寻找系统中大于100M的文件
$find / -type f -size +100M

在当前目录下查找最近没有被修改的文件
$find . -mtime +60
$find . -mtime -2

PS:以不同的形式显示该文件的大小
$du -sh linuxeden.pdf
$du -sk linuxden.pdf
$du -sm linuxden.pdf

删除扩展名为.tar.gz 并且大于 100M 的压缩文件
#find / -type f -name “*.tar.gz” -size +100M -exec rm -f {} \;

在下面这两种情况下 , 您都需要对通配符进行转义以确保它传递到 find 命令并且不由 shell 解释. 因此 , 请将您的搜索字符串放到引号里 , 或者在它前面加上反斜线 .
$find . -name "*.java"
$find . -name \*.java

下面两个命令的最后输出结果还是有差别的 . 请自行测试 .
$find . "*.pdf"
$find ~/Desktop/PDF "*.pdf"

将错误发送至空文件
#find /root -name "*.jar" 2>/dev/null

将输出和运行错误都放到黑洞里去 , 其实就是没有显示了
$find . -name "*.pdf" > /dev/null 2>&1

不区分大小写
$find . -name "*.JPG"
$find . iname "*.JPG"

mtime , ctime , atime , mmin , cmin , amin的区别 :
-amin n : 查找系统中最后N分钟访问的文件
-atime n : 查找系统中最后n*24小时访问的文件
-cmin n : 查找系统中最后N分钟被改变文件状态的文件
-ctime n : 查找系统中最后n*24小时被改变文件状态的文件
-mmin n : 查找系统中最后N分钟被改变文件数据的文件
-mtime n : 查找系统中最后n*24小时被改变文件数据的文件

结尾的“c”以字节为单位,即找出大于5M的文件.
$find . -size +5000000c 2>/dev/null

寻找perm为777的文件:
$find . -type f -perm 777 -exec ls -l {} \;
$find . -type f -perm a=rwx -exec ls -l {} \;

通过运行以下命令在目录树的前三个级别中查找日志文件 , 您可以看到 -maxdepth 的效果
#find / -maxdepth 3 -name "*.log"
#find / -mindepth 3 -name "*.log"

8) xargs 命令
当你使用 rm 命令去删除很多的文件时,你可能会得到错误信息:“/bin/rm list too long – Linux” . 这时可以用 xargs 来避免这个问题.
$find ~ -name   “*.log” -print0 | xargs -0 rm –f

当你想下载一些 URL,这些 URL 都保存在一个文件里,你可以以如下的方式使用 xargs 命令
$cat url-list.txt | xargs wget –c

找出所有的.jpg 格式的图片,并将其归档
#find / -name “*.jpg” -type f -print | xargs tar -cvzf images.tar.gz

9) sort 命令
升序排列
$sort name.txt

降序排列
$sort -r name.txt

对passwd的第3栏进行排序
$cat /etc/passwd | sort -t ":" -k 3 -n

10) uniq 命令
列出不同的条目
$sort test | uniq -u

列出重复的条目
$sort test | uniq -d

相同的条目的条数
$sort test | uniq -dc

不同条目的条数
$sort test | uniq -uc

不要列出重复的条目
$sort test | uniq

11) cut命令
显示一个以冒号分隔的文件中的第一列
$cut -d: -f 1 names.txt

显示一个以冒号分隔的文件中的第一列和第三列
$cut -d: -f 1,3 names.txt

显示文件中每行的前八个字符
$cut -c 1-8 names.txt

12) PS1——默认提示符
请看我之前写的一篇博客 , 狂击这里

13) PS2——再谈提示符
一个非常长的命令可以通过在末尾加“\”使其分行显示 . 多行命令的默认提示符是“>” .  我们可以通过修改 PS2 ,将提示符修改为"continue->"  .
$export PS2="continue-> "

14) PS3——Shell 脚本中使用 select 时的提示符
$cat ps3.sh
select i in mon tue wed exit
do
case $i in
mon) echo "Monday";;
tue) echo "Tuesday";;
wed) echo "Wednesday";;
exit) exit;;
esac
done

$./ps3.sh
1) mon
2) tue
3) wed
4) exit
#? 1
Monday
#? 4
[注: 缺省的提示符是 #?]

改造以后
$cat ps3.sh
PS3="Select a day (1-4): "
select i in mon tue wed exit
do
case $i in
mon) echo "Monday";;
tue) echo "Tuesday";;
wed) echo "Wednesday";;
exit) exit;;
esac
done

$./ps3.sh
1) mon
2) tue
3) wed
4) exit
Select a day (1-4): 1
Monday
Select a day (1-4): 4
[注: 设置了 PS3 变量后,命令提示符已经成为 "Select a day (1-4):"]

15) PS4——PS4-“set -x"用来修改跟踪输出的前缀
$cat ps4.sh
set –x
echo "PS4 demo script"
ls -l /etc/ | wc –l
du -sh ~

$./ps4.sh
++ echo 'PS4 demo script'
PS4 demo script
++ ls -l /etc/
++ wc –l
243
++ du -sh /home/ramesh
48K
/home/ramesh
[注: 当使用 sex -x 跟踪输出时的提示符为 ++]

PS4 在 ps.sh 中定义了下面两个变量
$0 显示当前的脚本名
$LINENO 显示的当前的行号

$cat ps4.sh
export PS4='$0.$LINENO+ '
set -x
echo "PS4 demo script"
ls -l /etc/ | wc -l
du -sh ~

$./ps4.sh
../ps4.sh.3+ echo 'PS4 demo script'
PS4 demo script
../ps4.sh.4+ ls -l /etc/
../ps4.sh.4+ wc -l
243
../ps4.sh.5+ du -sh /home/ramesh
48K
/home/ramesh
[注: 使用 PS4 后使 "{script-name}.{line-number}+" 成为 set –x 的命令提示符]

16) PROMPT_COMMAND 环境变量
Bash 在显示 PS1 之前先执行 PROMPT_COMMAND 定义的内容

$export PROMPT_COMMAND="date +%H:%M:%S"
[ $export PROMPT_COMMAND="date +%T" ]
19:27:16
>

$export  PROMPT_COMMAND="date +%Y-%m-%d"
2010-09-14
>

如果你想让 PROMPT_COMMAND 和 PS1 在同一行显示,用 -n 参数即可:
$export PROMPT_COMMAND="echo -n [$(date +%Y-%m-%d)]"
[2010-09-14]>

$export PROMPT_COMMAND="echo -n $(date +%D)"
09/14/10>

17) zip 命令基础

$zip test.zip test/

递归地压缩一个目录及目录下的文件
$zip -r test.zip test/

显示详细的解压缩过程
$unzip -v(verbose) test.zip

不解压缩而查看压缩文件里面的内容
$unzip -l(ls) test.zip

18) zip 高级用法
zip 命令提供了十个压缩等级:
等级 0 是最低等级,只做归档,不压缩
等级 1 压缩率低,但速度很快
等级 6 是默认的压缩等级
等级 9 的压缩率最高,但它耗时也多,除了大文件,我们一般推荐于用等级 9

$zip -r -9 test.zip test
通过ls -ltr查看(t:按modify的时间排序 , r反向)

19) zip 文件的密码保护
为文件加密
$zip -P password test.zip test
或者
$zip -e(encrypt) test.zip test

20) 检查 zip 文件的完整性
检测文件是否完整
$unzip -t(test) test.zip

21) tar 命令的基础知识
只打包不压缩
$tar -cv(verbose)f test.tar test

查看包含哪些文件
$tar -tvf test.tar

压缩成.tar.gz文件
$tar -zcvf test.tar.gz test

解压至指定的目录
$tar -zxvf test.tar.gz -C /home

查看,不解压
$tar -tcvf test.tar.gz

22) 在 tar 中使用bzip2
bzip2压缩的时间跟gzip相比较慢 , 但压缩率更高
$tar -jcvf test.tar.bz2 test
$tar -jxvf test.tar.bz2
$tar -jtvf test.tar.bz2

Linux 101 Hacks(二)将要触及全书的精华,敬请期待:-)

  • http://www.freetstar.com freetstar

    比较经典。
    貌似中文版的那本翻译的不时很好

    • jaseywang

      还说得过去吧,能看得懂==

  • http://blog.ibfsu.com Carlos Gong

    考虑去加个代码显示插件呗~

    • jaseywang

      我的wp里面有,但是禁用了,这么多命令一个一个加会出事了,而且感觉加了也不是很好看的样子…

  • http://blog.mrseacow.org mrseacow

    作者还写了本VIM hacks 101,也挺有趣的。
    其实关键还是用熟shell和RTFM…

    对了。。。果断求链接~~

    • jaseywang

      我也想看阿,不过网上貌似没有电子版的,一本书要20+USD了><
      不要求啦,小弟主动加海牛大叔的:D