你必须要会的Shell 命令

 shell 介绍
=============

  Unix 系统分成三个重要部份: 系统核心, Shell, 应用程序
  如下图:

  +------------+         +---------+        +------------+
  |    内核    |  --->   |  shell  |  ----> |  应用程序  |
  +------------+         +---------+        +------------+
                    
  登录系统后执行的第一个程序就是 Shell, 这在 /etc/passwd 中指定.
  
  目前常见的 shell 有:
  
  a. Bourne Again shell: bash (GNU) -- 常用, 功能强大, 非常好用
  b. Korn shell: ksh                -- 比较少用
  c. C shell : csh                  -- 比较少用
  d. Bourne shell : sh              -- 很原始的 shell, 很少人用它
  e. tcsh                           -- 很少用

  在前面的图中, 应用程序是指一些常用命令, 例如 ls, cp 等,
  所以, 所谓 unix 环境需要学习的就是 shell 的配置文件,
  以及一些常用命令.

  由于 bash 实在是太好用了, 以后所说的 shell 均指 bash.

    以后可能会用到它做一些练习, 以提高 unix 使用及其它方面的能力.
 

3.1 环境变量与配置文件
----------------------

  进入 shell 后会执行用户的配置文件, 具体文件名视所用 shell 而定,
  通常都会执行 ~/.profile 或 ~/.bash_profile

  内核在执行程序的时候可以传入环境变量(见 man execve), 格式是 word=value,
  当然了, 这个格式是由应该程序解释的, 所以在 shell 中用了大量的环境变量,
  其中有些是常用的:

  PATH     shell 查找命令和程序的路径
  HOME     用户的主目录, 默认是在 /etc/passwd 中指定的目录
  PS1      在命令行出现的 shell 命令提示符
  TERM     终端类型
  SHELL    一些程序如 vim 会用到

  $ echo $TERM

3.2 登录设置
------------

  可使用多种工具登录到远程的 Unix 系统, 这里介绍的是使用 SecureCRT [1]
  在 SecureCRT 中, terminal 选 linux, 然后选中 ANSI color,
  这样就可以了, 颜色建议使用背景色为黑色, 前景色为灰白色,
  这样对眼睛来说比较舒服.

  在远程系统里把 TERM 设置成 vt100, 即:

  $ export TERM=vt100

  当然, 应该写到配置文件中, 例如我的配置文件:

  export TERM=vt100
  export SHELL=/bin/bash  # vim 里有用
  export PATH=$HOME/bin:$PATH:/usr/local/bin
  export LANG=zh_CN
  export PS1='[\u@106 \W]$ ' # 当前 shell 的提示
  export EDITOR=vim          # 有些程序用到, 例如 svn, 数据的前端 dbaccess


3.3 内建命令
------------

  shell 中有一些是内建的命令如: cd, alias, export, bg, fg,
  pwd, echo, history 当中有些可以用其它程序代替 pwd, echo,
  但像 cd 等是不可能用程序代替的.

  $ cd 
  $ cd ~       # 同上
  $ cd $HOME   # 同上
  $ cd ..      # 上一层目录
  $ cd -       # 回到先前的目录

3.4 匹配符
----------

  在命令的参数中, 可以输入一些特殊字符, 用来匹配一些字符串. 常用的是 * 和 ?
  
  *  匹配 0 个或多个
  ?  匹配 0 个或 1个
  [] 指定范围, 如 [1-5] 匹配 1 至 5 的其中一个.
  
  如:
  
  $ ls *.c
  a.c   b.c   c.c
  
  在上面的命令中, 会列出当前目录下所有以 .c 结尾的文件, 处理过程是这样的:
  shell 先把 *.c 展开成 "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   # 效果跟上面一样, 但更为静悄悄(没有任何输出)

  不过, 就算, 还是强烈大家在配置文件中加上这三条语句.

4. bash 介绍
============

4.1 何为 bash
-------------

  bash 的全称是 GNU Bourne-Again SHell

  优点:
  a) GNU 软件, 可自由使用, 拷贝, 修改再发布.
  b) 使用 readline 库, 使得行编辑很方便.

4.2 约定
--------

  以 ^X 表示 Ctrl+X, X 为任意字符, <TAB> 表示输入 Tab 键

