读书笔记-LinuxShell编程与服务器管理-part1

来源:互联网 发布:淘宝一件代发怎么加入 编辑:程序博客网 时间:2024/05/18 03:29

读书笔记-LinuxShell编程与服务器管理-part1 的内容在github  点击这里

note01: Linux/BSD系统分成3个重要部分;
                *核心(kernel)
                *Shell
                *工具程序
                相对应的关系是:
                                核心非常复杂,非常难用
                                Shell为核心提供良好的接口


note02: Shell根据表现形式:
                *Text base
                *Graphic base


note03: Linux/BSD的Shell种类非常多,
                可以让人自由地更换(使用chsh指令)
                目前常用的Shell有:
                sh / bash / ksh93 / pdksh / csh / tcsh
                sh : Bourne Shell                                 BSD/Public Domain
                Bash : Bourne Again Shell                GPL
                Bash兼容sh
                在Linux套件中,常用的是Bash


note04: Bash有两种工作模式:
                互动模式和非互动模式
                互动模式:
                                interactive mode
                                键盘输入命令,必须等待Shell执行完,
                                才能执行下一条命令。
                非互动模式:
                                Shell Script mode
                                non-interactive mode
                                设计Shell Script,把要执行的命令写在
                                文件中,交由Bash去读取和执行。
                                效率高,也称为自动化模式。


note05: Bash Shell的特性:
                *兼容 Bourne Shell (sh)
                *支持许多选项及变量,可自定义Shell的使用环境
                *支持历史命令(history)
                *命令列修订的能力,可重新取用或修改之前执行过的命令
                *具有job control的能力,可控制前台及后台程序
                *具有程序设计的能力
                *具有:普遍且免费,小(文件小),快(免编译即可执行),
                                   准(正确性高),稳定(可重复试验),可组合使用。。。


note06: 编写第一个Bash
                #!/bin/bash
                echo "你好 Bash Shell;" 
                保存为hello.sh
                添加执行权限: chmod +x hello.sh
                ./hello.sh回车之后,就能看到结果


note07: 第一个有用的Bash Shell
                cp /dev/null /var/log/apache2/access.log
                利用特殊文件/dev/null(只写文件),清空apache2的日志文件(文件大小变成0,但文件仍然存在)
                然后 chomod +x /root/cleanlog.sh
                crontab -u root -e
                接着,在vi中填入:
                0 6 * * * /root/clearlog.sh
                那么每天凌晨6时,就会执行clearlog.sh,自动清理log文件。


note08: 在Linux平台部署Bash Linux的环境
                查看SHELL的支持:echo $SHELL
                一般会有 /bin/Bash或者在Ubuntu中/bin/bash
                ls -la /bin/sh
                一般可以看到 /bin/sh是一个link,链接到 /bin/sh --> Bash
                在Ubuntu 14.04中是 /bin/sh --> dash
                只要在.sh文件中指定 #!/bin/bash就行了。


note09: 自行编译最新版本的Bash
                1,  下载Bash的最新版本:http://ftp.gnu.org/gnu/bash/
                2,  下载到的是一个bash-x.x.x.tar.gz文件
                3,  解压 tar -zxvf bash-x.x.x.tar.gz
                4,  进入目录,执行设定。
                                ./configure 会将bash安装到/usr/local目录下
                                也可以使用 --prefix知道要安装的路径
                                ./configure --prefix=/home/zxwtry
                5,  编译
                                make
                6,  测试
                                make tests
                                先执行看看:
                                ./bash
                                echo $BASH_VERSION
                                接着,离开新编译的bash (即执行exit),回到原来的环境
                7,  安装(注意root和user用户)
                                (user可以之前4使用--prefix进行安装,user安装之后,只能是user使用)
                                make install
                                或者使用
                                su -c "make install"
                                (make install默认会把bash的执行文件安装在/usr/local/bin中)
                                (如果之前4进行了--prefix指定的话,就在自定义的目录) 


