一、shell简介
Shell的作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行一条,这种方式称为交互式(Interactive),Shell还有一种执行命令的方式称为批处理(Batch),用户事先写一 个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲 命令。Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需 要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一 行敲到Shell提示符下执行。
二、shell执行脚本
代码:
#!/bin/bash
echo "this is a joy"
cd ..
ls</span>
#!/bin/bash
echo "this is a joy"
cd ..
ls</span>
Shell脚本中用#表示注释,相当于C语言的//注释。但如果#位于第一行开头,并且是则例外,它表示该脚本使用后面指定的解释器/bin/sh解释执行。
运行:
[root@www admin]# bash script.sh // 指定解释器 bash
this is a joy
admin
[root@www admin]# /bin/bash script.sh // /bin/bash
this is a joy
admin
[root@www admin]# sh script.sh // sh
this is a joy
admin
[root@www admin]# /bin/sh script.sh // /bin/sh
this is a joy
admin
[root@www admin]# chmod +x script.sh //增加可执行权限
[root@www admin]# ./script.sh
this is a joy
admin
//增加可执行权限的执行过程:
//bash 方法的shell执行过程:
1. 交互Shell(bash)fork/exec一个子Shell(sh)用于执行脚本,父进程bash等待子进程sh终 止。
2. sh读取脚本中的cd ..命令,调用相应的函数执行内建命令,改变当前工作目录为上一级目 录。
3. sh读取脚本中的ls命令,fork/exec这个程序,列出当前工作目录下的文件,sh等待ls终止。
4. ls终止后,sh继续执行,读到脚本文件末尾,sh终止。
5. sh终止后,bash继续执行,打印提示符等待用户输入。
2. sh读取脚本中的cd ..命令,调用相应的函数执行内建命令,改变当前工作目录为上一级目 录。
3. sh读取脚本中的ls命令,fork/exec这个程序,列出当前工作目录下的文件,sh等待ls终止。
4. ls终止后,sh继续执行,读到脚本文件末尾,sh终止。
5. sh终止后,bash继续执行,打印提示符等待用户输入。
注意:如果将命令行下输入的命令用()括号括起来,那么也会fork出一个子Shell执行小括号中的命令,一 行中可以输入由分号
[root@www admin]# (cd ..;ls)
admin
[root@www admin]# (cd ..) //目录没有变化,fork出来一个子进程
[root@www admin]# cd .. //执行目录跳到上一级,直接在shell下执行,改变了shell的pwd
[root@www home]#
[root@www admin]# . ./script.sh //直接在shell下执行,改变了shell的pwd
this is a joy
admin
[root@www home]# ls
admin
[root@www home]# cd admin
[root@www admin]# source ./script.sh //直接在shell下执行,改变了shell的pwd
this is a joy
admin
[root@www home]#
三、shell变量
环境变量
环境变量可以从父进程传给子进程,因此Shell进程的环境变量 可以从当前Shell进程传给fork出来的子进程。用printenv命令可以显示当前Shell进程的环境 变量。
本地变量
只存在于当前Shell进程,用set命令可以显示当前Shell进程中定义的所有变量(包括本地变 量和环境变量)和函数。环境变量是任何进程都有的概念,而本地变量是Shell特有的概念
[root@www admin]# export COUNT=10 //一个变量定义后只存在当前进程,export将本地变量导出到环境变量中
[root@www admin]# COUNT=10 //分两步导出 (等号两边不能有空格,否则被shell解释成命令和命令行参数)
[root@www admin]# export COUNT
[root@www admin]# printenv COUNT
10
[root@www admin]# unset COUNT //删除已经定义的本地变量或者环境变量
[root@www admin]# printenv COUNT
[root@www admin]#
变量的引用
Shell变量的值都是字符串,不需要明确定义
Shell变量不需要先定义后使用,如果对一个没有定义的变量取值,则值为空字符串
[root@www admin]# COUNT=10
[root@www admin]# echo $COUNT // $COUNT,${COUNT}表示它的值。
10
[root@www admin]# echo $COUNTabc //打印不出来,被识别成COUNTabc变量,该变量不存在
[root@www admin]# echo ${COUNT}abc //可以打印出来
10abc
[root@www admin]# echo ${COUNT}
10</span></strong>
四、文件名代换和命令代换
文件代换:
通配符: * ? []
Globbing所匹配的文件名是由Shell展开的,也就是说在参数还没传给程序之前已经展开了,比如传给ls命令的参数实际 上是这两个文件名,而不是一个匹配字符串。
[root@www SHELL]# touch test.s
[root@www SHELL]# touch teat.c
[root@www SHELL]# touch tebt.c
[root@www SHELL]# touch tect.c
[root@www SHELL]# ls te*t.c // *匹配0个或多个任意字符
teat.c tebt.c tect.c
[root@www SHELL]# ls te?t.c // ?匹配一个任意字符
teat.c tebt.c tect.c
[root@www SHELL]# touch tesat.c
[root@www SHELL]# ls te*
teat.c tebt.c tect.c tesat.c test.s
[root@www SHELL]# ls te?t.c
teat.c tebt.c tect.c
[root@www SHELL]# ls te[sab]t.c //[若干字符] : 匹配方括号中任意一个字符的一次出现
teat.c tebt.c
[root@www SHELL]# ls te[sab]t.c
teat.c tebt.c
[root@www SHELL]# touch test.c
[root@www SHELL]# ls
teat.c tebt.c tect.c tesat.c test.c test.s
[root@www SHELL]# ls te[sab]t.c
teat.c tebt.c test.c
命令代换:$() , ` ` , $(())
[root@www SHELL]# DATE=`date` // 反引号括起来的是个命令,shell先执行该命令,然后将结果替换到当前命令行上。
[root@www SHELL]# echo $DATE
2016年 06月 12日 星期日 05:49:25 PDT
[root@www SHELL]# DATE=$(date) // $()替换命令
[root@www SHELL]# echo $DATE
2016年 06月 12日 星期日 05:50:24 PDT
[root@www SHELL]# VAR=10
[root@www SHELL]# echo $(($VAR+3)) // $(())中的Shell变量取值将转换成整数,并且只能用于四则运算和整数</span>
13
[root@www SHELL]# echo `echo \$HOSTNAME`
www.sn.10086.cn
[root@www SHELL]# echo $(echo \$HOSTNAME)
$HOSTNAME
[root@www SHELL]# echo $(echo \\$HOSTNAME)
\www.sn.10086.cn
[root@www SHELL]# echo `echo \\$HOSTNAME`
$HOSTNAME
[root@www SHELL]# echo `echo \\\$HOSTNAME`
$HOSTNAME
[root@www SHELL]# echo $(echo \\\$HOSTNAME)
\$HOSTNAME
[root@www SHELL]# echo $(echo \\\\$HOSTNAME)
\\www.sn.10086.cn
-
反引号本身就对\进行了转义,保留了本身意思,如果我们想在反引号中起到\的特殊意义,我们必须使用2个\来进行表示。
所以我们可以简单的想象成反引号中: \\ = \
-
$()中则不需要考虑\的问题,与我们平常使用的一样:\ = \
五、转义字符
\在Shell中被用作转义字符
[root@www SHELL]# touch $\ $ //创建$ $文件
[root@www SHELL]# touch -- -file //创建-file文件
[root单引号⽤用于保持引号内所有字符的字⾯面值,即使引号内的\和回车也不
例外, 但是字符串中不能出现单引号@www SHELL]# rm -- -file
rm:是否删除普通空文件 "-file"?y
[root@www SHELL]# ls
$ $双引号⽤用于保持引号内所有字符的字⾯面值(回车也不例外),但以下情况除外:
[root@www SHELL]# touch ./-file //创建-file文件
[root@www SHELL]# ls
$ $ -file
[root@www SHELL]# ls \
> -l
总用量 0
-rw-r--r--. 1 root root 0 6月 12 06:02 $ $
-rw-r--r--. 1 root root 0 6月 12 06:03 -file
六、单引号、双引号
单引号用于保持引号内所有字符的字面值,即使引号内的\和回车也不例外, 但是字符串中不能出现单引号。
双引号用于保持引号内所有字符的字面值(回车也不例外),但以下情况除外:
$加变量名可以取变量的值
反引号仍表示命令替换
\$表示$的字面值
\`表示`的字面值
\"表示"的字面值
\\表示\的字面值 除以上情况之外,在其它字符前面的\无特殊含义,只表示字面值
反引号仍表示命令替换
\$表示$的字面值
\`表示`的字面值
\"表示"的字面值
\\表示\的字面值 除以上情况之外,在其它字符前面的\无特殊含义,只表示字面值
[root@www SHELL]# echo ${COUNT}
10
[root@www SHELL]# echo '$COUNT'
$COUNT
[root@www SHELL]# echo "$COUNT"
10