shell基础总结二
PATH变量
PATH变量的值是用":"分隔的路径,这些路径就是系统查找命令的路径。也就是说,输入一个程序名,如果没有写入路径,系统就会到PATH变量定义的路径中去寻找是否有可以执行的程序,如果找到则执行,否则会报“找不到命令”的错误。
只要把程序脚本复制到PATH变量定义的任意路径中,比如/bin/目录下,以后这个脚本就可以直接执行了,不用再指定绝对路径或相对路径。
也可以使用变量叠加的方式实现:
PATH="$PATH":/root/sh
这样定义的PATH变量只能临时生效,一旦重启或注销系统就会消失。如果想要永久生效,则需要写入环境变量配置文件。
PS1是一个很有意思的变量,是用来定义命令行的提示符的,可以按照需求来定义提示符。
常用选项:
\d:显示日期,格式为"星期 月 日"
\H:显示完整的主机名
\h:显示简写的主机名
\t:显示24小时制时间
\T:显示12小时制时间
\u:显示当前用户名
\v:显示Bash的版本信息
\w:显示当前所在目录的完整名称
\W:显示当前所在目录的最后一个目录
\#:执行的第几条命令
\$:提示符。root用户为“#”,普通用户为“$”
查看PS1变量的默认值:echo $PS1
如何设置:PS1='[\u@\t \w]\$' #修改提示符为'[用户名@当前时间当前所在完整目录]提示符'
LANG变量定义了Linux系统的主语系环境,这个变量的默认值如下:
echo $LANG
查询Linux系统中支持多少种语系:locale -a | more #详细 locale -a | wc -l #汇总
通过文件 /etc/sysconfig/i18n 定义系统的默认语系,查看一下这个文件的内容,如下:
[root@localhost src]# cat /etc/sysconfig/i18n
LANG="zh_CN.UTF-8"
在Linux的命令行中,当一条命令或脚本执行时,后面可以跟多个参数,可以使用位置参数变量来表示这些参数。
$0代表命令行本身,$1代表第1个参数,$2代表第2个参数,以此类推。当参数个数超过10个时,就要用大括号把这个数字括起来,例如${10}代表第10个参数。
$n:n为数字,$0代表命令本身,$1~$9代表第1~9个参数,10以上的参数需要用大括号包含,如${10}
$*:这个变量代表命令行中所有的参数,把所有的参数看成一个整体
$@:这个变量也代表命令行中所有的参数,不过$@把每个参数区别对待
$#:这个变量代表命令行中所有参数的个数
位置参数变量要用于向命令或程序脚本中传递信息,比如,我们想要写一个计算器,要告诉程序应该运算哪个字符,这时就需要通过位置参数变量向脚本中传递数值,命令如下:
# vi count.sh
#!/bin/bash
num1=$1
#给num1变量赋值是第一个参数
num2=$2
#给num2变量赋值是第二个参数
sum=$(($num1 + $num2))
#变量sum的和是num1加num2
echo $sum
#打印变量sum的值
在 Shell 中,数值运算是必须使用特殊格式的(后续章节会做详细介绍),这里大家先照着例子操作。 执行一下此脚本:
# chmod 755 count.sh
#给脚本文件赋予执行权限
#./count.sh 11 22
33
#这个脚本就会把第一个参数和第二个参数相加
还有几个位置参数变量是干什么的呢?请看如下脚本:
# vi parameter.sh
#!/bin/bash
echo "A total of $# parameters"
#使用$#代表所有参数的个数
echo 'The parameters is: $*"
#使用$*代表所有的参数
echo 'The parameters is: $@"
#使用$@也代表所有的参数
执行此脚本:
# chmod 755 parameter.sh
#./parameter.sh 11 22 33
A total of 3 parameters
#因为输入了三个参数,所以$#显示的值是3
The parameters is: 11 22 33
#输出了所有参数
The parameters is: 11 22 33
#也输出了所有参数
那么"$*"和"$@"有区别吗?还是有区别的,$* 会把接收到的所有参数当成一个整体对待,而 $@ 则会区别对待接收到的所有参数。还是举个例子吧:
# vi parameter2.sh
#!/bin/bash
for i in "$*"
#定义for循环,in后面有几个值,for就会循环多少次,注意"$*"要用双引号括起来
#每次循环都会把in后面的值赋予变量i
#Shell把“$*”中的所有参数看成一个整体,所以这个for循环只会循环一次
do
echo "The parameters is: $i"
#打印变量$i的值
done
x=0
#定义变量x的值为0
for y in "$@"
#同样,in后面有几个值,for就会循环几次,每次都把值赋予变量y
#因为Shell会把“$@”中的每个参数都看成独立的,所以“$@”中有几个参数,就会循环几次
do
echo "The parameter$x is: $y"
#输出变量y的值
x=$(( $x +1 ))
#让变量x每次循环都加1 ,是为了输出时看得更清楚
done
echo "x is: $x"
执行一下这个脚本:
# chmod 755 parameter2.sh
#./parameter2.sh 11 22 33
The parameters is: 11 22 33
#这是第一个for的结果,"$*"被看作一个整体,所以只会循环一次
The parameter1 is: 11
The parameter2 is: 22
The parameter3 is: 33
#这是第二个for的结果,“$@”中的每个变量被区别对待,所以会循环三次
x is:3
#x的值是 3,证明循环了三次
预定义变量是在shell一开始就定义的变量,这一点和默认环境变量有些类似。不同的是,预定义变量不能重新定义,用户只能根据shell的定义来使用这些变量
严格来说,位置参数变量也是预定义变量的一种,知识位置参数变量的作用比较统一,所以我们把位置参数变量单独划分为一类数量。
$?:最后一次执行的命令的返回状态。如果这个变量的值为0,则证明上一条命令正确执行;如果这个变量的值为非0(具体是哪个数由命令自己来决定),则证明上一条命令执行错误
$$:当前进程的进程号(PID)
$!:后台运行的最后一个进程的进程号(PID)
先看看"$?"这个变量:
# ls #ls命令正确执行
a.sh cest.sh hockey
# echo $?
0 #预定义变量"$?"的值是0,证明上一条命令正确执行
# ls ceshi.log #使用ls命令查看一个没有的.log文件
ls: cannot access ceshi.log: No such file or directory
# echo $?
2 #变量"$?"返回一个非0的值,证明上一条命令没有正确执行
#至于错误的返回值到底是多少,是在编写ls命令时定义好的,如果碰到文件不存在就返回数值2
通过脚本学习"$$"和"$!"这两个预定义变量:
#vi variable.sh
#!/bin/bash
echo "The current process is $$"
#输出当前进程的PID
#这个PID就是varable.sh脚本执行时生成的进程的PID
find /root -name hello.sh &
#使用find命令在/root目录下查找hello.sh文件
#符号"&"的意思是把命令放入后台执行
echo "The last one Daemon process is $!"
#输出这个后台执行命令的进程的PID,也就是输出find命令的PID
执行这个命令:
#chmod a+x variable.sh #赋予执行权限
#./variable.sh
The current process is 1713 #脚本variable执行时,PID是1713
The last one Daemon process is 1714 #find命令执行时,PID是1714
注意,无论是脚本variable.sh,还是find命令,一旦执行完毕就会停止,所以使用ps命令数查看不到这两个进程号的
read命令可以向脚本中传入数据,read命令接收标准输入(键盘)的输入,或者其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。
read命令格式如下:read [选项] [变量名]
选项:
-p "提示信息":在等待read输入时,输出提示信息
-t 秒数:read命令会一直等待用户输入,使用此选项可以指定等待时间
-n 字符数:read命令只接收指定的字符数就会执行
-s:隐藏输入的数据,适用于机密信息的输入
变量名:
变量名可以自定义。如果不指定变量名,则会把输入保存到默认变量REPLY中
如果只提供了一个变量名,则将整个输入行赋予该变量
如果提供了一个以上的变量名,则输入行分为若干字,一个接一个地赋予各个变量,而命令行上的最后一个变量取得剩余的所有字
#vi read.sh
#!/bin/bash
read -t 30 -p "Please input your name:" name
#提示"请输入姓名"并等待30秒,把用户的输入保存到变量name中
echo "Name is $name"
#看看变量"$name"中是否保存了你的输入
read -s -t 30 -p "Please enter your age:" age
#提示"请输入年龄"并等待30秒,把用户的输入保存到变量age中
#年龄是隐私,所以我们用"-s"选项隐藏输入
echo -e "n"
#调整输出格式,如果不输出换行,则一会儿的年龄输出不会换行
echo "Age is $age"
read -n 1 -t 30 -p "Please select your gender[M/F]:" gender
#提示"请选择性别"并等待30秒,把用户的输入保存到变量gender中
#使用"-n 1"选项只接收一个输入字符就会执行(无须按回车键)
echo -e "\n"
echo "Sex is $gender"
执行脚本:
# sh read.sh
Please input your name:ceshi #在read的提示界面输入姓名
Name is ceshi #"$name"变量中保存了我们的输入
Please enter your age:n #因为加入了"-s"选项,所以输入不会显示在命令行上
Age is 18 #"$age"变量中保存了我们的输入
Please select your gender[M/F]:M #因为加入了"-n 1"选项,所以只能输入一个字符
Sex is M # "$gender"变量中保存了我们的输入
read命令并不难,却是接收键盘输入的重要方法,要熟练使用
shell编程和其他语言还是有很多不一样的地方,在shell中所有的变量默认都是“字符串型”。也就是说,如果不手工指定变量的类型,那么所有的数值都是不能进行运算的。
# aa=11
# bb=22 #给变量aa和bb赋值
# cc=$aa+$bb #变量cc的值是aa和bb的和
# echo $cc
11+22 #但是cc的值却是"11+22"这个字符串,并没有进行数值运算
如果需要进行数值运算,则可以采用以下三种方法中的任意一种。
使用declare声明变量类型
既然所有变量的默认类型是字符串型,那么只要把变量声明为整数型不就可以参与运算了吗?使用declare命令就可以声明变量的类型