记录学习笔记、分享资源工具、交流技术思想、提升工作效率

《实战linux_shell编程与服务器管理》读书笔记

运维 xiaomudk 6年前 (2015-08-15) 6396次浏览 0个评论
文章目录[隐藏]

环境:CentOS-5.5-i386-2
shell目录:/tmp/test/

第一章 shell简介

1.5第一个有用的bash shell

#! /bin/bash
#清空apache2的日志文件
cp /dev/null /var/log/apache2/access.log

第二章 部署bash shell的环境

2.1布署bash shell环境

检查默认shell
echo $SHELL
检查bash shell的版本
echo $BASH_VERSION

检查可设置为默认shell的shell

cat /etc/shells   (或chsh -l) (新安装的shell也可以在这个里面添加)

修改默认shell: chsh 使用者账号

第三章 基础概念介绍

3.1登录、注销

openssh登录的三种方法:

  • ssh -l 账号 主机名或IP
  • ssh 账号@主机名或IP
  • ssh 主机名或IP

3.2文件、目录

文件:
文件的形态代码:
file
查看文件的形态代码:ls或file

文件权限:

-rwsr-xr-x  4775 
-rwxr-xr-x 1 root root 581K Sep 19  2009 /bin/vi

/bin/vi现在是755权限
如果/bin/vi设置为4755权限,现在其它用户使用这个vi的话,就会像root用户一样,可以任意更改文件!
给一个文件设置了suid,就是表示其它用户可以 以属主的权限来运行它!但是仅仅是运行它!
由于SUID是在执行程序(程序的可执行位被设置)时起作用,而可执行位只对普通文件和目录文件有意义,所以设置其他种类文件的SUID位是没有多大意义的

让本来没有相应权限的用户运行这个程序时,可以访问他没有权限访问的资源,获得程序属主的资源访问权限。

3.3通配符与转义字条

 * :代表任意字符串,可以为空字符串
 ? :代表一个字符,不可以为空!

 转义字符
 反斜线(\)
举例:
echo 9 * 9 = 81    base会把*视为通配符, 而以工作目录中所有的文件名取代它!
修正:
单引号:
echo 9 '*' 9 =81
echo '9 * 9 = 81'
转义字符:
echo 9 \* 9 = 81

特例:一对单引号中,不可以出现单引号,就算用转义字符\也不行。
echo 'This is Jack\'s book.' 多出一个’,会认为用户还没有输入完。
解决办法:

echo This is Jack\'s book.
echo "This is Jack's book."
echo 'This is Jac’k\''s book.'

常见的转义字符的用法:
file

续行符号:
转义字条唯一的例外:\的后面加回车,为”续行字符“,上下两行为视为一行!

3.4 字符集合

字符集合的符号是中括号:[],[]中所列的字符范围中的某一个字符,其长度为1!
以下列举常见的字符集合,注意! – 代表字符的范围

  • [a-z] :小写字母
  • [A-Z] :大写字母
  • [a-zA-Z] :大小写字母

– 代表字符集合的范围,如果要把 – 也纳为集合一分子,就把 – 放在集合的开头或结尾。

字符集合的“非”:
[!abc] : 只要不是a ,不是b,不是c,都符合。
[!0-9] :不是数字
[!a-z] :不是小写字母
[!A-Z] :不是大写字母
注:!若不在集合的第一位置,就失去了“非”的意义 : [0-9!]代表数字或感叹号
[!0-9] 也是代表感叹号或数字!

3.5括号扩展

用途:“组合”字符串
例:{g,nc,s}ftp 表示:gftp,ncftp或sftp
echo {1,2,3,4,5,6,7,8,9}*{1,2,3,4,5,6,7,8,9} 显示11 ~ 99 。( * 前后不能加空格,)

3.6 系统默认开启的文件

默认开启3个标准文件:标准输入(stdin)、标准输出(stdout)、标准错误(stderr)
分别对应的文件代码:0、1、2.

3.7 标准输入/输出转向

转向输出

转向附加