note10: 切换使用新版本的Bash Shell
                对应的命令是:chsh命令(即change Shell的简称)
                chsh会检查/etc/Shells这个文件,只有列在该文件中的Shell程序
                ,才算是合法的Shell,才能供使用者选用。
                编辑/etc/Shells文件,在最后添加/usr/local/bin/bash
                或者 echo '/usr/local/bin/bahs' >> /etc/Shells (注意:>会删除文件之前的东西)
                或者 su -c "echo '/usr/local/bin/bash' >> /etc/Shells"
                使用者自行切换: chsh --> 输入密码 --> 输入 /usr/local/bin/bash 
                root帮忙切换: chsh zxwtry  --> 输入 /usr/local/bin/bash
                
note11: 登录主机:分为本机登录(local login)和远程登录(remote login)                                
                区分:使用网络登录的就是远程登录


note12: 本机登录的接口:文本接口和图形接口
                在Linux/BSD系统,默认会开启7个终端界面即:tty1 ~ tty7
                其中,文本接口的主机登录,占用tty1 ~ tty6
                                  图形接口的主机登录,占用tty7
                如果需要在各终端之间切换,可按Ctrl+Alt+F1 ~~~ Ctrl+Alt+F7
                
note13: 远程登录:ssh和telnet等程序来登录,其中openssh是有加密编码
                ssh -l zxwtry 192.168.1.2
                ssh zxwtry@192.168.1.2
                ssh 192.168.1.2 (等同于 ssh -l root 192.168.1.2)


note14: 注销主机、结束终端程序
                exit 或者 Ctrl + D (先ctrl 后 d)


note15: 不同文件形态的代码,表现如下:
                -   一般文件
                d   目录文件
                l   符号链接文件
                b   磁盘设备文件
                c   字符设备文件
                s   Socket文件
                p   连接文件
                其中:一般文件-:纯文本文件,二进制文件,可执行文件等等
                                  目录d:包含文件的活页夹
                                  设备文件;字符文件b、磁盘文件c
                                  内部进程通信文件:Socket文件s、连接文件p(Pipe/FIFO)
                                  连接文件也是一种内部进程通信的机制:
                                                一个进程把数据写入Pipe中
                                                另一个进程则由Pipe读取数据
                                                数据采FIFO的次序,成为管道
                                  特殊文件:符号链接文件。
                                                符号链接文件称为soft link或symbolic link
                                  有的文件以.开头,表示是隐藏文件,隐藏文件可以是如上任何一种文件。


note16: file的用法
                file /tc/resolv.conf
                                执行的结果是:/etc/resolv.conf:ASCII text
                                这表示,resolv.conf是一个纯文件文件,属于一般文件
                file /usr/bin
                                执行的结果是:/usr/bin:directory
                                这表示,/usr/bin是一个目录
                file /usr/bin/ssh
                                执行的结果是:/usr/bin/ssh: ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=2f6aacfa7c26a98a02ce2a846cb03f753be0271d, stripped
                                这表示,/usr/bin/ssh是一个二进制文件,具有可执行的特点
                file hello.sh
                                执行的结果是:code001_print_hello_Bash.sh: Bourne-Again shell script, UTF-8 Unicode text executable
                                这表示,hello.sh是一个Bash Script文件,具有可执行的特点
                file /dev/tty
                                执行的结果是:/dev/tty1: character special
                                这表示:/dev/tty1 是一个字符设备文件
                file /dev/sda
                                执行的结果是:/dev/sda: block special
                                这表示:/dev/sda是一个磁盘设备文件
                file /dev/initctl
                                执行的结果是:/dev/initctl: fifo(named pipe)
                                这表示,/dev/initctl是一个连接文件
                file /var/run/mysqld/mysqld.sock
                                执行的结果是:/var/run/mysqld/mysqld.sock: socket
                                这表示,/var/run/mysqld/mysqld.sock是一个socket文件
                file /bin/sh
                                执行的结果是:/bin/sh:symbolic link to "bash"
                                这表示,/bin/sh是一个链接到/bin/bash的符号链接文件
                
