bash-basic
Table of Contents
- What is the shell
- Navigation
- Exploring The System
- Manipulating Files And Directories
- Working With Commands
- Redirection
- Seeing the world as the shell sees it
- Advanced keyboard tricks
- Permissions
- Processes
- The Environment
- A Gentle Introduction to VI
- Customizing The Prompt
- Package Management
- Packaging Systems
- How a Package System Works
- Common Package Management Tasks
- Finding a Package in Repository
- Installing a Package from a Repository
- Installing a Package from a Package File
- Removing a Package
- Updating Packages from a Repository
- Upgrading a Package from a Pckage File
- Listing Installed Packages
- Determining Whether a Package Is Installed
- Displaying Information About an Installed Package
- Finding Which Package Installed a File
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 = ⅈ 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
- 传统的方法,要转两次,利用了stdout的file descriptor为1
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
- 双引号做的就没那么绝:留下了三个活口:
- $(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
- \(backslash): 双引号不加入的话,backslash是不管用的,加了双引号,再echo加
-e就能起到作用了
bash-3.2$ echo -e "hello\nworld" hello world
- `(back tick): 这个是old-style的$()等价体,$()被特赦了,它也一样
bash-3.2$ echo "`id -u`" 501
- $(dollar sign) : 依赖dollor的三个parameter expansion,command substitution,
arithmetic都没问题
- 由于双引号的加入,我们也可以查看带空格的文件了(虽然带空格的文件不推荐在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是可执
行
- 其中的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的例子
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:
- login shell: 我们登录的时候弹出输入姓名密码就是login shell. "su -l username" 也是一种login shell
- 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