转向输入
<
转向输入和转向输出合用
格式:命令或scrip < 输入文件 > 转出文件
例: sort < unsort.txt > sorted.txt
sort读取unsort.txt里的数据,进行排序后,将结果转向存储至sorted.txt

利用转向输出做简易编辑
cat > out.sh
然后输入内容,编辑的内容就在保存在out.sh中,按ctrl+d

3.8 管道

基本型: 命令1 | 命令2

3.9 前台工作、后台工作

后台执行任务:
nuhup ./test.sh &

第四章 Bash Shell程序的结构

4.1 shell程序的组成

大体由:变量设定、内置命令、shell的语法结构、函数及其它命令行的程序所组成。

#! /bin/bash
# 用途: 这是一個简单的 shell 示范程式
#

function show_name() {
         echo "今个儿是 $1,您 $2 大大,来自 $3"
}

name="$1"
ip="163.26.197.1"
today=`date +%F`

if [ $# != 1 ]; then
   echo "Usage: ./$0 [使用者名称]"
   exit
fi

show_name "$today" "$name" "$ip"

sleep 5

echo
echo "Bye-Bye ;-)"

4.2 设定执行权限

chmod +x 文件名
或: chmod 755 文件名

4.3 执行bash script的方法

a: cd /root/tmp
./test.sh
b: /root/tmp/test.sh
c: cd /root/tmp
bash test.sh 或 sh test.sh
以前三种方法是在现在有shell(父shell)开启一下子shell
d: . /root/tmp/test.sh ( .和/之间,最少一个空格符)
source /root/tmp/test.sh
第四种方法,是在当前shell中运行

4.4 bash script排错的方法

检查script的语法
bash -v test.sh
不执行,仅查看script的程序代码
bash -n test.sh (我执行这条命令,什么也没有显示,)
追踪script的执行
bash -x test.sh
强制变量一定要经过声明才能使用
shopt -s -o nounset (这个不会用)
在特定位置摆放 echo 指令
用echo显示某些变量的内容,或加入暂停sleep 5,来观察输出画面。

4.5 bash script执行的原理

login shell
在/etc/passwd中设置
父shell和子shell
子shell再开启子shell
查看目前是位于第几层shell
echo $SHLVL

4.6 bash shell的启动配置文件

bash不同的运行模式
5种运行模式:互动模式、非互动模式(即执行script)、以sh名称调用、posix模式、限制功能模式。

登录(login)
login shell先执行/etc/profile,然后检查用户的主目录,检查是否有
.bash_profile 最优先
.bash_login 其次
.profile 最后
这三个文件中的其中之一
注销(logout)
bash检查主目录中 .bash_logout.若有,则读取并执行!

第五章 基本操作介绍

5.1 内置命令

file
help
用法: help 或 help 内置命令
help -s 内置命令:显示内置命令的语法格式。
echo
例:输出 hello world
echo hello world
echo "hello world"
echo ‘hello world’

: (冒号)
什么都不做,传回真值

:> test.txt
建立一个空文件test.txt

alisa
显示、设定程序别名
unalisa
取消程序别名
umask
显示或设定:文件、目录建立时,文件权限的屏蔽值
fc
列出登录主机之后、最近执行过的指令
set
设定bash shell 的属性
shopt
设定bash shell的行为模式
read
由标准输入读取一行数据
exec
执行指定的程序,取代原来的shell;或使转向操作生效。

5.2 命令行程序

file
which
由搜寻路径(PATH)中,找出某一命令行程序的文件位置
locate
由文件名数据库中,找出包含有“关键词”的文件路径
basename
取得路径名称中最后的文件名部分
dirname
取得路径名称中的目录部分
sort
对文本文件的每一行做排序
uniq
对已排序好的文件删除重复行
cat
对文件的每一行抽出某一部分
paste
对文件以行和行的方式合并
tr
转换或删除字符
tee
读取标准输入,然后由标准输出显示,并且把这些数据存储在指定的文件。
diff
比较两个文件之间的差异
xargs
由标准输入,安排要执行的命令和参数。

5.3 执行多个命令的方法

a : 用; (分号)隔开 ,各种指令都执行,但执行完之后,不保证执行过程都正确
b : 用 && 隔开,前一个命令执行成功,才会执行下一个
c : 用 || 隔开,前一个成功过,才会执行下一个。
d :把数个命令弄成一组,然后整组去执行!方法有二:
● (命令1;命令2;命令3;……) \在子shell中执行
● { 命令1;命令2;命令3;…… } \在现有shell中执行, 在 { 的右边和 }的左边,最少一空格。

5.4 记录命令的执行过程

Script工具(/usr/bin/script)

5.5 命令行编辑的方法

5.6 Bash分析命令行的方式

命令、选项、参数

第六章 变量与字符串操作

6.1 变量是什么

在bash中,只有一种数据形态:以字符组成的字符串。
设定变量值之后,该变量值只在当前shell环境中有效!

6.2 变量的命名

可使用:英文字母、数字及_(底线)组成。开头不能为数字。变量长度没有限制,但有英文字母大小写区别!

6.3 设定变量

变量名称=值
好的习惯:把字符串用双引号或单引号括起来。
注意:等号的两边,不可以有空格!
若等号右边的值有空格,则要用空格括起来。 错例:name=black jack 正例:name="black jack"

在脚本前面加上shopt -s -o nounset可以避免手误写错变量,-s:打开选项,nounset:变量一定要先设定过才能使用,否则会提示unbound variable

6.4 取得变量值

方法: $变量名称 或 ${变量名称}
注意:如果变量的后面有其它英数单词或下划线,须用{}隔开$和变量名称。
例: myname=jack
echo Hi, ${myname}Mmmm…
但如果后接的不是英数单词、不是下划线,刚不必使用{}隔开。(如果是中文的话,也可以不用{} )
例: dir2=sbin
echo /usr/local/$dir2/config
I=8
echo \$I
echo ‘$I’
显示结果均为:$I . ( \ 或” 会屏蔽掉 $ )

●printf "格式字符串"字符串或变量值

6.5 取消与清空变量

取消变量: unset
unset 名称 取消变量或函数(如果没有该名字的变量,才会取消函数)
unset -v 名称 取消的是变量
unset -f 名称 取消的是函数

清空变量
变量名称= (就是等于空)
清空变量是把变量的值清空!

6.6 变量和引号

双引号:
替换变量
替换命令执行结果
替换算术运算结果
单引号的作用:形成一个所见即所得的字符串(即写什么,就显示什么),不会进行任务的变量替换。

6.7 变量的有效范围

变量的作用范围,仅在各自的shell环境中才有效。

6.8 环境变量

当子shell产生时,会继承父shell的环境变量。
设置环境变量: export
例:test="hello"
export test

export test="hello"
另外: delclare -x test="hello"
作用和export一样!

取消环境变量值
a、用“=”把变量内容清空
b、unset 变量名

6.9 bash的内置变量

BASH :bash的完整路径名
BASH_ENV :仅在bash非互动模式中适用。如果值不为空的话,执行shell时,都会启动指定文件。
BASH_VERSION :bash的版本。
CDPATH :cd命令的搜寻路径;将该父目录设置为CDPATH, 执行linux cd命令进入子目录时无需再指定父目录路径
ENV : 互动模式下;如果ENV指定启动文件,则先执行那个文件。
EUID :有效的使用者id
FCEDITOR :fc命令默认使用的比较器
FIGNORE :在进行文件名补齐时,如若想忽略的扩展名列表,各文件名之间用:隔开
FUNCNAME :在函数式执行期,此变量内容即为函数式的名称
HOSTNAME :主机名
HOSTTYPE :主机形态。例如:i386
IFS :定义字段分隔字符。默认值为:空格、tab字符、换行字符。
MACHTYPE :描述主机形态的GUN格式:cpu-公司-系统
PATH :命令的搜寻路径
PPID :父进程的进程编号
RANDOM :随机函数
SECONDS :目前bash shell已执行的时间。(以秒为单位)

6.10 调整变量的属性

只读变量:使用readonly命令
用法: readonly 变量名称
其它用计:
执行readonly或readonly -p :显示目前只读属性的变量列表
readonly -f 函数名称 :设定该函数式不可修改
readonly -a 数组变量 :设定-a后接的变量名称是只读的数组。
只读变量:使用declare命令
用法:declare -r 变量名称

调整变量的属性
file

6.11 别名

建立别名
alias 别名=指令 (注意:1.等号两旁不可以有空白;2.如果等号右边的介绍信有空白,用单引号)

替换别名
取消别名
unalisa 别名
取消所有别名: unalias -a

6.12 自定义环境

6.13 数组

bash数组,元素个数没有限制,随时可以增加。
数组的索引由0开始,但不一定是连续的。索引也可以用算术表达式表示,如1+2
bash暂时只支持一维数组

数组的用法
欲显示或取得某一元素的值: ${数组[索引值]} 如:echo ${A[1]}
数组的建立:
常规方法:
A[0]=5
A[1]=10
A[2]=28
设定元素值,而不设置元素位置
B=(23 88 99 66) //B[0]=1;B[1]=88;B[2]=99;B[3]=66
只指定个别元素的索引
C=([3]=77 [1]=100 [5]=66)
指定某一元素的索引,其余交由系统接续
E=(124 [8]=188 266) //E[0]=124; E[8]=188; E[9]=266

取出数组所有的元素
echo ${B[@]} 结果显示:23 88 99 66

ehco ${B[]} 结果显示:23 88 99 66
区别:${B[@]} 得到4个以空白隔开的的数字。
${B[
]} 得到一整个字符串"23 88 99 66"

取得数组元素的个数
${#数组[@]} 或 ${#数组[*]}
例:echo ${#B[@]} 结果就会是4

取得数组某个元素的长度
${#数组[索引值]}

取消数组或数组元素
unset A 取消数组
unset A[3] 取消A数组的第4个元素

6.14 here document

基本语法:
命令 <<标记
……
……
标记

把命令和标记之间的内容,利用转向输入的方式交给该命令来处理。

标记可以是任何字符串,原则:尽量选不常用的字符组合,避免该字符串出现在输入的内容中造成bash误判。

支持变量替换

控制here document的格式

  • 关闭变量替换的功能 (下面的HERE加上单引号,即可关闭变量替换)
    cat <<'HERE'
    line 1 is good.
    they are jack, marry and john.
    $wow
    HERE
  • 去掉每行之前的TAB字符(<<后面加上- 就可去掉TAB字符)
    #!/bin/bash
    wow=hello
        cat <<- HERE
        line 1 is good.
        they are jack,marry and john.
        $wow
        here

    利用here document做多行批注
    bash只支持单行批注,即#
    here document 例:

    : <<   HERE
    这是第一行批注
    这是第二行批注
    这是第三行批注
    HERE

    ( : 代表“什么也不做”的空命令,在cript中,bash会忽略不执行,因为达到批注的结果)

利用here document,打包C(或其它程序语言)的原始码

#! /bin/bash

echo "正在生成 hello.c ...."
echo
cat <<'EOF' > hello.c
#include 

int main() {
    printf("Hello world!\n");
    return 0;
}
EOF

echo "编译 hello.c ...."
echo
# 编译 hello.c,产生执行文件
gcc -o hello hello.c

# 若编译成功,则执行
if [ $? -eq 0 ]; then
   echo "执行 hello ...."
   echo
   ./hello
else
   echo 'Compile ERROR: hello.c'
fi

第七章 高级变量(重点)

主要为以下三种:
基本型 扩展各类 范例
${变量名称} 变量扩展 ${filename}
$(命令) 命令替换 ${ls /}
$((算术式)) 算术扩展 $((9+9))

7.1 变量扩展:测试存在性及空值

变量扩展是一种简易的条件判断,对不同的条件赋予变量不同的替换值。

基本型是:${变量名称}
变量存在
变量值可以为“空”或“非空”
变量不存在
没有设置过变量,或unset取消变量,则称变量不存在或未定义

测试变量“存在与否”的基本用法 (测试!!)
语法:${待测变量-默认值}
若变量存在,传回变量的值;若变量不存在,刚传回默认值。

unset myname
r=${myname-'basher'}
echo $r
刚 r结果为:basher

myname=88
r=${myname-'basher'}
echo $r
刚 r结果为88
测试变量“不存在”或其值为空:“传回”一个默认值
语法:${待测变量:-默认值}
如果变量不存在或其值为空,刚“传回”默认值;反之,刚“传回”变量值。
小整理:
● 若变量扩展的条件式中只有-这个符号,刚只做变量"存在性"的判断
● 若变量扩展的条件式中使用:-这个符号,除了判断变量的"存在性"之外,也会多加一个判断,变量是否为空值。
● 多了冒号(:),表示要同时测试存在性及空值两种情况。
拆解条件表达式
${变量名称:-默认值}
可拆成
if [ 变量不存在 或 空值]; then
传回'默认值'
else
​传回'变量值'
fi
特殊运用法

[ -n ${debug:-} ] && set -v #如果debut不为空,刚执行set -v,即:script开启查错模式。如果debut为空或没有设定,刚不进入查错模式。

测试变量“不存在”或其值为空:给变量设一个默认值
语法:${待测变量:=默认值}
若变量不存在或其值为空,刚把变量设为“默认值”;如果变量存在,刚传回变量值!

测试变量是否“不存在”或其值为空:提示错误信息
语法: ${待测变量:?提示信息}
若变量不存在,或空值,刚显示变量名称和:?后面的提示信息,并立即停止执行script!

拆解
if [ 变量不存在 或 空 ]; then
显示变量名称: '提示信息'
exit
else
继续执行script的下一个命令
fi

用途:
确保某变量值一定要存在,否则若是继续执行下去,恐怕会发生严重后果。
例:

!/bin/bash

fn=${1:?'错误!请提供要删除的目录名称!'}

echo '你要执行删除目录的指令是:'
echo "rm -Rf ~/$fn"

测试变量的“存在性”​
语法:${待测变量:+真值} #这个真值可以为:非空字符串或数字
若变量存在且其值非空,刚传回“真值”;若不然,传回空值。
目的:用来测试某件事是真的(比如设置真值为true)。

file

7.2 变量扩展:取字符串切片、字符串长度

取字符串切片

字符串的第一个字符,编号为0,右邻的字符编号,依次增加1.如:“sheller”,字符s编号为0,r的编号为6
取字符串切片的方法:
● ${变量:位置起点} //由指定位置开始,获取子字符吕到字符串结束
例:
myname="sheller"
substr=${myname:4}
substr的结果为:ler
● ${变量:位置起点:长度} //指定位置开始,截取指定长度的子字符串
例:
filename="/etc/apache2"
dir=${filename:1:3}
dir的结果为:etc

取部分位置参数
命令行参数:
$0 就是脚本文件自身的名字, $1 是第一个参数, $2 是第二个参数, $3 是第三个参数, 然后是第
四个. [1] $9 之后的位置参数就必须用大括号括起来了, 比如, ${10} , ${11} , ${12} .
两个比较特殊的变量$*和$@ 表示所有的位置参数,$#表示参数的个数
像$0、$1、$2等变量,称为位置变量
取得部分位置参数的方法:
●${@:起点} //由起点开始,取得后面所有的位置参数
poz.sh

!/bin/bash

echo $0
echo ${@:2}

./poz.sh 88 77 66 22
结果:
./poz.sh
77 66 22

● #{@:起点:个数} //由起点开始,取得指定个数的位置参数。

计算字符串长度
语法:${#变量名称}
file

利用外部程序expr来做:
● expr length "字符串"
● expr "字符串":'.*'

7.3 变量扩展:对比样式

将符合样式的部分字符串删除或取代。


发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址