UP | HOME

bash-basic

Table of Contents

What is the shell

  • 当我们说到command line的时候,我们其实是说的shell. shell是一个从键盘接受信息 传递给操作系统的程序.Linux默认的shell是bash

Terminal Emulators

  • 如果我们使用GUI界面的话,我们还要使用terminal emulator来和shell进行联系.KDE 里面使用的是konsole, GNOME使用的是gnome-terminal

Your First keystrokes

  • 打开terminal emulator,应该是如下这个样子的
    lvtest@auto-inst:~$
    
  • $(dollar sign)代表一般用户, #(hash mark)代表超级用户.

Command History

  • 上下键可以选择上一条下一条命令,一遍最少会保存500条历史

Cursor Movement

  • 左右键,可以让光标左右移动

Try Some Simple Commands

  • date是日期命令
    lvtest@auto-inst:~$ date
    Wed Feb 26 16:13:11 CST 2014
    
  • cal是日历命令
    lvtest@auto-inst:~$ cal
       February 2014
    Su Mo Tu We Th Fr Sa
                       1
     2  3  4  5  6  7  8
     9 10 11 12 13 14 15
    16 17 18 19 20 21 22
    23 24 25 26 27 28
    
  • df可以查看当前驱动器下面的剩余空间
    lvtest@auto-inst:~$ df
    Filesystem     1K-blocks    Used Available Use% Mounted on
    /dev/sda1       40120704 1944148  36131884   6% /
    none                   4       0         4   0% /sys/fs/cgroup
    udev              496420       4    496416   1% /dev
    tmpfs             101188     296    100892   1% /run
    none                5120       0      5120   0% /run/lock
    none              505932       0    505932   0% /run/shm
    none              102400       0    102400   0% /run/user
    
  • free产科内存的剩余
    lvtest@auto-inst:~$ free
                 total       used       free     shared    buffers     cached
    Mem:       1011868     227332     784536          0      21464      78256
    -/+ buffers/cache:     127612     884256
    Swap:      1046524          0    1046524
    

Ending a Terminal Session

  • 我们使用exit来结束一个terminal session
  • 除了我们上面说的terminal emulator, Linux还会在GUI的背后运行一些terminal session.叫做virtual terminal,我们可以通过CTRL+ALT+F1~F6来调用,返回GUI 桌面使用ALT-F7

Navigation

Understanding the Filesystem Tree

  • 和windows一样,linux也是采用了树形结构的文件系统.第一个文件夹叫做root 文件夹(/)
  • 和windows不一样的是:windows为每一个分区准备了一个单独的"文件系统树", 对于Linux 来说,无论有多少设备,都只有一套"文件系统树", 额外的设备是通过"mount"的形式来放在 某个文件夹下面的

The Current Working Directory

  • 我们的shell当前无论如何都会在某个文件夹下,使用pwd来表示
    lvtest@auto-inst:~/tmp$ pwd
    /home/lvtest/tmp
    

Listing the Contents of a Directory

  • 当前文件夹下的内容使用ls
    lvtest@auto-inst:~/tmp$ ls
    a.out  printf.c  testsig.c  unpbook
    

Changing the Current Working Directory

Absolute pathnames

  • 我们使用以"/"开头的绝对文件路名来cd到相应文件夹
    lvtest@auto-inst:~/tmp$ cd /usr/bin
    lvtest@auto-inst:/usr/bin$ pwd
    /usr/bin
    

Relative Pathnames

  • 相对路径就是从pwd开始如何找到下一级,其中"."是当前文件夹".."是上层文件夹
    lvtest@auto-inst:/usr$ pwd
    /usr
    lvtest@auto-inst:/usr$ cd ./bin
    lvtest@auto-inst:/usr/bin$ pwd
    /usr/bin
    

Some helpful Shortcuts

  • 一些有用的cd快捷键
    Shortcut Result
    cd Changes the working directory to your home directory
    cd - Changes the working directory to the previous working
      directory
    cd ~username Changes the working directory to the home directory
      of theusername.
    lvtest@auto-inst:/usr/bin$ pwd
    /usr/bin
    lvtest@auto-inst:/usr/bin$ cd
    lvtest@auto-inst:~$ pwd
    /home/lvtest
    lvtest@auto-inst:~$ cd -
    /usr/bin
    lvtest@auto-inst:/usr/bin$ pwd
    /usr/bin
    lvtest@auto-inst:/usr/bin$ cd ~lvtest
    lvtest@auto-inst:~$ pwd
    /home/lvtest
    

Exploring The System

More Fun with ls

  • ls 不仅仅可以列出当前文件夹的内容,还可以列出其他文件夹的内容,甚至多个文件夹的内容
    lvtest@auto-inst:~$ ls /usr
    bin  games  include  lib  local  sbin  share  src
    lvtest@auto-inst:~$ ls ~ /usr
    /home/lvtest:
    authorized_keys  backupssh  test  tmp
    
    /usr:
    bin  games  include  lib  local  sbin  share  src
    

Options and Arguments

  • 我们的命令都是由如下三部分组成的
    command -options arguments
    
  • ls就支持-l这种"单字母"参数,而且单字母参数可以写在一块,效果叠加,还支持通过 "–"来增加long options
    lvtest@auto-inst:~$ ls -l
    total 16
    -rwx------ 1 lvtest lvtest  802 Oct 24 15:05 authorized_keys
    drwx------ 2 lvtest lvtest 4096 Oct 24 15:05 backupssh
    drwxrwxr-x 3 lvtest lvtest 4096 Oct 24 16:45 test
    drwxrwxr-x 3 lvtest lvtest 4096 Feb 21 16:33 tmp
    lvtest@auto-inst:~$ ls -lt
    total 16
    drwxrwxr-x 3 lvtest lvtest 4096 Feb 21 16:33 tmp
    drwxrwxr-x 3 lvtest lvtest 4096 Oct 24 16:45 test
    -rwx------ 1 lvtest lvtest  802 Oct 24 15:05 authorized_keys
    drwx------ 2 lvtest lvtest 4096 Oct 24 15:05 backupssh
    lvtest@auto-inst:~$ ls -lt --reverse
    total 16
    drwx------ 2 lvtest lvtest 4096 Oct 24 15:05 backupssh
    -rwx------ 1 lvtest lvtest  802 Oct 24 15:05 authorized_keys
    drwxrwxr-x 3 lvtest lvtest 4096 Oct 24 16:45 test
    drwxrwxr-x 3 lvtest lvtest 4096 Feb 21 16:33 tmp
    
  • 下面就来总结一下ls的参数
    Option Long Option Description
    -a –all List all files, even hidden files
    -d –directory if No -d dpecified, ls will list the contents
        of directory. with -d, ls will list the
        directory itself
    -F –classify This option will append an indicator character
        to the end of each listed name(for example, a
        forward slash for directory)
    -h –human-readable in long format listing(with -l), display the
        sizes in human-readable format rather than in
        bytes
    -l   Display result in long format
    -r –reverse Display the results in reverse order
    -S   Sort result by file size
    -t   Sort by modification time

A Longer Look at Long Format

  • 下面是一个long listing的例子
    lvtest@auto-inst:~/tmp$ ls -l
    total 24
    -rwxrwxr-x  1 lvtest lvtest 8522 Feb 21 16:33 a.out
    -rw-rw-r--  1 lvtest lvtest  222 Feb 21 16:33 printf.c
    -rw-rw-r--  1 lvtest lvtest 1042 Feb 19 18:09 testsig.c
    drwxrwxr-x 40 lvtest lvtest 4096 Feb 20 16:48 unpbook
    
  • 我们以最后一行来分析long listing
    Field Meaning
    drwxrwxr-x first character indicates the type fo file. "-"-> regular file
      "d"-> directory next three characters"rwx"->access rights for
      file's owner, next three characters"rwx"->access rights for
      file's group, final thress"r-x" for everyone else
    40 File's number of hard links
    lvtest The user naemfo the file's owner
    lvtest The name of the group that owns the file
    4096 Size of the file in bytes
    Feb 20 16:48 Date and time of the file's last modification
    unpbook Name of the file