note17: 文件权限
                UNIX-like系统,将文件模式,分成3种身份、4种权限
                3种身份是:
                                u:  自己(user),即文件的拥有者
                                g:  和自己同一组的人(group)
                                o:  其他人(other)
                                而a代表所有人   
                每种身份皆有4种可能的权限:
                                r:  读取权限
                                w:  写入权限
                                x:  执行权限
                                s:  特殊权限  set user id(s)、set group id(s)及sticky bits(t),简称sst
                UNIX-like系统用10个字符来表示文件模式,如下所示:   
                文件形态 文件拥有者权限 隶属组权限 其他身份的权限
                   -                                rwx                                                 rwx                 rwx
                r --- 4                 w --- 2                 x --- 1
                如果某一个文件执行时,执行者可以暂时变成"文件拥有者"的身份,则称为具有特殊权限
                                set user id,其权限组rwx则改用rws来表示。这种文件,会在原权限值(假定0755)
                                之前加上4000,记为4755
                                /usr/bin/chsh文件拥有者的权限记为rws,这表示使用者执行chsh时,可暂时用root
                                身份来变更login Shell的种类
                如果一个文件执行时,执行者可以暂时变成"用户组"的身份,则称为拥有特殊权限
                                set group id,其权限组r-x改用r-s表示,这种文件会在原文件的权限值 (假定0755)
                                之前加上2000,记为2755
                如果某一个目录,其中的文件只有文件拥有者才能删除,则称该目录具有特殊权限
                                seticky bit,其权限组记为rwt。这种文件会在原权限值(假定0755)之前加上1000
                                记为1755
                                某个文件drwxrwxrwt(1777),表示该文件可被其他用户新建文件,读取文件,执行文件
                                但是只有文件的建立者才能删除自己建立的文件。
                需要特别小心目录的权限组,以rwx来说,其中x对目录而言不是执行的意义,而是
                                可以进入该目录的权限。例如,/var/www的目录属性如下:
                                drwx------ 8 www-data www-data 4096 2016-10-16 22:23 /var/www
                                这表示,只有执行身份同于www-data的账号,才能进入/var/www这个目录


note18: 设定权限
                chmod 755 hello.sh 
                chmod +x hello.sh 等同于给3种身份加上可执行权限等同于 chmod a+x hello.sh
                如果只是给文件拥有者自己加上执行权限,应执行
                                chmod u+x hello.sh
                只是给组身份加上执行权限,应执行
                                chmod g+x hello.sh
                只是给其他人身份加上执行权限,应执行
                                chmod o+x hello.sh
                如果将+x更改成-x,则是去掉执行权限的意思。
                比如,去掉"其他人身份"执行权限
                                chmod o-x hello.sh


note19: 通配符
                两个常用通配符:*和?,其中*代表任意的字符串,可以是空字符串
                                                                                                                  ?代表一个字符,但不可以为空


note20: 转义字符
                在/root下执行 echo 9 * 9 = 81   的结果是 9 github install temp 9 = 81
                在/root下执行 echo 9 '*' 9 = 81 的结果是 9 * 9 = 81
                在/root下执行 echo '9 * 9 = 81' 的结果是 9 * 9 = 81
                在/root下执行 echo 9 \* 9 = 81  的结果是 9 * 9 = 81
                
                执行 echo this is zxwtry's book                 的结果是 bash认为输入没有完成 >
                执行 echo this is zxwtry\'s book                的结果是 this is zxwtry's book 
                执行 echo this is zxwtry'\''s book  的结果是 bash认为输入没有完成 > 
                执行 echo this is zxwtry'\'s book   的结果是 this is zxwtry\s book 
                执行 echo this is zxwtry's book'                的结果是 this is zxwtrys book
                执行 echo "this is zxwtry's book"   的结果是 this is zxwtry's book
                执行 echo 'this is zxwtry"s book'   的结果是 this is zxwtry"s book


