name="ni"
变量名
变量类型:bash默认把所有的变量都认为是字符串
bash变量是弱类型,无需事先声明类型,是将声明和赋值同时进行。?
[root@localhost ~]# name="ni"
[root@localhost ~]# echo ${name}
ni
[root@localhost ~]# cho $name ? #可以省略花括号ni?
单引号:不识别特殊符号
双引号:可以识别特殊符号?
反引号:会将命令的执行结果返回给变量
无引号:连续的符号可以不加引号,有空格则有歧义,最好使用双引号
本地变量,只针对当前的shell进程?
?pstree检查进程树
?
环境变量:也称为全局变量,针对当前shell以及其任意子进程,环境变量也分自定义、内置两种环境变量
局部变量:针对shell函数或是shell脚本中定义
位置参数变量:用于shell脚本中传递的参数。
特殊变量:shell内置的特殊功效变量
$?? ?:? 用于判断上一条命令是否执行成功
? ? ?0:成功
? ? ?1-255:错误码
自定义变量
? ? ? ? ? ? ? 双引号,会识别特殊符号
[root@localhost ~]# echo $name
ni
[root@localhost ~]# name2="$name"
[root@localhost ~]# echo $name2
ni?
?不同的执行方式,不同的shell环境
解答:
1.每次调用bash/sh都会开启一个子shell,因此不保留当前shell变量,通过pstree命令检查进程树
2.调用source是在当前shell环境加载脚本,因此保留变量。
环境变量一般指的是用export内置命令导出的变量,用于定义shell的运行环境、保证shell命令的正确执行。shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用。
环境变量可以在命令行中临死创建,但是用户退出shell终端,变量即丢失,如要永久生效,需要修改环境变量配置文件
? ?用户个人配置文件 ~/.bash_profile、~/.bashrc远程登录用户特有文件
? ?全局配置文件 /etc/profile、/etc/bashrc,且系统建议最好创建在/etc/profile.d/,而非直接修改主文件,修改全局配置文件,影响所有登录系统用户
reaonly name="ni"
?readonly:不能修改变量的值,只有shell结束,只读变量失效。
[root@localhost ~]# ls; cd /? #使用;号来分隔
shell的特殊变量,用在如脚本,函数传递参数使用,有如下特殊的,位置参数变量
$0? ? ? ? 获取shell脚本文件名,以及脚本路径
$n? ? ? ? 获取shell脚本的第n个参数,n在1-9之间,如$1,$2,$9,大于9则需要写,${10},? ? ? ? ? ? ? 参数空格隔开。?
$#? ? ? ? 获取执行的shell脚本后面的参数总个数
$*? ? ? ? 获取shell脚本所有参数,不加双引号等同于$@作用,加上引号"$*"作用是:接收所? ? ? ? ? ? ? ? 有参数为一个字符串(即所用参数都在一个字符串中)
$@? ? ? 不加引号,效果同上,加引号,是接收所有参数为独立字符串(一个参数是一个字? ? ? ? ? ? ? ? 符串),如"$1" "$2" "$3" ..., 空格保留
$?? ? ? ? 上次命令执行状态返回值,0正确,非0失败
$$? ? ? ? 当前shell脚本的进程号
$!? ? ? ? ?上一次后台进程的PID
$_? ? ? ? 再次之前执行的命令,最后一个参数?
echo
eval
exec
export
read
shift?
-n? ?不换行输出
-e? ?解析字符串中的特殊符号
\n? ?换行
\r? ? 回车
\t? ? ?制表符? 4个空格
\b? ? 退格
执行多个命令
[root@localhost ~]# eval cd /;ls
backup ?bin ?boot ?data ?dev ?etc ?home ?lib ?lib64 ?media ?mnt ?opt ?proc ?root ?run ?sbin ?srv ?sys ?tmp ?usr ?var
[root@localhost /]# ls
backup ?bin ?boot ?data ?dev ?etc ?home ?lib ?lib64 ?media ?mnt ?opt ?proc ?root ?run ?sbin ?srv ?sys ?tmp ?usr ?var?
不创建子进程,执行后续命令,且执行完毕后,自动exit。
[root@localhost ~]# read[选项][变量名]
选项
-p "提示信息“ | 在等待read输入时,输出提示信息 |
---|---|
-t 秒数 | read命令会一直等待用户输入,使用此选项可以制定等待时间 |
-n 字符数 | read命令值接受指定的字符数,就会执行 |
-s | 隐藏输入的数据,适用于机密信息的输入 |
#!/bin/bash
#Author: mlz
read -t 30 -p "Please input your name:" name
#提示“请输入姓名”并等待30秒,把用户的输入保存入变量name中
echo "Name is $name"
read -s -t 30 -p "Please enter your ege: " age
#年龄是隐私,所以我们用“-s”选项隐藏输入
echo "Age is $age"
echo -e "\n"
read -n 1 -t 30 -p "Please select your gender[M/F]: " gender
#使用“-n l”选项只接收一个输入字符就会执行(都不用输入回车)
echo -e "\n"
echo "Sex is $gender"
${变量}? ? ? ? ? ? ?返回变量值
${#name}? ? ? ? ?返回变量长度,相当于java中的String.length()方法
${变量:start}? ? ?返回变量start数值之后的字符串,且包含start的数字(下标从0开始,类似于? ? ? ? ? ? ? ? ? ? ? ? ? ?java中的substring()方法)?
${变量:start:length}? ?返回变量start数值之后的字符串直到这个字符串长度等于length,且包? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 含start的数字(下标从0开始,类似于ava中的substring()方法) .
${变量#word}? ? ? 从变量前缀删除最短匹配的word子串
${变量##word}? ? 从变量前缀删除最长匹配的word子串
${变量%word}? ? ? 从变量结尾删除最短匹配的word子串
${变量%%word}? ? 从变量结尾删除最长匹配的word子串
${变量/pattern/string}? ? 用string代替第一个匹配的pattern
${变量//pattern/string}? ?用string代替所有的pattern
[root@localhost /]# name=abcAHHIOac
[root@localhost /]# echo $name
abcAHHIOac
[root@localhost /]# echo ${name#a*c}
AHHIOac
[root@localhost /]# echo ${name##a*c}
[root@localhost /]#
这4个扩展变量,都属于对变量的值进行判断、处理
如果parameter变量值为空,返回word字符串,赋值给result变量(即将word的值返回给result),如果不为空则把parameter赋值给result
result=${parameter:-word}
如果parameter变量为空,则word代替变量值,且返回其值。(即word值赋给parameter,然后将word的值返回给result),如果不为空则把parameter赋值给result
result=${parameter:=word}
如果parameter变量为空,word当作stder输出,否则输出变量值
用于设置变量为空导致错误时,返回的错误信息
${parameter:?word}
如果parameter变量为空,什么都不做,否则Word返回
${parameter:+word}
${变量}? ? ? ?取出变量结果
$()? ? ? ? ? ? ? ?在括号中执行命令,且拿到命令的执行结果。
``? ? ? ? ? ? ? ? ?在括号中执行命令,且拿到命令的执行结果。
()? ? ? ? ? ? ? ? 开启子shell执行命令结果
$变量? ? ? ? ??取出变量结果
expr命令也支持模式匹配功能
2个特殊符号
:冒号,计算字符串的字符数量
.*? 任意的字符重复0次或者多次。
语法
expr 字符串 ":" ".*"
求长度:expr length
expr计算用于整数,有些运算符需要转译?
xufan@cengdongdeiMac Documents % expr 3 \* 2
6
xufan@cengdongdeiMac Documents % expr 3 + 2
5
执行脚本,传入一个文件名,然后判断该文件是否是jpg图片文件。?
#!/bin/bash
#从参数1中匹配一个字符串以.jpg结尾,并返回匹配上的字符串的长度,并且将输出写入到黑洞文件中
if expr "$1" ":" ".*\.jpg" &> /dev/null
then
echo "这的确是以jpg结尾的文件~"
else
echo "这不是jpg文件"
fi
bc命令当做计算器来用的,命令行的计算器
把计算式子通过管道符传给bc命令
xufan@cengdongdeiMac Documents % re=`echo "$num*3" | bc`
xufan@cengdongdeiMac Documents % echo $re
9
awk既支持整数也支持小数计算
awk支持if条件判断,数组等等
xufan@cengdongdeiMac Documents % echo "3.2 2.2" | awk '{print $1+$2}'
5.4
?注意:
当你使用?
echo "3.2 2.2" | awk '{print $1+$2}'
?这个命令时,你实际上是将字符串 "3.2 2.2" 传递给?awk
?命令来处理。在这个上下文中,单引号和双引号的使用是有特定的意义的。
- 双引号 (" "): 在双引号内的内容会被 shell 解释,这意味着其中的变量和特殊字符(如?
$
)会被扩展或解释。- 单引号 (' '): 在单引号内的内容不会被 shell 解释,而是被当作纯文本。
在你给出的命令中,
awk
?命令是用单引号包围的,这意味着其中的内容({print $1+$2}
)会被?awk
?解释,而不是 shell。这个?awk
?脚本的意思是:取第一列($1
,即 "3.2")和第二列($2
,即 "2.2"),然后将它们相加。如果你使用双引号来包围?
awk
?命令,如?awk "{print $1+$2}"
,这可能会导致问题,因为 shell 会尝试解释?$1
?和?$2
,而在这个上下文中,它们并没有定义。所以,为了避免这种解释,我们通常使用单引号来包围?awk
?的脚本部分。总之,单引号在这里确保?
awk
?脚本被正确地传递给?awk
?命令,而不是被 shell 提前解释。
$[运算式]
xufan@cengdongdeiMac Documents % echo $[4*2]
8
条件测试常用的语法
test命令评估一个表达式,他的结果是真,还是假,如果条件为真,那么命令执行状态码结果就为0,否则就是不为0,通过$?取值
语法
. 关于某个文件名的「类型」侦测(存在与否),如test -e filename
1.针对文件类型判断真假
2.关于文件的权限侦测,如 test -r filename?
3.两个文件之间的比较, 如:test file1 -nt file2
4.关于两个整数之间的判定,例如 test n1 -eq n2?
5.判断字符串的数据
6.多重条件判定,例如:test -r filename -a -x filename
在shell中,对于真假判断的逻辑,提供&& 与运算? ||或运算
A条件 && B条件:当A条件成立,并且执行B条件
A条件||B条件:当A条件不成立的时候,才会执行B条件。
脚本中经常进行条件测试,用的最多的,都是中括号[ ]
test和[ ]的作用是一样
注意的点:
1.中括号,前后的空格必须有
2.在条件测试中取变量必须添加双引号
[ -f "$filename" ]
- 字符串比较:在单中括号中,字符串比较使用
=
和!=
,而在双中括号中,字符串比较也支持其他操作符,如-eq
,?-ne
,?-gt
,?-lt
,?-ge
,?-le
等。- 模式匹配:双中括号允许使用正则表达式进行模式匹配,而单中括号不支持。
- 扩展性:双中括号会对shell元字符进行扩展,而单中括号不会。这意味着在双中括号中,如果字符串值含有shell元字符,Bash会对它进行扩展。(像在双中括号中就不需要对>、<等符号j进行转译)
- 变量扩展:单中括号的TEST命令会对变量进行单词分离,当变量值包含空白符时,要用引号将变量括起来。而双括号的TEST命令不会对变量进行单词分离。
单分支if
if? <条件表达式>
? ?then
? ? ? ?代码...
fi
简化
if? <条件表达式>;then
? ? 代码..
fi?