Determining a File's Type with file

  • 我们可以用file命令来判断文件类型
    lvtest@auto-inst:~/tmp$ file printf.c
    printf.c: C source, ASCII text
    

Viewing File contents with less

  • 我们可以使用less来查看text类型的文件, 期间所有的操作和VI一样!, 可以按h来查 看帮助
    lvtest@auto-inst:~/tmp$ less printf.c
    WARNING: terminal is not fully functional
    printf.c  (press RETURN)
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
        int ii = 0x01020304;
        int i = 0;
        char* ptr = &ii;
        for (i = 0; i < 4; i++) {
            printf("%x\n", *ptr);
            ptr++;
        }
    
        return 0;
    }
    printf.c (END)
    

A Guided Tour

  • 我们在移动位置的时候,有很多时候要用到绝对路径,下面就是一些绝对路径的意义
    Directory Comments
    // The root directory, where everything begins
    /bin Contains binaries must be present for system to boot and run
    /boot Contains Linux Kernel, initial RAM disk image
      /boot/grub/grub.conf->used to configure the boot loader
      /boot/vmlinuz, the Linux kernel
    /dev Contains device nodes, nodes are also file
    /etc Contains system-wide configuration files
      /etc/crontab->defines when automated job will run
      /etc/fstab->a table of storage devices and their associated
      mount points
      /etc/passwd, a list of the user accounts
    /home Every user has one directory in /home
    /lib Contains shared library files used by the core system programs,
      like the DLLs in Windows
    /lost+found Unless somethign really bad has happened to your system, this
      directory will reman empty
    /media On modern Linux system, it will contain the mount pionts for
      removable media such as USB, CD-ROM, that are mounted
      automatically at insertion
    /mnt On older Linux systems, /mnt directory conatins mount points
      for removable devices that habe been mounted manually
    /opt The /opt directory is used to install "optional" software
    /proc /proc is not a real filesystem. it is a virtual filesystem
      maintained by the Linx kernel. The files are readable and will
      give you a picture of how the kernel sees your computer
    /root home directory for the root account
    /sbin This directory conains "system" binaries. These are programs
      that perform vital system tasks that are generally reserved
      for the superuser
    /tmp Intended for staorage of temporary, transient files.
    /usr This directory is likely the largest one on a Linux system. It
      contains all the programs and support files used by regular
      users
    /usr/bin containst the executable programs installed by your Linux
      distribution. It is common for this directory to hold thousands
      of programs
    /usr/lib The shared libraries for the programs in /usr/bin
    /usr/local The /usr/local tree is where programs that are not included with
      your distribution but are intended for system-wide use are
      installed. Programs compiled from source code are normally
      installed in /usr/local/bin
    /usr/sbin Contains more system administration programs
    /usr/share /usr/share contains all the shared data used by programs in
      /usr/bin. This includes things like defult configuration files,
      icons, screen backgrounds, sound files, etc
    /usr/share/oc Most packages installed on the system will include some kind of
      documentation files organized by package
    /var With the exception of /tmp and /home, the directories we showd
      here keep their content static, in other words, their contents
      are not changed. /var directory tree is where data that is
      likely to chagne is stored. Various databases, spoll files, user
      mail, for example
    /val/log /var/log contains log files, records of various sytem activity.
      The most useful one is /var/log/messages, in some system, only
      superuser can view log file

Symbolic Links

  • 在ls 的long format里面,如果第一个不是"-"或者"d", 而是"l"的话,就是symbolic links
    lrwxrwxrwx  1 root root    17 Feb 20  2013 libip4tc.so.0 -> libip4tc.so.0.0.0
    

Manipulating Files And Directories

Wildcards

  • 因为shell经常使用文件名, 通配符为shell提供了一种快速定位"一组"文件的方法.下 面是主要通配符
    Wildcard Matches
    * Any characters
    ? Any single character
    [characters] Any character that is a member of the set characters
    [!characters] Any character that is not a member of the set characters
    [\[:class:]\] Any character that is a member of the specified class
    [:alnum:] Any alphanumeric character
    [:alpha:] Any alphabetic character
    [:digit:] Any numeral
    [:lower:] Any lowercase letter
    [:upper:] Any uppercase letter
  • 下面是通配符例子
    Pattern Matches
    * All files
    g* Any file beginning with g
    b*.txt Any file beginning weith b followed by any characters and
      characters and ending with .txt
    Data?? Any file beginning with Data followed by exactly three chars
    [abc]* Any file beginning with either a, b, or c
    BACKUP.[0-9][0-9][0-9] Any file beginning weith BACKUP. followed by exactly 2 nums
    [ [:upper:] ]* Any file beginning with an uppercase letter
    [![:digit:]]* Any file not beginning with a number
    *[[:lower:]123] Any file ending with a lowercase letter or num 1, 2, 3
    lvtest@auto-inst:~/tmp/ttt/wc$ ls *
    12.txt  23.txt  ABC.txt  BACKUP.123  Datafhr  abc.txt  bca.txt  g1.txt  g2.txt
    lvtest@auto-inst:~/tmp/ttt/wc$ ls g*
    g1.txt  g2.txt
    lvtest@auto-inst:~/tmp/ttt/wc$ ls b*.txt
    bca.txt
    lvtest@auto-inst:~/tmp/ttt/wc$ ls Data???
    Datafhr
    lvtest@auto-inst:~/tmp/ttt/wc$ ls [abc]*
    abc.txt  bca.txt
    lvtest@auto-inst:~/tmp/ttt/wc$ ls BACKUP.[0-9][0-9][0-9]
    BACKUP.123
    lvtest@auto-inst:~/tmp/ttt/wc$ ls [[:upper:]]*
    ABC.txt  BACKUP.123  Datafhr
    lvtest@auto-inst:~/tmp/ttt/wc$ ls [![:digit:]]*
    ABC.txt  BACKUP.123  Datafhr  abc.txt  bca.txt  g1.txt  g2.txt
    lvtest@auto-inst:~/tmp/ttt/wc$ ls *[[:lower:]123]
    12.txt  23.txt  ABC.txt  BACKUP.123  Datafhr  abc.txt  bca.txt  g1.txt  g2.txt
    

mkdir-Create Directories

  • mkdir是建立文件夹的命令
    lvtest@auto-inst:~/tmp/ttt/mk$ ls
    lvtest@auto-inst:~/tmp/ttt/mk$ mkdir dir1 dir2 dir3
    lvtest@auto-inst:~/tmp/ttt/mk$ ls
    dir1  dir2  dir3
    

cp-Copy Files and Directories

  • cp的用法主要就是下面三种
    lvtest@auto-inst:~/tmp/ttt/mk$ ls
    dir1  dir2  dir3  f1  f2  f3  f4
    lvtest@auto-inst:~/tmp/ttt/mk$ cp f1 f5
    lvtest@auto-inst:~/tmp/ttt/mk$ ls
    dir1  dir2  dir3  f1  f2  f3  f4  f5
    lvtest@auto-inst:~/tmp/ttt/mk$ cp f1 dir1
    lvtest@auto-inst:~/tmp/ttt/mk$ find .
    .
    ./f5
    ./dir3
    ./dir2
    ./f3
    ./f2
    ./f4
    ./f1
    ./dir1
    ./dir1/f1
    lvtest@auto-inst:~/tmp/ttt/mk$ cp f2 f3 f4 f5 dir2
    lvtest@auto-inst:~/tmp/ttt/mk$ find .
    .
    ./f5
    ./dir3
    ./dir2
    ./dir2/f5
    ./dir2/f3
    ./dir2/f2
    ./dir2/f4
    ./f3
    ./f2
    ./f4
    ./f1
    ./dir1
    ./dir1/f1
    
  • cp的参数主要有
    Option Meaning
    -a, –archive Copy the files and directories with all their attributes
      It is default attributes for the user performing the copy
    -i, –interactive If this option is not specified, cp will silently
      overwrite files
    -r, –recursive Recursively copy directories and their contesnts
    -u, –update copy only files that either don't exist or are newer
      than the existing corresponding files in the destination
      directory
    -v, –verbose Display informative messages