note21: 常见的转义字符:
                ' --- \'                " --- \"                * --- \*                ? --- \?                \ --- \\
                ~ --- \~                ` --- \`                ! --- \!                # --- \#                $ --- \$
                & --- \&                ( --- \(                ) --- \)                | --- \|                [ --- \[
                ] --- \]                { --- \{                } --- \}                ; --- \;                < --- \<
                > --- \>                / --- \/


note22: 续行符号:\  将上下输入的两行,视为一行
                echo "line 1 \
                                  line 1 too"
                                输出的结果是:line 1 line 1 too
                经常使用的情形如下:
                ./configure \
                                --with-apache=../apache_$ApacheVersion \
                                --with-mysql=$MYSQLHOME &&


note23: 字符集合
                [] : 所在范围内的某一个字符,其长度为1
                                [abc], [a-z], [A-Z], [a-zA-Z]
                由于-已经用于表示集合范围,如果需要在集合中添加-
                                那么必须将-放置在集合的开头或者结尾
                                [a-z_-]:代表小写字母、下划线、以及-字符
                !放置在集合前面表示非的意思
                                [!abc]:只要不是a不是b不是c就行
                                [!a-z]:只要不是小写字母就行
                                [\!abc]:只要是a b c或者!就行
                                [abc!]:只要是a b c或者!就行
                注意[abc.*]:指的是a b c . *中的其中一个


note24: 括号扩展{}
                {g,gc,s}ftp表示的是gftp, gcftp, sftp
                aabb{,.bak}表示的是aabb或者aabb.bak
                mkdir -p /root/temp/{dir1,dir2,dir3}/{a,b,c}:
                                在dir1,dir2,dir3目录下,都建立a,b,c3个子目录
                echo {1,2,3}\*{1,2,3}   输出的是:
                                1*1 1*2 1*3 2*1 2*2 2*3 3*1 3*2 3*3
                echo {1,2,3}*{1,2,3}                输出的是:
                                1*1 1*2 1*3 2*1 2*2 2*3 3*1 3*2 3*3
                echo {1,2,3} * {1,2,3}  输出的是:
                                1 2 3 github install temp 1 2 3
                echo {1,2,3}* {1,2,3}   输出的是:
                                1* 2* 3* 1 2 3
                
note25: 系统默认开启的文件
                每一个Shell Script执行时(称为"进程"或"处理程序"),
                                系统默认会开启3个标准文件,分别是:
                                标准输入(stdin),标准输出(stdout),标准错误(stderr)
                                键盘                                                 屏幕                                                  屏幕
                系统开启这3个标准文件时,是以文件代码做连接。
                                标准输入的文件代码为0
                                标准输出的文件代码为1
                                标准错误的文件代码为2
                                称这3个文件为标准I/O(Input和Output)


note26: 标准输入/输出转向
                把标准输入/输出重新指定到别的文件,称为"转向"
                转向输出:echo zxwtry@zxwtry > a.txt
                转向附加:echo zxwtry@zxwtry >> a.txt
                转向输入:使用统计行数的形式来作demo
                                输入wc -l回车
                                接着输入line1
                                                                line2
                                                                line3
                                再按Ctrl+D结束输入
                                                wc -l会马上计算行数
                                wc -l < input.txt会直接输出input.txt的行数


note27: 转向输入转向输出的合用
                用法:命令或Script < 输入文件 > 输出文件
                用例:sort < unsort.txt < sorted.txt
                利用转向输出做建立编辑
                                cat > out.sh
                                #!/bin/bash
                                echo "你好世界"
                                按ctrl+D退出编辑,即有一个out.sh文件


note28: 管道
                管道:一个程序的输出,可以变成另一个程序的输入
                优势:不同的程序可以一起合作,完成一项工作
                                  发挥"组合的力量"
                用法:基本型:命令1 | 命令2
                                  cat unsort.txt | sort
                                  cat unsort.txt | sort > sorted.txt
                                  cat sorted.txt | lp
                                  (把sorted.txt通过管道,交给打印机程序lp,打印内容)
                                  多个管道组合:命令1 | 命令2 |... | 命令n
                                  grep '".*" 4[0-9][0-9]' access.log | grep -o '".*" 4[0-9][0-9]' |
                                                                sort | uniq -c | sort -n | tee alog.txt
                                                                grep: 从日志文件中,找出含有4xx错误信息的数据行
                                                                grep -o : 取出符合样式的字符串,交给sort排序
                                                                相同的数据行,便会摆在一起
                                                                uniq -c : 把重复的数据行删除,并统计重复的次数
                                                                sort -n : 用数值比较的方式排序
                                                                tee : 交给tee打印出结果,同时tee也把结果存储在alog.txt文件中。


note29: UNIX-like程序的工作哲学:
                把一件工作分成几个部分,各部分交由一个小工具去完成,最后通过管道组合起来。
                小工具的开发原则:努力地把一件工作做到最好。


note30: 前台工作、后台工作
                前台工作:  每执行一条指令,都要等到该指令执行结束后,才能取得键盘的控制权
                                                                然后再执行下一条指令。
                后台工作:  利用操作系统分时的架构,将工作放到后台;在工作未完成之前,
                                                                仍然拥有键盘的控制权。
                ./my-work.sh &
                                & 符号表示:把my-work.sh 放到后台执行
                此时,系统会显示该程序的进程编号,例如[1] 11973
                在my-work.sh运行过程中,在Shell中仍然能够执行其他程序。
                当my-work.sh执行结束,系统会显示:
                                [1]+ Done                ./my-work.sh


note31: Shell程序的组成
                程序是:code003_shell_structure.sh,运行过程如下:
                                ./code003_shell_structure.sh 天竺
                                今天是2016-10-17,贫道来自东土大唐,去往天竺拜佛求经
                                
                                Bye-Bye :-)
                程序结构讲解:
                                show_name是一个函数定义如下
                                                function show_name() {
                                                                echo "今天是$1,贫道来自$2,去往$3拜佛求经"
                                                }
                                三个变量,如下:
name="$1"
address="东土大唐"
today=`date +%F`
                                if条件判断语句:
if [ $# != 1 ]; then
               echo "Usage: . /$0 {使用者名称}"
               exit
fi
                                调用show_name函数:
                                                show_name "$today" "$address" "$name"
                                进程睡眠5秒:
                                                sleep 5
                                最后执行一些输出


note32: 执行Bash Scipt的方式:
                方法一:./test.sh
                方法二:bash test.sh
                                                sh test.sh
                (以上两种方法,Script在执行时,现行的Shell也叫父Shell,
                 会开启一个子Shell环境,此Script即是在这个子Shell中执行。
                 Script执行完毕之后,此子Shell环境随机关闭,回到现行的Shell中)
                方法三:也可以让Script在现行的Shell中执行,方法如下:
                                . /root/temp/test.sh
                                source /root/temp/test.sh
                                注意.和/之间至少要有一个空格


note33: Bash Script排错的方法
                先检查语法的正确性,然后追踪Script执行的过程,进行排错。
                检查语法的指令如下:(假设将sleep 5 写成 slep 5)
                                bash -v code003_shell_structure.sh 天竺
                                                slep 5
                                                code003_shell_structure.sh: line 18: slep: command not found 
                                只需要修改slep就行了。
                追踪Script的执行:
bash -x code003_shell_structure.sh 天竺
+ name=天竺
+ address=东土大唐
++ date +%F
+ today=2016-10-17
+ '[' 1 '!=' 1 ']'
+ show_name 2016-10-17 东土大唐 天竺
+ echo 今天是2016-10-17,贫道来自东土大唐,去往天竺拜佛求经
今天是2016-10-17,贫道来自东土大唐,去往天竺拜佛求经
+ sleep 5
+ echo

+ echo 'Bye-Bye :-)'
Bye-Bye :-)


note34: 强制变量一定要经过声明才能使用
                bash有一内置命令shopt,可用来设定bash的功能选项。
                                其中有一个选项和程序排错有关,如果启用此选项,可避免错打变量名称
                                造成程序执行错误的情况。用法如下:
                                                shopt -s -o nounset


note35: 在特定位置摆放echo指令,可以进行排错。


note36: Bash Script执行的原理:login Shell
                登录主机后,在执行Bash Script之前,所处的环境已经是在一个Bash Shell之中
                这个Shell叫做login Shell,是将来我们执行任何Script的上层环境,又叫做父Shell
                login Shell从何而来:
                                每个账号都可以自定义login Shell。
                                以Linux来说,账号的login Shell定义在/etc/passwd这个文件里头。
                                /etc/passwd的结构:
                                                /etc/passwd的每一行代表一个账号,共有7个字段,字段之间用:隔开,如下所示:
                                                账号:x:UID使用者代码:GID群组代码:用户信息:主目录位置:login Shell程序
                                                第2栏x原为密码栏,基于系统安全考虑,编码后的密码已被放到到/etc/shadow文件之中
                                                login Shell定义在7个字段。如果在这个字段的Shell程序不存在、不合法(不存在/etc/shells之列)
                                                或者执行结果失败(如/bin/false),则这个账号就无法登录主机。
                                例如:
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
libuuid:x:100:101::/var/lib/libuuid:
syslog:x:101:104::/home/syslog:/bin/false
messagebus:x:102:106::/var/run/dbus:/bin/false
landscape:x:103:109::/var/lib/landscape:/bin/false
sshd:x:104:65534::/var/run/sshd:/usr/sbin/nologin
zxwtry:x:1000:1000:zxwtry,,,:/home/zxwtry:/bin/bash
                                普通用户可以使用chsh更换login  Shell


note37: 父Shell和子Shell
                当我们执行某一个Shell Script时,父Shell会根据Script程序的第一行#!之后所指定的Shell程序开启
                (此操作称为fork)一个子程序Shell的环境,然后,在子Shell中执行此Shell Script。
                一旦子Shell中的Script执行完毕,此子Shell随机结束,仍然回到父亲Shell之中,不会影响父Shell原本的环境
                子Shell和父Shell一样,会开启3个文件:标准输入,标准输出,标准错误。
                                同时,子Shell会继承父Shell的若干变量值的内容,这些变量称为环境变量。 
                执行code004_sub_shell.sh完成之后,不会切换到/root/temp
                如果要切换到/root/temp,可以执行
                                . /root/code004_sub_shell.sh
                                souce /root/code004_sub_shell.sh
                                这样就会切换到/root/temp。
                                (这种执行Script的方式,会影响父Shell的环境,通常在做系统调校时,才会如此运用)


note38: 子Shell再开启子Shell
                如何知道目前是在哪一层的Shell呢?
                                echo $SHLVL
                                也可以使用ps axf,观察内存中各进程之间的层级关系
                echo $SHLVL使用如下:
root@zxwtry:~# echo $SHLVL
1
root@zxwtry:~# bash
root@zxwtry:~# echo $SHLVL
2
root@zxwtry:~# bash
root@zxwtry:~# echo $SHLVL
3
                ps axf如下:
                                  1044 ?                                Ss                 0:00  \_ sshd: root@pts/1                
 1184 pts/1                Ss+                0:00  |   \_ -bash
 1128 ?                                Ss                 0:00  \_ sshd: root@pts/2                
 1245 pts/2                Ss+                0:00  |   \_ -bash
 1136 ?                                Ss                 0:00  \_ sshd: root@pts/5                
 1304 pts/5                Ss+                0:00  |   \_ -bash
 1197 ?                                Ss                 0:00  \_ sshd: root@pts/6                
 1364 pts/6                Ss                 0:00                  \_ -bash
 2746 pts/6                S                  0:00                                  \_ bash
 2756 pts/6                S                  0:00                                                  \_ bash
 2766 pts/6                R+                 0:00                                                                  \_ ps axf

note39: POSIX
                POSIX: Portable Operating System Interface
                POSIX: 可移植操作系统接口
                POSIX: 期望获得源代码级别的软件可移植性。
                                   (为一个POSIX兼容的操作系统编写的程序,应该可以
                                                在任何其它的POSIX操作系统上编译执行)


note40: Bash Shell的启动配置文件
                Bash有5种运行模式:
                                1,  互动模式
                                                (Bash的输入、输出都和终端连接)
                                                (Bash由键盘读取用户输入的指令来执行)
                                                (须等一个指令执行完了之后,才能执行下一条指令)
                                                (命令行互动)
                                2,  非互动模式
                                                (执行一个Scrpt程序)
                                3,  以sh名称调用
                                4,  POSIX模式
                                5,  限制功能模式
                在不同的运行模式中,Bash调用不同的启动配置文件。
                Bash的启动配置文件,主要与Shell的环境设定有关。


note41: Bash Shell的启动配置文件---登录(login),注销(logout)
                登录时候,
                首先,login Shell先执行 /etc/profile
                接着,检查用户的主目录中,是否有 .bash_profile
                                  .bash_login  .profile三个文件之一
                                 (优先级:.bash_profile > .bash_login > .profile)
                注销时候,
                bash检查主目录中是否有.bash_logout。如果有,执行它。


note42: Bash Shell的启动配置文件---执行新Shell
                执行新Shell(非login Shell),可分成两种情况:
                * 执行交互式的Shell:例如,直接执行bash,产生一个子Shell。
                 此时,bash会读取并执行/etc/bash.bashrc,以及主目录中的.bashrc
                * 执行Shell Script(即非交互式的Shell):例如,执行Script文件test.sh,
                 它会检查BASH_ENV变量的内容,若该变量有定义,则综合性该变量所定义
                  的启动活动文件的内容。
                假定BASH_ENV的内容执行bash_env.sh,如下所示:
                 export BASH_ENV="/home/zxwtry/bash_env.sh"
                bash_env.sh文件内容如下:
                                #!/bin/bash
                                echo "Hi! BASH_ENV is running."
                tesh.sh文件内容如下:
                                #!/bin/bash
                                echo "running test.sh"
                运行过程如下:
                                export BASH_ENV="/home/zxwtry/bash_env.sh"
./test.sh 
Hi! BASH_ENV is running.
running test.sh
                
note43: Bash Shell的启动配置文件---以sh文件名调用bash
                若以sh文件名调用bash,则仿照旧版的sh执行
                (会尽量兼容于POSIX的标准功能)
                (bash特有的功能将会丧失)
                * login Shell调用/bin/sh:账号登录时使用/bin/sh
                  (在/etc/passwd中该账号行的第7字段是/bin/sh)
                  (bash会读取并执行/etc/profile和主目录的.profile)
                * 执行交互式Shell:例如,执行/bin/sh,产生一个子Shell
                  (bash会检查ENV变量的内容,如果有定义,执行对应文件)
                * 执行Shell Script:若Shell Script第一行#!之后,
                  调用的Shell程序是/bin/sh,则bash不会执行任何启动配置文件。


note44: Bash Shell的启动配置文件---以BASH--POSIX的方式执行
                此称为POSIX模式,bash使用与POSIX标准兼容的功能。
                (bash会检查ENV变量的那日容,如果有定义,执行对应文件)


note45: Bash Shell的启动配置文件---以Bash -r或者以rbash的名称调用
                rbash其实只是一个指向bash的soft link。
                执行Bash -r或者rbash,称为受限模式。
                (bash的功能受到许多限制,不能使用cd指令,不能设定或取消环境变量等等)
                (只让登录者拥有少数可用的功能,是一种安全性的考虑)
                (bash会读取、执行主目录里的.bashrc配置文件)
                (尽量少用,不要仅以bash -r作为建立安全Shell环境的唯一凭据)


note46: Bash Shell的启动配置文件---总结
                * 登录
                                bash先执行/etc/profile,再调用~/.bash_profile
                * 注销
                                bash调用~/.bash_logout
                * 执行新Shell
                                在图形接口,执行终端程序或手动执行/bin/bash ||
                                在编辑程序中调用Shell(如Emacs的Shell mode)
                                会先调/etc/bash.bashrc,再调用~/.bashrc
                * 执行Script(使用#!/bin/bash)
                                不调用.bash_profile、.bashrc,但会检查BASH_ENV的内容,
                                如果非空,则执行它指定的文件。
                * 执行Script(使用#!/bin/sh)
                                不调用任何启动文件,没有其他检查环境变量的操作


note47: Bash Shell Script包含的指令有"内置的"和"命令行程序"两种
                内置的:Bash程序本身就有提供这个功能
                命令行程序:Bash外部的车管内需,独立存在于文件系统中的执行文件
                                                                有时称为"工具"程序,简称外部程序
                判断某一个指令是不是内置命令,可以用"type命令"看出来,例如:
                                type echo 执行结果是:
                                                echo is a shell builtin
                                                (表明,echo是一个内置命令,bulitin---内含)
                                type mkdir 执行结果是:
                                                mkdir is /bin/mkdir
                                                (表明,mkdir是一个命令行程序,文件路径在/bin/mkdir)


note48: 内置命令
                Bash Shell的内置命令,由于不需要去搜寻路径($PATH)中查找,
                                直接就能执行,因此,速度很快。
                常见的内置命令有:
                                alias   bg                  bind                break   bulitin case                cd
                                command compgen complete                                continue                                decalare
                                dirs                disown  echo                enable  eval                exec                exit
                                export  fc                  fq                  for                 getopts bash                help
                                history if                  jobs                kill                let                 local   logout
                                popd                printf  pushd   pwd                 read                readonly
                                return  set                 shift   shopt   source  suspend test
                                time                trap                type                typeset ulimit  umask   unalias
                                unset   until   wait                while




note49: 有意思的命令
                echo -n 不想让它自动换行
                                执行结果:
                                                zxwtry@zxwtry:~$ echo -n "aabb"
                                                aabbzxwtry@zxwtry:~$
                echo -e 可以让字符串中的特殊字符起作用
                                执行结果:
                                                zxwtry@zxwtry:~$ echo -e "aa\nbb"
aa
bb
zxwtry@zxwtry:~$


note50: printf的用法
                %q  将特殊字符用\转义
                                执行结果:
                                zxwtry@zxwtry:~$ printf "%q" []{}/
                                \[\]\{\}/zxwtry@zxwtry:~$
                %e  科学记数法
                                执行结果:
                                zxwtry@zxwtry:~$ printf "%e\n" 10000
                                1.000000e+04
                %g  由Bash选择使用%f或者%e
                                执行结果:
                                zxwtry@zxwtry:~$ printf "%g\n" 10000
10000
zxwtry@zxwtry:~$ printf "%g\n" 10000.00
10000
zxwtry@zxwtry:~$ printf "%g\n" 10000.12
10000.1
zxwtry@zxwtry:~$ printf "%g\n" 10000.1233
10000.1
                %i  等同于%d
                %o  显示八进制数
                %x  显示十六进制数,a-f表示
                %X  显示十六进制数,A-F表示
                                执行结果:
zxwtry@zxwtry:~$ printf "%x\n" 1993
7c9
zxwtry@zxwtry:~$ printf "%x\n" -1993
fffffffffffff837
zxwtry@zxwtry:~$ printf "%X\n" 1993
7C9
zxwtry@zxwtry:~$ printf "%X\n" -1993
FFFFFFFFFFFFF837
%%  显示%这个符号

0 0