读书笔记-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
%% 显示%这个符号