mv-Move and Rename Files

  • mv 和copy从参数和使用方面都是一样的.要注意的是,比如, mv a b, 如果a,b在一个 文件夹下,那么mv就等同于rename了

rm-Remove Files and Directories

  • rm就是删除某个item.和前面的mv,copy使用方法一样,多了一个"-f, –force"参数,忽 略文件不存在的提示.

ln-Create Links

Hard links

  • 创建hard link的方法为 ln file link, 注意先写file再写link, hard link只能link 普通文件,不能link其他, hard link有如下缺点:
    • 不能link其他partition的文件
    • 不能link文件夹
    lvtest@auto-inst:~/tmp/ttt/hs$ ls
    f1
    lvtest@auto-inst:~/tmp/ttt/hs$ ln f1 hard-link
    lvtest@auto-inst:~/tmp/ttt/hs$ ls
    f1  hard-link
    lvtest@auto-inst:~/tmp/ttt/hs$ ls -al
    total 8
    drwxrwxr-x 2 lvtest lvtest 4096 Feb 27 18:58 .
    drwxrwxr-x 6 lvtest lvtest 4096 Feb 27 18:58 ..
    -rw-rw-r-- 2 lvtest lvtest    0 Feb 27 18:58 f1
    -rw-rw-r-- 2 lvtest lvtest    0 Feb 27 18:58 hard-link
    
  • 创建Symbolic Link的方法是ln -s item link, symbolic link不仅仅能link普通文 件, 也可以link文件夹等.
    lvtest@auto-inst:~/tmp/ttt/hs$ ls
    f1  hard-link
    lvtest@auto-inst:~/tmp/ttt/hs$ ln -s f1 soft-link
    lvtest@auto-inst:~/tmp/ttt/hs$ ls -al
    total 8
    drwxrwxr-x 2 lvtest lvtest 4096 Feb 27 19:03 .
    drwxrwxr-x 6 lvtest lvtest 4096 Feb 27 18:58 ..
    -rw-rw-r-- 2 lvtest lvtest    0 Feb 27 18:58 f1
    -rw-rw-r-- 2 lvtest lvtest    0 Feb 27 18:58 hard-link
    lrwxrwxrwx 1 lvtest lvtest    2 Feb 27 19:03 soft-link -> f1
    

Let's Build a Playground

  • hard link和symbolic link的区别在于hard link不会创建一个新的inode,而是两个文 件使用一个inode,使用ls -i可以创建这个inode
    lvtest@auto-inst:~/tmp/ttt/hs$ ls -li
    total 0
    134897 -rw-rw-r-- 2 lvtest lvtest 0 Feb 27 18:58 f1
    134897 -rw-rw-r-- 2 lvtest lvtest 0 Feb 27 18:58 hard-link
    134898 lrwxrwxrwx 1 lvtest lvtest 2 Feb 27 19:03 soft-link -> f1
    

Working With Commands

What Exactly Are Commands?

  • 一个命令其实质上可能会是下面四种中的一种:
    • An executable program: 所有的在/usr/bin下面的可执行程序都是这种, which的 结果就是/usr/bin
    • A command build into the shell itself:是shell自带的. which的结果是空, 比如cd
    • A shell function
    • An alias: 在其他命令的基础上自己简单改变的命令,比如ll, which ll也是空的

Identifying Commans

type-Display a Command's Type

  • 我们可以用type命令来判断命令的类型:
    lvtest@auto-inst:~$ type type
    type is a shell builtin
    lvtest@auto-inst:~$ type ls
    ls is aliased to `ls --color=auto'
    lvtest@auto-inst:~$ type cp
    cp is /bin/cp
    

which-Display an Executable's Location

  • 有时候我们一个可执行程序会有多个版本,which可以判断系统默认的使用哪个, which 还只能作用在executable程序,对于builtin的程序不管用
    lvtest@auto-inst:~$ which ls
    /bin/ls
    lvtest@auto-inst:~$ which cd
    

Getting a Command's Documentation

help-Get Help for Shell Builtins

  • help + buildin command的话可以查看其文档
    lvtest@auto-inst:~$ help cd
    cd: cd [-L|[-P [-e]]] [dir]
        Change the shell working directory.
    
        Change the current directory to DIR.  The default DIR is the value of the
        HOME shell variable.
    
        The variable CDPATH defines the search path for the directory containing
        DIR.  Alternative directory names in CDPATH are separated by a colon (:).
        A null directory name is the same as the current directory.  If DIR begins
        with a slash (/), then CDPATH is not used.
    
        If the directory is not found, and the shell option `cdable_vars' is set,
        the word is assumed to be  a variable name.  If that variable has a value,
        its value is used for DIR.
    
        Options:
            -L  force symbolic links to be followed
            -P  use the physical directory structure without following symbolic
            links
            -e  if the -P option is supplied, and the current working directory
            cannot be determined successfully, exit with a non-zero status
    
        The default is to follow symbolic links, as if `-L' were specified.
    
        Exit Status:
        Returns 0 if the directory is changed, and if $PWD is set successfully when
        -P is used; non-zero otherwise.
    

–help-Display Usage Information

  • buildin的可以使用help,那么如果是executable的话,help就不管用了,但是默认这种 命令会加一个–help参数(executable最开始都是c语言写的,c语言自然对于位于自己exe 后面的参数,当然好分析了)
    lvtest@auto-inst:~$ type mkdir
    mkdir is /bin/mkdir
    lvtest@auto-inst:~$ help mkdir
    bash: help: no help topics match `mkdir'.  Try `help help' or `man -k mkdir' or `info mkdir'.
    lvtest@auto-inst:~$ mkdir --help
    Usage: mkdir [OPTION]... DIRECTORY...
    Create the DIRECTORY(ies), if they do not already exist.
    
    Mandatory arguments to long options are mandatory for short options too.
      -m, --mode=MODE   set file mode (as in chmod), not a=rwx - umask
      -p, --parents     no error if existing, make parent directories as needed
      -v, --verbose     print a message for each created directory
      -Z, --context=CTX  set the SELinux security context of each created
                          directory to CTX
          --help     display this help and exit
          --version  output version information and exit
    
    Report mkdir bugs to bug-coreutils@gnu.org
    GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
    General help using GNU software: <http://www.gnu.org/gethelp/>
    Report mkdir translation bugs to <http://translationproject.org/team/>
    For complete documentation, run: info coreutils 'mkdir invocation'
    

man-Display a Program's Manual Page

  • 对于buildin的命令,前置的查看方法是help cmd,对于executable(开始都是c语言写 的)来说,前置的查看方法是man ls
  • 由于一个executable通常都是c语言写的,而这些命令都有c语言的相应函数(甚至是system call),所以我们有如下的常用默认显示类别
    Section Contents
    1 User commands
    2 Programming interfaces for kernel system calls
    3 Programming interfaces to the C library
    4 Special files such as device nodes and drivers
    5 File formats
    6 Games and amusements such as screensavers
    7 Miscellaneous
    8 System administration commands
  • 类别的使用方法是把类别序号放在man和cmd之间
    lvtest@auto-inst:~$ man 5 passwd
    PASSWD(5)                File Formats and Conversions                PASSWD(5)
    

apropos-Display Appropriate Commands

  • 可以看成是bash的google
    lvtest@auto-inst:~$ apropos mkdir
    mkdir (1)            - make directories
    mkdir (2)            - create a directory
    mkdirat (2)          - create a directory relative to a directory file descri...
    

whatis-Display a Very Brief Description of a Command

  • whatis 就是bash的百度百科
    lvtest@auto-inst:~$ whatis ls
    ls (1)               - list directory contents
    

