1、1Unix 及 Shell 基础钱善海 2007-8-6目的: 熟悉使用 Unix 环境, 使用 bash 提高效率.主要内容: Shell 介绍 ,基本命令使用,使用 bash,Shell 脚本2目 录0. Unix 介绍 31. Shell 命令 .31.1 Shell 介绍 31.2 启动文件与环境变量 .31.3 内建命令 .51.4 匹配符 .51.5 选择 Shell.61.5.1. bash 介绍 61.5.1.1 bash 优点 .61.5.1.2 约定 .61.5.1.3. bash 快捷键 .61.5.1.4 示例 .71.5.2 其它 Shell71.6 基本命令 .81
2、.7 输入输出重定向 .111.8 文件权限和进程 .122. Shell 编程 123. 其它需要熟悉的 .1330. Unix 介绍google “Unix 历史“1. Shell 命令1.1 Shell 介绍Unix 系统分成三个重要部份: 系统核心, Shell, 工具程序。用户不易和系统内核直接沟通, 需要有一个友善的界面(interface), 使得操作时能更为方便, 这个界面便是 Shell。 系统启动过程: 在机器启动时由引导程序载入内核文件 , 之后把控制权交给内核, 内核初始化后 执行的第一个程序是 init , 然后再初始化到登录界面, 这时候就到了大概如下的界面: lo
3、gin: 登录后就执行了默认的 Shell, 这在 /etc/passwd 中指定。目前常见的 shell 有:a. Bourne shell : sh b. C shell : csh c. Korn shell: kshd. tcsh (free) f. Bourne Again shell: bash (GNU) 41.2 启动文件与 环境变量进入 shell 后会执行用户的配置文件, 具体文件名视所用 shell 而定, 通常都会执行 /.profile 或 /.bash_profile。内核在执行程序的时候可以传入环境变量(见 man execve), 格式是 word=value,
4、当然了, 这个格式是由应该程序解释的, 所以在 shell 中用了大量的环境变量, 其中有些是常用的:PATH shell 查找命令和程序的路径HOME 用户的主目录, 默认是在 /etc/passwd 中指定的目录PS1 在命令行出 现的 shell 命令提示符TERM 终端类型SHELL 一些程序如 vim 会用到查看相关环境变量设置:$ echo $TERM设置环境变量:$ export PATH=$PATH:/usr/local/bin为了安全, 不要把当前路径加到 $PATH 中。看下面的例子:$ cat ls t.c char *env = “PATH=/bin:/usr/bin:
5、/usr/local/bin“,“TERM=vt100“,“SHELL=/bin/sh“,NULL;char *sh = “/bin/sh“,NULL;int main(int argc, char *argv)setuid(geteuid();setgid(getegid();execve(sh0, sh, env);return 0;EOF$ cc -o t t.c通常我们进入后第一件事就是执行 ls , 于是上面的脚本被执行, 最后我们得到一个设置了有效 ID 的程序。1.3 内建命令shell 中有一些是内建的命令如: cd, alias, export, bg, fg, pwd, e
6、cho, history当中有些可以用其它程序代替 pwd, echo, 但像 cd 等是不可能用程序代替的。$ cd $ cd # 同上$ cd $HOME # 同上$ cd # 上一 层目录$ cd - # 回到先前的目 录61.4 匹配符在命令的参数中, 可以输入一些特殊字符, 用来匹配一些字符串. 常用的是 * 和 ?。 * 匹配 0 个或多个? 匹配 0 个或 1 个 指定范 围, 如 1-5 匹配 1 至 5 的其中一个 .如: $ ls *.ca.c b.c c.c在上面的命令中, 会列出当前目录下所有以 .c 结尾的文件, 处理过程是这样的: shell 先把 *.c 展开成
7、“a.c b.c c.c“, 然后再把展开后的列表当作参数给 ls , 并不是命令 ls 去解析当中的星号(*)的。若是不想让星号(*)当成匹配符, 那么可以用反斜杆()进行转义:$ ls *.c # 相当于 ls *.c匹配符使用起来方便无比, 但有时一不小心会造成恶梦的开始, 像下面的:$ rm * .bak # 在*和.之间多打了个空格, 结果当前目录的文件全部丢失。于是, 慢慢地使用了下面的定义:$ alias rm=rm -i$ alias mv=mv -i$ alias cp=cp -i但这样也不能解决问题, 使用这三个命令只能靠小心:$ rm -f * .bak # 效果跟上面一
8、 样, 但更为静悄悄(没有任何输出)71.5 选择 Shell1.5.1. bash 介绍1.5.1.1 bash 优点bash 全称是 GNU Bourne-Again Shell优点:a) GNU 软件, 可自由使用, 拷贝, 修改再发布.b) 使用 readline 库, 使得行编辑很方便.1.5.1.2 约定以 X 表示 Ctrl+X, X 为任意字符, 表示输入 Tab 键1.5.1.3. bash 快捷键A 跳到最前端, 跟 Home 同样效果B 向左移一字符 , 较 少使用.C 重新 编辑D 删除光标所在字符,或退出E 跳到最末端, 跟 End 同样效果F 向右移一字符, 较少使
9、用.H 删除光标前一字符N 显示下一个历史命令U 删除光标前的所有字符K 删除光标后(包括当前光标)的所有字符, 较少使用.8P 显示上一个历史命令R 查找命令T 交换当前光标字符和光标前一字符, 较少使用.W 删除前一字(word)Y 粘贴最后一次由 U 或 K 或 W 删除的字符J , O, M , 相当于回车, 较少使用. I 跟 Tab 一样效果 , 一般使用 Tab .自动补全命令或文件名!cmd 慎用! 一般用 R 代替.1.5.1.4 示例1.5.1.4.1 Tab显示所有命令:qshbeta qsh$ Display all 2124 possibilities? (y or
10、n)显示所有以 ls 开头的命令:qshbeta qsh$ lsls lsattr lsb_release lsdev lsof qshbeta qsh$ ls显示以 open 开头的文件 :qshbeta qsh$ ls open如果存在多个这样的文件, 那么再按 后:qshbeta qsh$ ls openssh-4.2p1.tar.gzopenssh-4.2p1.tar.gz openssh-4.2p1.tar.gz.bak91.5.1.4.2 各种快捷键$ ls /usr/src/现在想跳到目录 /usr/src , 可以输入 PWCcd Y 就变成$ cd /usr/src$ cp
11、/bin/test.1 /path/to/dir当输入上面的命令后, 发现应该是 test.12 , 可以输入 PWH2 Y 就变成$ cp /bin/test.12 /path/to/dir$ im tmpfile还没按 Enter 键时发现少打 v 了, 只需 Av 即可.1.5.2 其它 Shell基于 bash 的优点, 我 们应该使用 bash, 而有些人会 认为使用 vi 模式也能编辑得快, 理由是大家都熟悉 vi, 但是文本的编辑和一行的编辑是完全两码事的, 如果他们使用过 bash, 最终也会发现 bash 的行编辑确实很方便了。所以有些人设置了烦人的 vi 模式: set -
12、o vi , 可以使用 set +o vi 清除此设置。或者有人认为, 很多机器上没有 bash, 而其它 shell 用着用着就习惯了, 但习惯的东西并不是就是好的。如果使用较多的命令行, 无疑地, bash 能提高效率.1.6 基本命令Unix 的基本命令:man infocd, alias, export, fg, bg, historyls, pwd, cp, mv, rm, diff, sort, cat, more, grep, find, which, head, tail, chown, chmod, file, mkdir, rmdir, ln, touch, split,
13、cut, wc,echo, ps, su, kill, exit, passwd, chsh, sleep,df, du, history, date, id, ipcs, ipcrm,tar, gzip(gunzip), bzip2(bunzip2), compress(uncompress), zcat, zmore,10ftp, telnet, ssh (sftp),示例:$ man man # 查看命令 man 的手册$ man date # 查看 date 命令的帮助$ man localtime$ echo $PATH # 打印变量 PATH$ echo $? # 变量$? 是上一
14、个命令的返回状 态.$ alias rm=rm -i $ export PATH=$HOME/bin:$PATH$ which prog # 查看 prog 在哪, 在变量 $PATH 中找$ date # 系统时间, 显示或设置$ id # 用户信息$ su - test # 切换用户$ sleep 60 # 休眠$ history # 命令输入的历 史记录$ history | grep prog更改目录:$ cd # 相当于 cd $HOME$ cd /path/to/dir$ cd - # 跳回上一个路径基本的文件及目录操作:11$ ls # 查看文件或目录信息$ ls -l$ ls
15、/path/to/dir$ ls -lrt # 按文件修改时间排序$ cp file1 file2 # copy 文件$ cp -f file1 file2$ /bin/cp -f file1 file2$ cp file* /path/to/dir$ mv file1 file2 # 把 file1 改名 为 file2$ mv -f file1 file2$ rm file1 # 删除文件$ rm -f file2$ rm -rf /path/to/dir$ mkdir /path/to/dir # 创建目录$ mkdir -p path/to/dir/dir2 # 先创建目录 path,
16、 to, dir$ rmdir /path/todir # 删除空目录$ touch file # 更改文件 file 的修改时间为当前时间# 若无文件 file , 则创建空文件 file$ cat file # 把文件 file 输出至屏幕$ cat file # 从标准输入创 建一文件, 按 D 结束$ more file # 分页查看文件 file$ prog | more$ grep word file1 # 输出文件 file1 中有字 word 的行$ prog | grep word12$ head file1 # 输出文件的前 10 行$ tail file1 # 输出文件的
17、最后 10 行$ tail -f file1$ cut -b1-10 file1$ wc file1 # 统计文件的行数, 字节等$ wc -l file1$ sort file1 # 对文件的每行排序$ sort -u file1 # 去掉重复的行再排序$ prog | sort -u file1$ find . -name “*.c“ # 查找文件$ find /path/to/dir -type f$ find /path/to/dir -name “*.Z“ -exec rm -f ;$ find /path/to/dir -name “*.Z“ -exec zcat ; | perl
18、 -e do something$ split -l 1000 file1 # 分割文件成多个小文件$ split -a 3 -l 1000 file1$ chmod 755 file1 # 修改文件权限$ chmod +s file2$ chown qsh.devolop file3 # 修改文件的用户权限$ ln -s file1 file2 # 对文件做链接$ ln -s tmp/*.c tmp2$ ln /tmp/* tmp2查看进程及终止进程$ ps axu$ ps -ef$ kill -l$ kill 1234 # 终止进程, 默认发送信号 SIGTERM.$ kill -2 12
19、3413$ kill -9 1234 # 信号 9 是强制终止.文件系统及目录使用情况:$ df $ df /tmp$ df -k /tmp$ df .$ du /path/to/dir查看共享内存, 信号量, 消息队列情况:$ ipcs -s$ ipcs -a$ ipcs -m$ ipcs -am$ ipcrm -m 0x1234$ ipcrm -M 102394判断 file1 属于哪类文件 :$ file file1$ file which which文件压缩(解压缩) 及目录打包:$ tar -cf work.tar work # 把目录 work 打包为 work.tar$ tar
20、-cf /path/to/dir/work.tar work$ gzip work.tar # 压缩文件$ tar -cf - work | gzip - work.tar.gz # 打包的同时压缩$ gzip -cd work.tar.gz | tar -xf - # 解压缩文件$ gzip -cd file1.gz | more$ bzip2 -cd work.tar.bz2 | tar -xf -$ bunzip2 file2.bz2$ gunzip file3.gz14$ compress file1$ uncompress file1.Z$ zcat file1.Z$ zmore f
21、ile1.Z远程登录及文件传输$ ftp 10.200.27.92$ telnet 10.200.27.92$ ssh root10.200.27.92$ sftp root10.200.27.921.7 输入输 出重定向shell 一开始会打开三个文件描述符, 用来输入, 输出, 及显示错误的。标准输入: 通常是键盘, 文件描述符为 0 标准输出: 通常是屏幕, 文件描述符为 1 标准出错: 通常与标准输出相同(也就是屏幕), 文件描述符为 2 当我们执行下面的命令时, 是直接输出到屏幕的:$ ls -la若是想输出到另一文件中, 需要重定向输出:$ ls -al myfile 输 出转 向, 会先把文件清空1 标准输出2 标准出错15 输出转向, 追加写入1 标准输出2 标准出错myfile$ cat /etc/passwd | grep bash$ make -j4 tmpfile 2 thenecho $TERMfi但, 通常来 说, 我们不需要写复 杂的 shell 脚本 , 并且, 如果我们需要文本处理, 更不应该使用 shell 脚本, 也就是说, 不应该使用 sed 和 awk, 我们应该使用 perl。3. 其它需要熟悉的a. vim - 编辑器b. perl - 文本 处理c. make - 管理源代码