4.3 bash 快捷键
---------------

  ^A 跳到最前端, 跟 Home 同样效果
  ^B 向左移一字符, 较少使用.
  ^C 重新编辑
  ^D 删除光标所在字符,或退出
  ^E 跳到最末端, 跟 End  同样效果
  ^F 向右移一字符, 较少使用.
  ^H 删除光标前一字符
  ^N 显示下一个历史命令
  ^U 删除光标前的所有字符
  ^K 删除光标后(包括当前光标)的所有字符, 较少使用.
  ^P 显示上一个历史命令
  ^R 查找命令
  ^T 交换当前光标字符和光标前一字符, 较少使用.
  ^W 删除前一字(word)
  ^Y 粘贴最后一次由 ^U 或 ^K 或 ^W 删除的字符

  ^J , ^O, ^M , 相当于回车, 较少使用. 
  ^I 跟 Tab 一样效果, 一般使用 Tab . 自动补全命令或文件名
  !cmd 慎用! 一般用 ^R 代替.

4.4  示例
---------

4.4.1 Tab 的功能
----------------

  显示所有命令:
  [qsh@beta qsh]$ <TAB><TAB>
  Display all 2124 possibilities? (y or n)

  显示所有以 ls 开头的命令:
  [qsh@beta qsh]$ ls<TAB>
  ls           lsattr       lsb_release  lsdev        lsof         
  [qsh@beta qsh]$ ls

  显示以 open 开头的文件:
  [qsh@beta qsh]$ ls open<TAB>

  如果存在多个这样的文件, 那么再按 <TAB> 后:
  [qsh@beta qsh]$ ls openssh-4.2p1.tar.gz
  openssh-4.2p1.tar.gz      openssh-4.2p1.tar.gz.bak

4.4.2 各种快捷键
----------------

  $ ls /usr/src/
  现在想跳到目录 /usr/src , 可以输入 ^P^W^Ccd ^Y 就变成
  $ cd /usr/src

  $ cp ~/bin/test.1 /path/to/dir
  当输入上面的命令后, 发现应该是 test.12 , 可以输入 ^P^W^H2 ^Y 就变成
  $ cp ~/bin/test.12 /path/to/dir

  $ im tmpfile
  还没按 Enter 键时发现少打 v 了, 只需 ^Av 即可.

4.5 对比其它 Shell
------------------

  基于 bash 的优点, 我们应该使用 bash, 而有些人会认为使用 vi 模式也能编辑得快,
  理由是大家都熟悉 vi, 但是文本的编辑和一行的编辑是完全两码事的, 如果他们使用
  过 bash, 最终也会发现 bash 的行编辑确实很方便了.
  
  所以有些人设置了烦人的 vi 模式: set -o vi , 可以使用 set +o vi 清除此设置.

  或者有人认为, 很多机器上没有 bash, 而其它 shell 用着用着就习惯了,
  但习惯的东西并不是就是好的. 如果使用较多的命令行, 无疑地, bash 能提高效率.


5.  基本命令
============

Unix 的基本命令:

  man info
  cd, alias, export, fg, bg, history
  ls, pwd, cp, mv, rm, diff, sort, cat, more, grep, find, which, 
  head, tail, chown, chmod, file, mkdir, rmdir, ln, touch, split, 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,
  ftp, telnet, ssh (sftp),


  示例:
  
  $ man man           # 查看命令 man 的手册
  $ man date          # 
  $ man localtime
  
  $ echo $PATH        # 打印变量 PATH
  $ echo $?           # 变量 $? 是上一个命令的返回状态.
  
  $ 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 -                    # 跳回上一个路径
  
  基本的文件及目录操作:
  
  $ ls                      # 查看文件或目录信息
  $ ls -l
  $ ls /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, 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 word
  
  $ head file1                   # 输出文件的前 10 行
  $ tail file1                   # 输出文件的最后 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 -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 1234
  $ 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 -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.gz
  
  $ compress file1
  $ uncompress file1.Z
  $ zcat file1.Z
  $ zmore file1.Z
  
  远程登录及文件传输
  
  $ ftp ip

  $ telnet ip

  $ ssh username@ip

  $ sftp username@ip

7.  输入输出重定向
==================

  shell 一开始会打开三个文件描述符, 用来输入, 输出, 及显示错误的.
  
  标准输入: 通常是键盘, 文件描述符为 0 
  标准输出: 通常是屏幕, 文件描述符为 1 
  标准出错: 通常与标准输出相同(也就是屏幕), 文件描述符为 2 
  
  当我们执行下面的命令时, 是直接输出到屏幕的:
  
  $ ls -la
  
  若是想输出到另一文件中, 需要重定向输出:
  
  $ ls -al > myfile
  
  >  输出转向, 会先把文件清空
     1>    标准输出
     2>    标准出错

  >> 输出转向, 追加写入
     1>>   标准输出
     2>>   标准出错

  <  输入转向, 把一文件当作输入
  |  把一程序的输出当作另一程序的输入
  
  $ cat < /bin/ls > myfile
  $ cat /etc/passwd | grep bash

  $ make -j4 > tmpfile 2>&1 &