Creating Your Own Commands with alias

  • 我们可以使用alias来重新组合一个命令
    lvtest@auto-inst:~$ alias foo='cd /usr; ls; cd -'
    lvtest@auto-inst:~$ which foo
    lvtest@auto-inst:~$ type foo
    foo is aliased to `cd /usr; ls; cd -'
    lvtest@auto-inst:~$ foo
    bin  games  include  lib  local  sbin  share  src
    /home/lvtest
    
  • 使用unalias来去掉这个命令的alias
    lvtest@auto-inst:~$ unalias foo
    lvtest@auto-inst:~$ type foo
    bash: type: foo: not found
    
  • 使用alias不加参数的话,会列举系统上面所有的alias
    lvtest@auto-inst:~$ alias
    alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
    alias egrep='egrep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias grep='grep --color=auto'
    alias l='ls -CF'
    alias la='ls -A'
    alias ll='ls -alF'
    alias ls='ls --color=auto'
    
  • alias命令只有在当前shell的生命期内有用,一旦关掉当前的terminal,这次alias的就 消失了.

Redirection

Standard Input, Output, and Error

  • bash程序都会和standard input,output,error相关联的,比如ls就是把结构发送到 standard output和standard error的.

Redirecting Standard Output

  • 我们是通过>将standard output转移到>指向的"文件"(从头开始,会覆盖以前的内容)
    bash-3.2$ ls /usr/bin/ > ls-output.txt
    bash-3.2$ ls -l ls-output.txt
    -rw-r--r--  1 hfeng  staff  8911 Mar  4 20:43 ls-output.txt
    bash-3.2$ ls /usr/bin/ > ls-output.txt
    bash-3.2$ ls -l ls-output.txt
    -rw-r--r--  1 hfeng  staff  8911 Mar  4 20:43 ls-output.txt
    
  • 我们是通过>>将standard output叠加转移到>指向的"文件"(从尾开始,会保留以前的内容)
    bash-3.2$ ls /usr/bin/ >> ls-output.txt
    bash-3.2$ ls /usr/bin/ >> ls-output.txt
    bash-3.2$ ls /usr/bin/ >> ls-output.txt
    bash-3.2$ ls -l ls-output.txt
    -rw-r--r--  1 hfeng  staff  26733 Mar  4 20:44 ls-output.txt
    

Redirecting Standard Error

  • 如果是redirect standard Error就稍微有点拐弯了,要借助file descriptor的概念, 一个程序产生的输出会输出到三个"文件"上面,他们也默认拥有前三个file descriptor: 0,1,2分别代表:stin, stdout, sterr,所以把sterr导入到某个文件的方法如下(注意 2和>是在一块的):
    bash-3.2$ ls -l /bin/usr 2> ls-error.txt
    bash-3.2$ cat ls-error.txt
    ls: /bin/usr: No such file or directory
    

Redirecting Standard Output and Standard Error to One File

  • 有如下两种方法:
    • 传统的方法,要转两次,利用了stdout的file descriptor为1
      bash-3.2$ ls -l /bin/usr > ls-output.txt 2>&1
      bash-3.2$ cat ls-output.txt
      ls: /bin/usr: No such file or directory
      
    • 新版本bash支持如下方法(更简介)
      bash-3.2$ ls -l /bin/usr &> ls-output.txt
      bash-3.2$ cat ls-output.txt
      ls: /bin/usr: No such file or directory
      

Disposing of Unwanted Output

  • 如果我们不想要某些输出,我们可以redirect它们到一个特殊的文件
    bash-3.2$ ls -l /bin/usr 2> /dev/null
    

Redirecting Standard Input

  • 我们用">"把stdout转移到一个文件,其实我们还可以使用"<"把文件内容作为standard input,如下
    bash-3.2$ cat > lazy_dog.txt
    The quick brown fox jumped over the lazy dog.
    bash-3.2$ cat lazy_dog.txt
    The quick brown fox jumped over the lazy dog.
    bash-3.2$ cat < lazy_dog.txt
    The quick brown fox jumped over the lazy dog.
    
  • 我们可以看到这里使用"<"和不使用"<",是没有什么区别的.但是也说明了<的作用.

Pipelines

  • 管道是bash的重要概念,我们可以通过"|"把一个程序的stout redirect到另一个 程序的stdin
    bash-3.2$ ls -l /usr/bin | less
    

Filters

  • 我们还可以在管道中间进行一些filter操作,比如sort一下
    bash-3.2$ ls -l /usr/bin | more | less
    

uniq-Report or Omit Repeated Lines

  • uniq是和sort配合最多的一个程序,它把重复的行只显示一次, 而加了-d参数以后,就 是只显示那些重复的行
    bash-3.2$ cat test.txt
    a
    n
    c
    n
    c
    n
    1
    2
    3
    4
    bash-3.2$ cat test.txt | sort | uniq
    1
    2
    3
    4
    a
    c
    n
    bash-3.2$ cat test.txt | sort | uniq -d
    c
    n
    

wc-Print Line, Word and Byte Counts

  • wc会显示文件的1行数2word数3byte数
    bash-3.2$ wc test.txt
          10      10      20 test.txt
    
  • 我们可以用前面学过的几个参数来统计我们总共有多个个executable程序在/usr和 /usr/bin下面
    bash-3.2$ ls /bin /usr/bin | sort | uniq | wc -l
        1078
    

grep-Print Lines Matching a Pattern

  • grep是一个强大的命令,其主要就是"KMP"查找字符串,其使用格式是(注意如果没有 files的话,那么就是grep stin了)
    grep pattern [file...]
    
  • grep的一个简单应用(-i ignore -v反向输出,等复杂的以后再研究)
    bash-3.2$ ls /usr/bin | sort | uniq | grep zip
    bunzip2
    bzip2
    bzip2recover
    funzip
    gunzip
    gzip
    unzip
    unzipsfx
    zip
    zipcloak
    zipdetails
    zipdetails5.16
    zipgrep
    zipinfo
    zipnote
    zipsplit
    

head/tail-Print First/Last Part of Files

  • head 可以看文件的前n(n可以指定默认是10)行, tail反之
    bash-3.2$ head -n 5 ls-output.txt
    2to3
    2to3-
    2to3-2.7
    2to32.6
    BuildStrings
    bash-3.2$ tail -n 5 ls-output.txt
    zipsplit
    zless
    zmore
    znew
    zprint
    
  • tail更重要的一个功能是在-f之后看log
    bash-3.2$ tail -f /var/log/appstore.log
            "os_updates_to_install_on_restart" = "";
            result = pass;
            "user_initiated" = no;
            "will_restart" = no;
        }
    Mar  4 20:29:34 hair.lan storeagent[263]: SoftwareMap: Software map rebuild took 0.0856 seconds for 0 records and produced: {
        }
    Mar  4 20:29:34 hair.lan storeagent[263]: AutoUpdateOperation: Released BackgroundTask power assertion (returned 0)
    ......
    

tee-Read from Stdin and Output to Stdout and Files

  • tee其实是提供了一种"T"型的管道,就是结果不仅仅是传递给tee后面指定的文件,而且 同时传递给了stdout(这样可以让管道继续叠加下去)
    bash-3.2$ ls /usr/bin | grep zip | tee out-grep.txt | grep un
    bunzip2
    funzip
    gunzip
    unzip
    unzipsfx
    bash-3.2$ cat out-grep.txt
    bunzip2
    bzip2
    bzip2recover
    funzip
    gunzip
    gzip
    unzip
    unzipsfx
    zip
    zipcloak
    zipdetails
    zipdetails5.16
    zipgrep
    zipinfo
    zipnote
    zipsplit
    

Seeing the world as the shell sees it

Expansion

  • 我们看到的bash执行,从宏观上可以分成两个部分,第一部分bash先做一些预处理,然后 第二部分才开始正式的执行,比如下面的echo *, *就是第一部分进行了预处理,处理 成了"match any chars in a filename",所以echo *就输出了当前文件夹下的name
    bash-3.2$ echo this is a test
    this is a test
    bash-3.2$ echo *
    Desktop Documents Downloads Library Movies Music Pictures Public orgblog test tmp
    

Pathname Epansion

  • wildcard能自动转换成"文件夹下"的文件的功能叫做pathname expansion.下面就是几 个转换的例子
    bash-3.2$ ls
    Desktop         Downloads       Movies          Pictures        orgblog         tmp
    Documents       Library         Music           Public          test            百度云同步盘
    bash-3.2$ echo D*
    Desktop Documents Downloads
    bash-3.2$ echo *s
    Documents Downloads Movies Pictures
    bash-3.2$ echo [[:upper:]]*
    Desktop Documents Downloads Library Movies Music Pictures Public
    
  • pathname epansion不会扩展出隐藏文件的,需要加个".", 也就是"echo .*"

Tilde Expansion

  • ~代表当前的用户home directory
    bash-3.2$ echo ~
    /Users/hfeng
    bash-3.2$ echo ~root
    /var/root
    

Arithmetic Expansion

  • 我们还可以使用bash计算算术表达式,格式是$((expression)), 两个括号
    bash-3.2$ echo $((2+2))
    4
    bash-3.2$ echo $(($((5**2)) * 3))
    75
    

Brace Expansion

  • brace的扩展可以说是最不直观的,因为它会有Permutation的作用在里面,列表式的看 起来还很简单
    bash-3.2$ echo Front-{A,B,C}-Back
    Front-A-Back Front-B-Back Front-C-Back
    
  • 一旦加入了..就麻烦起来了(注意是两点,而且必须没有空格)
    bash-3.2$ echo Number_{1..5}
    Number_1 Number_2 Number_3 Number_4 Number_5
    bash-3.2$ echo {Z..A}
    Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
    
  • 复杂的扩展性通常也意味着最后会产生非常大的作用,比如为2009到2011每个月建一个folder
    bash-3.2$ mkdir {2009..2011}-0{1..9} {2009..2011}-{10..12}
    bash-3.2$ ls
    2009-01 2009-03 2009-05 2009-07 2009-09 2009-11 2010-01 2010-03 2010-05 2010-07 2010-09 2010-11 2011-01 2011-03 2011-05 2011-07 2011-09 2011-11
    2009-02 2009-04 2009-06 2009-08 2009-10 2009-12 2010-02 2010-04 2010-06 2010-08 2010-10 2010-12 2011-02 2011-04 2011-06 2011-08 2011-10 2011-12
    

Parameter Expanison

  • 我们可以用$来表示bash自己的参数(可以被我们知道的参数可以用printenv来全部显示)
    bash-3.2$ echo $USER
    hfeng
    bash-3.2$ printenv
    SHELL=/bin/bash
    TERM=dumb
    TMPDIR=/var/folders/2d/z9f32m_55_71lttsknj0b3980000gn/T/
    Apple_PubSub_Socket_Render=/tmp/launch-ymkMDD/Render
    LC_ALL=en_US.UTF-8
    USER=hfeng
    EMACS=t
    RBENV_ROOT=/usr/local/var/rbenv
    SSH_AUTH_SOCK=/tmp/launch-X7FGUA/Listeners
    TERMCAP=
    __CF_USER_TEXT_ENCODING=0x1F5:25:52
    PAGER=cat
    COLUMNS=177
    PATH=/usr/local/var/rbenv/shims:/usr/local/bin:/bin:/sbin:/usr:/usr/bin:/usr/sbin:/usr/bin:/bin:/usr/sbin:/sbin
    __CHECKFIX1436934=1
    PWD=/Users/hfeng/Pics
    LANG=en_US.UTF-8
    SHLVL=1
    HOME=/Users/hfeng
    LOGNAME=hfeng
    DISPLAY=hair.lan
    INSIDE_EMACS=24.3.1,comint
    SECURITYSESSIONID=186a5
    _=/usr/bin/printenv
    OLDPWD=/Users/hfeng
    

Command Substitution

  • $(), 一个括号的情况是把一个bash命令的结果expand出来
    bash-3.2$ ls -l $(which cp)
    -rwxr-xr-x  1 root  wheel  24848 Feb  7 21:09 /bin/cp
    bash-3.2$ file $(ls /usr/bin/* | grep zip)
    /usr/bin/bunzip2:        Mach-O 64-bit executable x86_64
    /usr/bin/bzip2:          Mach-O 64-bit executable x86_64
    /usr/bin/bzip2recover:   Mach-O 64-bit executable x86_64
    /usr/bin/funzip:         Mach-O 64-bit executable x86_64
    /usr/bin/gunzip:         Mach-O 64-bit executable x86_64
    /usr/bin/gzip:           Mach-O 64-bit executable x86_64
    /usr/bin/unzip:          Mach-O 64-bit executable x86_64
    /usr/bin/unzipsfx:       Mach-O 64-bit executable x86_64
    /usr/bin/zip:            Mach-O 64-bit executable x86_64
    /usr/bin/zipcloak:       Mach-O 64-bit executable x86_64
    /usr/bin/zipdetails:     a /usr/bin/perl script text executable
    /usr/bin/zipdetails5.16: a /usr/bin/perl5.16 script text executable
    /usr/bin/zipgrep:        POSIX shell script text executable
    /usr/bin/zipinfo:        Mach-O 64-bit executable x86_64
    /usr/bin/zipnote:        Mach-O 64-bit executable x86_64
    /usr/bin/zipsplit:       Mach-O 64-bit executable x86_64
    
  • 原来的bash是使用``(不是'')来代替$()的.
    bash-3.2$ ls -l `which cp`
    -rwxr-xr-x  1 root  wheel  24848 Feb  7 21:09 /bin/cp
    

Quoting

  • quoting是为了解决由于shell要依靠某些字符(比如$)做转义,导致不需要转义的时候, 就抓瞎的情况, 下面第一个例子多余的space被去掉了,第二个例子$1因为没有定义,被 认为了是无定义的变量,就成了空
    bash-3.2$ echo this a     test
    this a test
    bash-3.2$ echo The total is $100.00
    The total is 00.00
    

Single Quotes

  • 单引号的作用就是去除上面提到的所有的expanison,所有转义字符都不再起作用
    bash-3.2$ echo 'text ~/*.txt {a, b} $(echo foo) $((2+2)) $USER'
    text ~/*.txt {a, b} $(echo foo) $((2+2)) $USER
    

Double Quotes

  • 双引号做的就没那么绝:留下了三个活口:
    1. $(dollar sign) : 依赖dollor的三个parameter expansion,command substitution, arithmetic都没问题
      bash-3.2$ echo "$USER"
      hfeng
      bash-3.2$ ls -l "$(which cp)"
      -rwxr-xr-x  1 root  wheel  24848 Feb  7 21:09 /bin/cp
      bash-3.2$ echo "$((2+2))"
      4
      
    2. \(backslash): 双引号不加入的话,backslash是不管用的,加了双引号,再echo加 -e就能起到作用了
      bash-3.2$ echo -e "hello\nworld"
      hello
      world
      
    3. `(back tick): 这个是old-style的$()等价体,$()被特赦了,它也一样
      bash-3.2$ echo "`id -u`"
      501
      
  • 由于双引号的加入,我们也可以查看带空格的文件了(虽然带空格的文件不推荐在linux 上面使用),当然,单引号因为去掉了所有的"特权",也可以对付空格
    bash-3.2$ ls -l hello world.txt
    ls: hello: No such file or directory
    ls: world.txt: No such file or directory
    bash-3.2$ ls -l "hello world.txt"
    -rw-r--r--  1 hfeng  staff  3 Mar  5 22:07 hello world.txt
    bash-3.2$ ls -l 'hello world.txt'
    -rw-r--r--  1 hfeng  staff  3 Mar  5 22:07 hello world.txt
    
  • 多个空格被丢弃的问题也得到了解决
    bash-3.2$ echo "this is a      test"
    this is a      test
    
  • 事实上,空格的问题值得一说,前面的多个空格被解析成一个空格,是因为bash对待空 格, 换行符和tab的态度是只把他们看做是delimiter(分隔符). 这个和高级语言 比如c,java里面对待空格的态度一样.有些情况下我们希望保留格式,比如如下的cal 那么双引号就非常重要:
    • 这个时候单引号就不行了,因为其把$抛弃了,
    • 不加引号不行,因为他们把换行符tab,多余空格都抛弃了
    bash-3.2$ echo $(cal)
    March 2014 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    bash-3.2$ echo "$(cal)"
    March 2014
    Su Mo Tu We Th Fr Sa
    1
    2  3  4  5  6  7  8
    9 10 11 12 13 14 15
    16 17 18 19 20 21 22
    23 24 25 26 27 28 29
    30 31
    bash-3.2$ echo '$(cal)'
    $(cal)
    

Escaping Characters

  • "\"是个神奇的字符,可以把特殊字符转移,比如$,!,&,空格都不能出现在bash 文件名里面 那么我们就可以使用\来转移
    bash-3.2$ echo "The balance for user $USER is : \$5.00"
    The balance for user hfeng is : $5.00
    bash-3.2$ touch good\$work\!
    bash-3.2$ ls -l good*
    -rw-r--r--  1 hfeng  staff  0 Mar  5 23:16 good$work!
    

Advanced keyboard tricks

Command Line Editing

  • bash使用了一个叫做Readline的方法来实现command line的编辑

Cursor Movement

  • 下表就是光标移动的快捷键,其实都是Emacs的快捷键
    CTRL-A Move ahead
    CTRL-E Move to the end
    CTRL-F Move forward one character
    CTRL-B Move backward one character
    ALT-F Move forward one word
    ALT-B Move backward one word
    CTRL-L Clear the screen

Cutting and Pasting(Killing and Yanking) Text

  • 还是大体和Emacs相似,除了使用Ctrl+T来exchange

Completion

  • 使用TAB可以进行补全

Using History

Searching History

  • 使用history加grep可以配合找到原来的命令,!+序号可以重复执行
    bash-3.2$  history | grep "grep zip"
      448  ls /usr/bin | sort | uniq | grep zip
      451  ls /usr/bin | sort | uniq | grep zip | wc -l
      452  ls /usr/bin | sort | uniq | grep zip
      470  ls /usr/bin | grep zip | tee out-grep.txt | grep un
      504  ls /usr/bin | sort | uniq | grep zip
      505   history | grep grep zip
      506   history | grep "grep zip"
    bash-3.2$ !448
    ls /usr/bin | sort | uniq | grep zip
    bunzip2
    bzip2
    bzip2recover
    funzip
    gunzip
    gzip
    unzip
    unzipsfx
    zip
    zipcloak
    zipdetails
    zipdetails5.16
    zipgrep
    zipinfo
    zipnote
    zipsplit
    
  • CTRL + L可以关键字查找history命令