8. 文件权限
===========

8.1 文件系统
------------

  在类 unix 系统中, 文件系统中的数据组合以目录或文件的方式存在,
  目录下可有多个子目录和文件, 最顶层的目录是 /, 称为根目录,
  就是说, 所有的目录都在根目录之下.

8.2 文件及目录权限
------------------

  在类 unix 系统中, 有多用户和组的概念, 一个用户可同时属于多个组,
  每个文件或目录的权限属于并且只属于一个用户和一个组:

  # ls -l /home/ | grep test1
  drwx------ 48 test1         dev       4096 03-28 16:16 test1
  ~~~~~~~~~~    ~~~~~         ~~~
    第一部分     第二部分     第三部分

  我们使用 ls -l 可看到, 目录 /home/test1 属于用户 test1 和组 dev.
  先暂时不用管 "48" 和 "4096" 是啥意思, 先看看一部分的内容,
  这里有 10 个字符, 第一个用于表示目录, 或文件, 或链接文件:

  d    -- 目录
  -    -- 文件
  l    -- 链接文件, 可以指向目录, 也可以指向文件

  剩下的 9 个字符分成三部分, 用于表示权限许可:

  d   rwx   ---   ---
      ~~~   ~~~   ~~~
       1     2     3

  1) 用户的权限, 在上面的例子中, 即表示 test1 用户本身的权限.
     r  表示可读, 对应数字 4, 后面用到
     w  表示可写, 对应数字 2,
     x  表示可执行, 对应数字 1
     对于目录来讲, 一定要有 x 权限才能进入的.
  2) 组权限, 在这个例子中, 组 dev 没有任何权限.
  3) 其它用户权限, 即除了 test1 本身和组 dev 的其它用户.
     在这里, 其它用户也没有这个目录的任何权限
 
  有两个命令用于更改一个目录的所属目录和所属组, 以及对应的权限:

  a. chown   --  修改所属用户和组

     chown test1.dev2  /home/test1   # 把所属组改为 dev2 啦
     但这样只能改掉目录 /home/test1, 并不能改掉子目录的组,
     如果也想改掉子目录, 那么加上 -R :
     chown -R test1.dev2  /home/test1

  b. chmod  --  修改用户及组对应的权限

     chmod 755 /home/test1   # 改为 755 :)
     755 中的每个数字对应上面的一部分,
     7 = r (4) + w (2) + x (1)
     5 = r + x

  如果想在原来的基础加上一个权限, 那要这样:

  chmod +x  tmpfile   # 加上可执行

  大家只需会 +x 和数字组合(如 755, 644, 700) 就可以了.

9. 进程管理
============

  有时需要把进程放到后台运行, 这样可以不用占用当前的终端,
  可以在后面加上 &, 如

  $ grep hehe tmpfile > tmpfile.1 & 
  [1] 22775

  shell 会输出后面的 "[1] 22775" 的字样, 意思是当前 shell 在后台有一个进程,
  如果这时再输入:

  $ sleep 60 &
  [2] 22776

  当中的 [2] 表示有两个进程在后台运行, 如果想转为前台, 可以这样:

  $ fg 1
  grep hehe tmpfile > tmpfile.1

  下面的那行提示是 fg 的输出, 表示又回到前台啦...

  这时如果又想放到后台运行的话, 可先按 ^Z , 表示暂停正在运行的命令:

  $ grep hehe tmpfile > tmpfile.1
  ^Z
  [1]+  Stopped                grep hehe tmpfile > tmpfile.1

  注意的是这是暂停, 想把它放后台运行需要输入 bg 1

  fg 和 bg 在没有参数的情况下默认是 1 .

10. shell 脚本
==============

  Shell 内建了自己的一套语言, 用于作业管理.

  $ ls && echo fail
  $ ls || echo fail

  最简单的 Shell 脚本就是一系列的命令, 如:

  $ cat t.sh
  #!/bin/sh
  echo "start..."
  rm -f tmpfile
  cp /bin/ls tmpfile

  而 Shell 也提供流程控制: 如

  $ cat t.sh
  #!/bin/sh
  if [ "TERM" = "vt100" ]; then
      echo $TERM
  fi

  if [ "TERM" = "vt100" ]; then
      echo $TERM
  elsle
      echo $TERM
  fi

  for i in `ls`; do
      echo $i
  done

  但, 通常来说, 我们不需要写复杂的 shell 脚本, 并且, 如果我们需要文本处理,
  更不应该使用 shell 脚本, 也就是说, 不应该使用 sed 和 awk, 我们应该使用 perl


转自http://blog.csdn.net/wallwind

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值