Permissions

Owners, Group Members, and Everybody Else

  • id 命令会列出当前用户(也可以指定)所属的user id, groupid,并且会指出其属于哪 些group
    [hfeng@harrifeng ~]$ id
    uid=1000(hfeng) gid=100(users) groups=100(users),10(wheel)
    

Reading, Writing, and Executing

  • 下图精确的表达了在ls -l出来的前10个字符是干嘛的. r就是可读, w是可写,x是可执 行

    permission.png

  • 其中的Type permission有如下几种:
    Attribute File Type
    - A regular file
    d A directory
    l A symbolic link
    c A character special file
    b A block file.

chmod-Change File Mod

  • chmod命令就是为了更改rwx属性的,其使用下面列表的三种方式来表示想要改成的mode
    Octal Binary File Mode
    0 000 ---
    1 001 –x
    2 010 -w-
    3 011 -wx
    4 100 r--
    5 101 r-x
    6 110 rw-
    7 111 rwx
  • 要把上面的mode施加于不同的作用域,是下面图标要表示的
    Symbol Meaning
    u Short for user but means the file or directory owner
    g Group owner
    o Short for others but means world
    a Short for all; the combination of u, g, and o
  • 下面是mode和作用域结合起来的例子
    Notation Meaning
    u+x Add execute permission for the owner
    u-x Remve execute permission from the owner
    +x Add execute permission for the owner, group, and world (== a+x)
    o-rw Remove the read and write permissions from anyone besides the owner and group owner
    go=rw Set the group and anyone besides the owner to have read and write permission. If
      either the group owner or world previously had execute permissions, remove them
    u+x, go=rx Add execute permission for the owner and set the permissions for the group and
      others to read and execute.
  • 创建一个新文件的时候,其格式为如下rw-rw-rw-, 但是你可以通过umask来指定

    umask.png

  • umask的例子
    bash-3.2$ umask 000
    bash-3.2$ rm foo.txt
    bash-3.2$ > foo.txt
    bash-3.2$ ls -l foo.txt
    -rw-rw-rw-  1 hfeng  staff  0 Mar  8 12:29 foo.txt
    bash-3.2$ rm foo.txt ; umask 0022
    

Changing Identities

su-Run a Shell with Substitute User and Group IDs

  • su命令我们很熟悉了,但是其实它的原型并不是只是对root有效(只是默认不指定用户 就是root用户)其使用方法如下
    su [-[l]] [user]
    
  • 如果我们使用了-l(甚至是-),那么shell就是一个login shell, 也就意味着:
    • [user]标记的environment 导入
    • working directory转化到/home/[user]

sudo-Execute a Command as Another User

  • sudo就是给某些用户某些root权限,好处是权限可控,而且用户不需要知道root密码

chown-Change File Owner and Group

  • chown使用方法如下,可以更改文件的owner和group
    chown [owner][:[group]] file ...
    
  • 其owner group的组合例子如下
    Argument Result
    bob Changes the ownership of the file from its current owner to user bob
    bob:users Changes the ownership of the file from it current owner to user bob
      and changes the file group owner to group users
    :admins Changes the group owner to the group admins. The file owner is unchanged
    bob: Changes the file owner from the current owner to suer bob and changes the
      group owner to the login group of user bob

chgrp-Change Group Ownership

  • 老版本的Unix chown不能改group,现在chgrp的存在已经没什么必要了

Processes

How a Proess Works

Viewing Processes with ps

  • 最常见的查看进程的命令是ps
    bash-3.2$ ps
      PID TTY           TIME CMD
     3970 ttys000    0:00.01 /bin/bash --noediting -i
     3929 ttys006    0:00.01 -bash
    
  • 加上x后,会显示的更多(注意没有-), 因为所有x windows的进程也会显示
    bash-3.2$ ps x
      PID   TT  STAT      TIME COMMAND
      145   ??  Ss     0:02.79 /sbin/launchd
      149   ??  S      0:02.93 /usr/libexec/UserEventAgent (Aqua)
      150   ??  S      2:09.42 /usr/sbin/distnoted agent
      152   ??  S      0:02.30 /usr/sbin/cfprefsd agent
      157   ??  S      0:08.60 /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock
    
  • 再加上au,会显示process更多的信息
    bash-3.2$ ps aux
    USER              PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND
    hfeng            3848  26.6  3.5  1175648 148560   ??  S    12:57PM   3:05.56 /Applications/Google Chrome.app/Contents/Versions/33.0.1750.117/Google Chrome Helper.app/Contents/M
    hfeng             226   9.7  2.2   902680  91836   ??  S     8:11PM  15:07.57 /Applications/Google Chrome.app/Contents/Versions/33.0.1750.117/Google Chrome Helper.app/Contents/M
    _windowserver     105   8.2  1.3  3066572  54600   ??  Ss    8:11PM  14:18.16 /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resource
    hfeng             205   7.2  3.8  1487564 158904   ??  S     8:11PM  25:21.50 /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    

Viewing Processes Dynamially with top

  • 使用top可以动态的查看进程的信息

Controlling Processes

Putting a Proces in the Background

  • 把一个进程放到后台运行的方法是在executable后面加个&
    bash-3.2$ ./a.out &
    [1] 4130
    
  • 我们可以通过jobs来看到"当前"bash启动的进程(ps是可以看到机器上的所有进程)
    bash-3.2$ jobs
    [1]+  Running                 ./a.out &
    

Returning a Proces to the Foreground

  • 当前terminal开启的进程都是可以用jobs来观看,如果当前terminal开启job的超过 三个的话,除了[id]以外,还有"+","-". 这里的"+"是fg的首选(在不使用参数的情况下)
    bash-3.2$ jobs
    [1]   Running                 ./a.out &
    [2]   Running                 ./a.out &
    [3]-  Running                 ./a.out &
    [4]+  Running                 ./a.out &
    bash-3.2$ fg %4 # equals==> fg %+ equals==> fg
    ./a.out
    

Stopping (Pausing) a Process

  • 无论是前台运行也好,后台运行也好,都是运行.我们有时候还要把程序停止(让他不要 再使用cpu), 方法是:当程序在前台运行的适合按Ctrl+z
    hAir:tmp hfeng$ ./a.out
    ^Z
    [1]+  Stopped                 ./a.out
    hAir:tmp hfeng$ jobs
    [1]+  Stopped                 ./a.out
    hAir:tmp hfeng$ bg %1
    [1]+ ./a.out &
    hAir:tmp hfeng$ jobs
    [1]+  Running                 ./a.out &
    
  • 我们这里使用了bg把程序从dead状态转到==>running运行状态(并且在后台运行). 而fg是吧程序从dead状态(或者后台运行状态)转到==>running运行状态(并且是在 前台运行)

Signals

Sending Signals to Process with kill

  • 使用kill可以杀掉某个id的process,使用方法如下
    kill [-signal] PID...
    
  • 具体使用-signal的时候,可以使用'数字', '命令',还有'SIG命令'.三种方式
    Air:tmp hfeng$ ./a.out &
    [1] 4214
    hAir:tmp hfeng$ kill -1 4214
    hAir:tmp hfeng$ jobs
    [1]+  Hangup: 1               ./a.out
    hAir:tmp hfeng$ ./a.out &
    [1] 4215
    hAir:tmp hfeng$ jobs
    [1]+  Running                 ./a.out &
    hAir:tmp hfeng$ kill -INT 4215
    hAir:tmp hfeng$ jobs
    [1]+  Interrupt: 2            ./a.out
    hAir:tmp hfeng$ ./a.out &
    [1] 4219
    hAir:tmp hfeng$ jobs
    [1]+  Running                 ./a.out &
    hAir:tmp hfeng$ kill -SIGINT 4219
    hAir:tmp hfeng$ jobs
    [1]+  Interrupt: 2            ./a.out
    

Sending Signals to Multiple Processes with killall

  • 还可以使用威力巨大的killall 来杀掉一批进程
    killall [-u user] [-signal] name...
    

More Process-Related Commands

  • 还有许多监视process的命令,如下
    Command Description
    pstree Outputs a process list arranged tree-like pattern
    vmstat Outputs a snapshot os system resource usage
    xload A graphical program that draws a graph showing system load over time
    tload Similar to the xload program, but draws the graph in the terminal

The Environment

What Is Stored in the Environments?

  • shell 存储两类的信息:
    • environment variables(环境变量)
    • shell variables(shell变量)

Examining the Environment

  • printenv可以打印全部或者指定的环境变量
    bash-3.2$ printenv PATH
    /usr/local/var/rbenv/shims:/usr/local/bin:/bin:/sbin:/usr:/usr/bin:/usr/sbin:/usr/bin:/bin:/usr/sbin:/sbin
    bash-3.2$ printenv USER
    hfeng
    bash-3.2$ printenv
    SHELL=/bin/bash
    TERM=dumb
    TMPDIR=/var/folders/2d/z9f32m_55_71lttsknj0b3980000gn/T/
    Apple_PubSub_Socket_Render=/tmp/launch-cyv39a/Render
    LC_ALL=en_US.UTF-8
    USER=hfeng
    EMACS=t
    RBENV_ROOT=/usr/local/var/rbenv
    SSH_AUTH_SOCK=/tmp/launch-6ChvRY/Listeners
    TERMCAP=
    __CF_USER_TEXT_ENCODING=0x1F5:25:52
    PAGER=cat
    COLUMNS=167
    PATH=/usr/local/var/rbenv/shims:/usr/local/bin:/bin:/sbin:/usr:/usr/bin:/usr/sbin:/usr/bin:/bin:/usr/sbin:/sbin
    __CHECKFIX1436934=1
    PWD=/Users/hfeng/orgblog/org/notes/bash
    LANG=en_US.UTF-8
    SHLVL=1
    HOME=/Users/hfeng
    LOGNAME=hfeng
    DISPLAY=hAir.local
    INSIDE_EMACS=24.3.1,comint
    SECURITYSESSIONID=186a4
    _=/usr/bin/printenv
    
  • set可以打印1环境变量,2shell变量,3shell function
    bash-3.2$ set
    Apple_PubSub_Socket_Render=/tmp/launch-cyv39a/Render
    BASH=/bin/bash
    BASH_ARGC=()
    BASH_ARGV=()
    BASH_LINENO=()
    BASH_SOURCE=()
    BASH_VERSINFO=([0]="3" [1]="2" [2]="51" [3]="1" [4]="release" [5]="x86_64-apple-darwin13")
    BASH_VERSION='3.2.51(1)-release'
    COLUMNS=167
    DIRSTACK=()
    DISPLAY=hAir.local
    EMACS=t
    EUID=501
    GROUPS=()
    HISTFILE=/Users/hfeng/.bash_history
    HISTFILESIZE=500
    HISTSIZE=500
    HOME=/Users/hfeng
    HOSTNAME=hAir.local
    HOSTTYPE=x86_64
    IFS=$' \t\n'
    INSIDE_EMACS=24.3.1,comint
    LANG=en_US.UTF-8
    LC_ALL=en_US.UTF-8
    LOGNAME=hfeng
    MACHTYPE=x86_64-apple-darwin13
    MAILCHECK=60
    OPTERR=1
    OPTIND=1
    OSTYPE=darwin13
    PAGER=cat
    PATH=/usr/local/var/rbenv/shims:/usr/local/bin:/bin:/sbin:/usr:/usr/bin:/usr/sbin:/usr/bin:/bin:/usr/sbin:/sbin
    PIPESTATUS=([0]="0")
    PPID=12271
    PS1='\s-\v\$ '
    PS2='> '
    PS4='+ '
    PWD=/Users/hfeng/orgblog/org/notes/bash
    RBENV_ROOT=/usr/local/var/rbenv
    SECURITYSESSIONID=186a4
    SHELL=/bin/bash
    SHELLOPTS=braceexpand:hashall:histexpand:history:interactive-comments:monitor
    SHLVL=1
    SSH_AUTH_SOCK=/tmp/launch-6ChvRY/Listeners
    TERM=dumb
    TERMCAP=
    TMPDIR=/var/folders/2d/z9f32m_55_71lttsknj0b3980000gn/T/
    UID=501
    USER=hfeng
    _=set
    __CF_USER_TEXT_ENCODING=0x1F5:25:52
    __CHECKFIX1436934=1
    _rbenv ()
    {
        COMPREPLY=();
        local word="${COMP_WORDS[COMP_CWORD]}";
        if [ "$COMP_CWORD" -eq 1 ]; then
            COMPREPLY=($(compgen -W "$(rbenv commands)" -- "$word"));
        else
            local words=("${COMP_WORDS[@]}");
            unset words[0];
            unset words[$COMP_CWORD];
            local completions=$(rbenv completions "${words[@]}");
            COMPREPLY=($(compgen -W "$completions" -- "$word"));
        fi
    }
    rbenv ()
    {
        typeset command;
        command="$1";
        if [ "$#" -gt 0 ]; then
            shift;
        fi;
        case "$command" in
            rehash | shell)
                eval `rbenv "sh-$command" "$@"`
            ;;
            *)
                command rbenv "$command" "$@"
            ;;
        esac
    }
    
  • echo当然也可以显示环境变量了
    bash-3.2$ echo $HOME
    /Users/hfeng
    
  • alias只有通过alias才能显示出来
    hfeng@harrifeng ~]$ alias
    alias ls='ls --color=auto'
    

How Is the Environment Established?

Login and Non-login Shells

  • 存在两种shell:
    1. login shell: 我们登录的时候弹出输入姓名密码就是login shell. "su -l username" 也是一种login shell
    2. non-login shell: 我们在GUI系统里面开启virtual console的时候就是non-login shell
  • login shell会在启动之前读取下面的starup files
    File Contents
    /etc/profile A global configuration script that applies to all users
    ~/.bash_profile A user's personal starup file. Can be used to extend or
      override settings in the global configuration script
    ~/.bash_login If ~/.bash_profile is not found, bash attempst to read
      this script
    ~/.profile If neither ~/.bash_profile nor ~/.bash_login is found,
      bash attempts to read this file. default to Ubuntu
  • non-login shell在启动的时候会读取如下文件
    File Contents
    /etc/bash.bashrc A global configuration script that applies to all users
    ~/.bashrc A user's personal startup file. Can be used to extend
      or override settings in the global config script
  • 除了这些文件non-login shell还会继承parent的environment

What's in a Starup File?

  • 我们来看一个CentOS里面的.bash_profile为如下
     1: # .bash_profile
     2: 
     3: # Get the aliases and functions
     4: if [ -f ~/.bashrc]; then
     5:     . ~/.bashrc
     6: if
     7: 
     8: # User specific environment and startup programs
     9: PATH=$PATH:$HOME/bin
    10: export PATH
    
  • line:3-6行的意思是如果某个用户home文件夹下面有.bashrc,那么.bash_profile就 会去读取.bashrc. 所以我们通常说的.bashrc会在1.登录2.打开新的terminal的时候 去执行.其中2.是天生执行的.而1.登录是通过上面的.bash_profile读取.bashrc来实 现的.
  • lien:8-10行的意思是给PATH环境变量增加一个文件夹(也就是系统会去寻找executable 的地方).~/bin 通常是自己编写的binary

Modifying the Environment

Which Files Should We Modify?

  • 一般来说我们.bash_profile里面会做如下操作
    • 增加PATH的文件夹
    • 增加环境变量
  • 其他的任何改动(除了.bash_profile提到的两项)都是完成在.bashrc里面

Activating Our Changes

  • 我们使用source来读取某个配置文件
    bash-3.2$ source .bashrc
    

A Gentle Introduction to VI

  • 对VI非常熟悉,跳过这一章.

Customizing The Prompt

Anatomy of a Prompt

  • 默认情况下是如下的
    lvtest@auto-inst:~$
    
  • prompt其实是环境变量PS1决定的
    lvtest@auto-inst:~$ echo $PS1
    ${debian_chroot:+($debian_chroot)}\u@\h:\w\$
    
  • PS可以使用如下的变量
    Sequence Value Displayed
    \a ASCII bell
    \d Current date in day
    \h Hostname of the local machine minus the trailing domain
    \H Full hostname
    \j Number of jobs running in the current shell session
    \l Name of the current terminal device
    \n A newline character
    \r A carriage return
    \s Name of the shell program
    \t Current time in 24-hour
    \T Current time in 12-hour format
    \@ Current time in 12-hour, AM/PM
    \A Current in 24-hour
    \u Username of the current user
    \v Version number of the shell
    \V Version and release numbers of the shell
    \w Name of the current working directory
    \W Last part of the current working directory name
    \! History number of the current command
    \# Number of commands entered during this shell session
    \$ This display a "$" if you have superuser privilege
    \[ This signals the start of a series of chars
    \] This signals the end of a non-printing char sequence

Trying Some Alternative Prompt Designs

  • 我们直接就可以定义PS1,然后回车一下就能看到改变了
    lvtest@auto-inst:~$ PS1="<\u@h \W>\$"
    <lvtest@h ~>$pwd
    /home/lvtest
    

Adding Color

  • 可以在PS里面加入ASNI color的值
    lvtest@auto-inst:~$PS1="\[\033[0;31m\]<\u@\h \W>\$ "
    <lvtest@auto-inst ~>$ pwd
    

Saving the Prompt

  • 我们通过export来保存设置
    <lvtest@auto-inst ~>$ PS1="\[\033[s\033[0;0H\033[0;41m\033[K\033[1;33m\t\033[0m\033[u\]<\u@\h \W>\$ "
    17:39:02<lvtest@auto-inst ~>$ export PS1
    

Package Management

Packaging Systems

  • Linux上面可以使用源代码来编译,但是这样太费事.所以就有了package system,它是 帮你编译好的binary,可以直接下载.主要的package 系统有如下:
    Packaging System Distributions(partial listing)
    Debian style(.deb) Debian, Ubuntu, Xandros, Linspire
    Red Hat style(.rpm) Fedora, CentOS, Read Hat, openSUSE, Mandriva

How a Package System Works

Package Files

  • packaging系统里面最小的单元就是packege file.
  • package file包含了pre-installation script 和post-installation script在安装 前后使用.

Repositories

  • 成千上万的package会被安排到一个中心的服务器叫做repository

Dependencies

  • 程序很少能够自我完成功能的,很多都要依靠dependency, package management系统会 提供一种叫做dependency resolution的方法来确保在安装这个文件的时候,它的dependency 都已经安装完毕了.

High-and Low-Level Package Tools

  • high-level tools用来处理metadata search和dependency resolution (总是和repo相联系)
  • low-level tools用来安装和移除软件(不和repo有瓜葛,本地操作)
  • 常见的tools有
    Distributions Low-Level Tools High-Level Tools
    Debian style dpkg apt-get, aptitude
    Redhat style rpm yum

Common Package Management Tasks

Finding a Package in Repository

  • high-level tools就可以来search
    Style Command
    Debian apt-get update
      apt-cache search search_string
    Red Hat yum search search_string

Installing a Package from a Repository

  • high-level tools可以找到并且下载,然后安装这些软件
    Style Command
    Debian apt-get update
      apt-get install package_name
    Red Hat yum install package_name

Installing a Package from a Package File

  • 如果我们从其他地方下载了安装包,那么就要用low-level tools来直接安装它们
    Style Command
    Debian dpkg –install package_file
    Red Hat rpm -i package_file

Removing a Package

  • high-level tools 移除软件的方法如下
    Style Command
    Debian apt-get remove package_name
    Red Hat yum erase package_name

Updating Packages from a Repository

  • package系统不仅仅是为了安装方便,其更重要的作用是为了能让系统总是和repo保证 同步(软件最新)
    Style Commands
    Debian apt-get update; apt-get upgrade
    Red Hat yum update

Upgrading a Package from a Pckage File

  • low-level的方法升级
    Style Command
    Debian dpkg –install package_file
    Red Hat rpm -U package_file

Listing Installed Packages

  • 查看机器上面有哪些安装的软件,是不需要和repo相联系的,所以是一个low-level tool command
    Style Command
    Debian dpkg –list
    Red Hat rpm -qa

Determining Whether a Package Is Installed

  • 判断一个package是否安装也不需要和repo通信,所以是一个low-level tool command
    Style Command
    Debian dpkg –status package_name
    Red Hat rpm -q package_name

Displaying Information About an Installed Package

  • 查看一个已经安装文件的信息
    Style Command
    Debian apt-cache show package_name
    Red Hat yum info package_name

Finding Which Package Installed a File

  • 查找某个binary是被哪个package安装的
    Style Command
    Debian dpkg –search file_name
    Red Hat rpm -qf file_name
  • 这个命令有点绕,说个例子会比较容易理解:查询哪个package安装了/usr/bin/vim
    lvtet@auto-inst: rpm -qf /usr/bin/vim