Shell编程(二)

变量和运算符

什么是shell变量?本地变量,环境变量,变量替换(显示变量),位置变量,标准变量,特殊变量,影响变量的命令。
 什么是shell的变量?
 为使用shell编程更加有效,系统提供了一些shell变量。shell变量可以保存注诸如路径名、文件名、或者数字这样的变量。从这一点上看,shell编程中,变量至关重要。
 eg: echo $myVar1

一、本地变量

 本地变量在用户现有的shell生命期的脚本中使用。
variablename=value
 定义本地变量:MYVAR=”test” 注意=左右不要有空格
 使用本地变量$MYVAR echo $MYVAR or echo ${MYVAR}
 set显示本地所有的变量
 readonly variablename
 readonly myvar1=”test2” ;myvar1=”test2”;bash会报错误

echo $MYV 每登录一个终端,都会运行一个shell程序,这个本地变量,就保存在这个shell程序中;如果再新登录,将启动新的shell程序,与原来的shell不同。建立起概念。

二、 环境变量

 环境变量用于所有用户进程(经常称为子进程)。登录进程称为父进程。shell中执行的用户进程均成为子进程。不像本地变量(只用于现在的shell),环境变量可用于所有子进程,这包括编辑器、脚本和应用程序。
 $HOME/.bash_profile (/etc/profile,所有用户都使用的profile)
 export 声明环境变量 export myvar=”tttt” 查看环境变量
 env 查看新增加的环境变量,

三、 变量替换(显示变量)

 用变量的值替换它的名字
 echo
 在变量名前加$,使用echo命令可以显示单个变量取值。
echo ${MYVAR} 或者echo $MYVAR

$(variablename)  显示实际值
$(variablename:+value)  若设置了variablename,则显示;否则空
$(variablename:?value)  若未设置variablename,则显示用户自定义信息valude
$(variablename:-value)  若未设置variablename,则显示其值
$(variablename:=value)  若未设置了variablename,则设置其值,并显示

四、unset 清除变量

 unset testvar ; 测试 echo $testvar;
 readonly的变量,不能被清除

五、位置变量

 位置变量表示 0 1 2 3 …$9

$0 代表bash文件名称 其他就是命令行参数
./02param a b c 

#!/bin/bash
#param
echo "脚本的名字 $0"
echo "parm 1: $1
echo "parm 2: $2"
echo "parm 3: $3"
#!/bin/bash
#param.sh
find /usr/lib/ -name $1 –print  查找目录下文件名是第一个参数的文件

六、标准变量

有一些预留的环境变量名,这些变量名不能用作其他用途。通常在/etc/profile中建立这些嵌入的环境变量,但也不完全是,这取决于用户自己。以下是嵌入shell变量列表。
1. CDPATH
改变目录路径变量,保留一系列由冒号隔开的路径名,用于cd命令。如果设置了CDPATH,cd一个目录时,首先查找CDPATH,如果CDPATH指明此目录,则此目录成为当前工作目录。例子如下:

$ CDPATH=:/home/dave/bin:/usr/local/apps ;export CDPATH.

如果要$ cd apps cd命令首先在CDPATH中查找目录列表,如果发现apps,则它成为当前工作目录。
2. EXINIT
EXINIT变量保存使用vi编 辑器时的初始化选项。例如,调用vi时,要显示行号,且在第10个空格加入tab键,命令为:$ EXINIT='set nu tab=10';export EXINIT
3. HOME
HOME目录,通常定位于passwd文件的倒数第2列,用于保存用户自身文件。设置了HOME目录,可以简单使用cd命令进入它。也可以用$ cd $HOME
4. IFS
IFS用作shell指定的缺省域分隔符。原理上讲域分隔符可以是任意字符,但缺省通常为空格、新行或tab键。IFS在分隔文件或变量中各域时很有用。下面的例子将IFS设置为冒号,然后echo $PATH变量,给出一个目录分隔开来的可读性很强的路径列表。/sbin /bin /usr/bin /home/dave/bin
要设置其返回初始设置:

$ IFS=<space><tab>; export IFS

这里为空格和tab键。
5. LOGNAME
此变量保存登录名,应该为缺省设置,但如果没有设置,可使用下面命令完成它:$ LOGNAME='dave'; export LOGNAME

6. MAIL
MAIL变量保存邮箱路径名,缺省为/var/spool/mail/<loginname>。shell周期性检查新邮件,如果有了新邮件,在命令行会出现一个提示信息。如果邮箱并不在以上指定位置,可以用MAIL设置。$ MAIL=/usr/mail/dave ;export MAIL
7. MAILCHECK
MAILCHECK缺省每60s检查新邮件,但如果不想如此频繁检查新邮件,比如设为每2m,使用命令:$ MAILCHECK=120 ;export MAILCHECK
8. MAILPATH
如果有多个邮箱要用到MAILPATH,此变量设置将覆盖MAIL设置。
$ MAILPATH=/var/spool/dave:/var/spool/admin ;export MAILPATH
上面的例子中,MAIL检测邮箱dave和admin。
9. PATH
PATH变量保存进行命令或脚本查找的目录顺序,正确排列这个次序很重要,可以在执行命令时节省时间。你一定不想在已知命令不存在的目录下去查找它。通常情况,最好首先放在HOME目录下,接下来是从最常用到一般使用到不常用的目录列表次序。如果要在当前工作目录下查询,无论在哪儿,均可以使用句点操作。目录间用冒号分隔,例如:

$ PATH=$HOME/bin:.:/bin:/usr/bin ;export PATH

使用上面的例子首先查找HOME/bin目录,然后是当前工作目录,然后是/bin,最后是/usr/bin。
PATH可以在系统目录下/etc/profile中设置,也可以使用下面方法加入自己的查找目录。

$PATH=$PATH:/$HOME/bin:.;export PATH

这里使用了/etc/profile中定义的PATH,并加入$HOME/bin和当前工作目录。一般来说,在查找路径开始使用当前工作目录不是一个好办法,这样很容易被其他用户发现。
10. PS1
基本提示符包含shell提示符,缺省对超级用户为#,其他为$。可以使用任何符号作提示符.

echo $PS1

 PS1=’[\u@\h \w] $’ u代表用户名 h主机名 w代表当前目录
 可以自己更改PS1 比如: PS1=”wangbaoming”
11. PS2
PS2为附属提示符,缺省为符号>。PS2用于执行多行命令或超过一行的一个命令。
12. SHELL
SHELL变量保存缺省shell,通常在/etc/passwd中已设置,但是如有必要使用另一个shell,
可以用如下方法覆盖当前shell:
13. TERMINFO
终端初始化变量保存终端配置文件的位置。通常在/usr/lib/terminfo或/usr/share/terminfo

$ TERMINFO=/usr/lib/terminfo ;export TERMINFO
14. TERM
TERM变量保存终端类型。设置TERM使应用获知终端对屏幕和键盘响应的控制序列类型,常用的有vt100、vt200、vt220-8等。`
$ TERM=vt100 ;export TERM

15. TZ
时区变量保存时区值,只有系统管理员才可以更改此设置。例如:

$echo $TZ
GMT2EDT

返回值表明正在使用格林威治标准时间,与GMT时差为2,并作EDT保存。

七、特殊变量

$# 传递到脚本的参数个数
   $* 以一个单字串显示所有向脚步传递的参数,与位置变量不同,次选项参数可以超过9个。
   $$    脚步运行的当前进程ID号
   $! 后台运行的最后一个进程的进程ID$@$#相同,但是使用时加引号,并在引号中返回每个参数
   $- 显示shell使用的当前选项,与set命令功能相同 
   $? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误
#!/bin/bash
#param

echo "脚本的名字 $0"
echo "parm 1: $1"

echo "parm 2: $2"
echo "parm 3: $3"
echo "parm 4: $4"
echo "parm 5: $5"
echo "显示参数的个数:$#"

echo "显示脚本全部参数:$*"
echo "显示前一命令运行后状态:$?" 

引号

简介:引号的必要性、双引号、单引号、反引号、反斜杠
 引号的必要性
 变量和替换操作,在脚本中执行变量替换时,最容易犯的一个错误就是引号的错误。
 例如:echo aa.tar.gz * ; echo “aa.tar.gz *” 效果大不一样
 双引号 使用双引号可以引用除字符$,反引号,反斜杠外的任意字符或者字符串。
echo -e " hello world, $SHELL '\n* wangbaoming 'echo $myvar' "
 单引号 单引号与双引号类似,不同的是shell会忽略任何引用值。换句话说,如果屏蔽了其特殊含义,会将引号里的所有字符,包括引号都作为一个字符。
 echo -e ’ hello world, $SHELL ‘\n* wangbaoming ’
 结论:单引号让特殊字符失去意义。

 反引号 反引号用于设置系统命令的输出到变量。shell将反引号中的内容作为一个系统命令,并执行其内容。
 eg:echo “* wangbaoming echo $PATH
 反斜杠
 如果一个字符有特殊含义,反斜杠防止shell误解其含义,即:屏蔽其特殊含义。
 下属字符含有特殊含义:$ * + ^ ` ‘’ | ?
 eg:echo * echo *

运算符

表达式类型
 按位运算符

~op1 反运算符
op1<<op2    左移运算符
op1>>op2    右移运算符
op1 & op2   与比较运算符 
op1 ^ op2   异或运算符
op1 | op2   或运算符
eg: echo $[2<<4]  echo $[2^4]
$[ ] 表示形式告诉shell对方括号中的表达式求值
eg: echo $[3+9] 

 逻辑运算符

&& 逻辑与运算
|| 逻辑或运算符 echo $[1||1]

 赋值运算符、
+=,-=,*=,/=,%=,&=,^=、|=,<<=,>>=

let count = $count + $change
let count += $change
[wbm@wmblinux64 myshell]$ var=10
[wbm@wmblinux64 myshell]$ let var+=5
[wbm@wmblinux64 myshell]$ echo $var
15

表达式替换

[ ] (( )) 习惯使用 [ ] s h e l l []可以接受不同基数的数字
 [base#n] n表示基数从2到36任意基数
[wbm@wmblinux64 myshell] e c h o [10#8+191]
199
运算符的优先级(不确定的地方,多加括号)

shell输入与输出

一、echo

echo命令可以显示文本行或变量,或者把字符串输入到文件。
    echo [option] string
    -e  解析转义字符 
    -n  回车不换行,linux系统默认回车换行 eg: echo –n “abc” ; echo “abc” 
    -转义字符(\c(回车不换行) \f(禁止)\t(回车换行) \n(回车换行))
#!/bin/bash
#echo
echo -e "demo01.... \n\n\n"
echo "ok"
#echo 空,后面没有任何东西,将要有一个回车换行
echo
echo "demo02......\n\n\n"
echo "demo03 line" >mylog.txt

二、read

read语句可以从键盘或文件的某一行文本中读入信息,并将其制复制给一个变量。
 read var1 var2 …. 若只指定了一个变量,那么read将会把所有的输入赋给该变量,直至遇上第一个文件结束符或者回车。如果给了多个变量,他们按照顺序分别赋予不同的变量。shell将用空格作为变量之间的分隔符。

#!/bin/bash
#readme
#注意回车不换行的用法

echo -n "First Name:"
read firstname

echo -n "Last Name:"
read lastname lastname2 

echo -e "FirstName: ${firstname}\n" 
echo -e "LastName: ${lastname}\n" 

echo -e "LastName2: ${lastname2}\n"   

三、cat

cat是一个简单而通用的命令,可用它显示文件内容、创建文件、还可以用它来显示控制字符。
 cat [options] filename1 … filename2 ….
 -v 显示控制字符
 使用cat命令时注意,它不会在文件分页处停下来;它会一下显示完整个文件。如果希望每次显示一页,可以使用more命令 或把cat命令的输出通过管道传递到另外一个具有分页功能的命令(more、less)中。
 man cat
 cat myfile cat myfile1 myfile2 myfile3; cat myfile1 myfile2 > myfile12
 cat –v dos.txt 显示dos文件的^M
 eg: cat longfile |more ; cat longfile | less; less longfile

四、 管道

 可以通过管道把一个命令的输出传递给另外一个命令做输入。管道用竖线表示
 格式:命令1 | 命令2
 cat myfile | more
 ls –l | grep “myfile”
 df –k | awk ‘{print $1}’ | grep –v “Filesystem文件系统”
 df –k 看磁盘空间 查找第一列 去除filesystem字符排除掉

五、 tee

tee 命令把结果输出到标准输出,另一个副本输出到相应文件
 tee –a file -a: 表示追加 不加-a表示覆盖
 该命令一般用于管道之后 (一般看到输出,并存文件)
 eg who | tee –a who.out
 df –k | awk ‘{print $1}’ | grep –v “Filesystem” | tee partation.txt

六、标准输入、输出和错误

当我们在shell中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描符来引用这些文件。由于文件描述符不容易记忆, shell同时也给出了相应的文件名。
下面就是这些文件描述符及它们通常所对应的文件名:
输入文件—标准输入 0
输出文件—标准输出 1
错误输出文件—标准错误 2
系统中实际上有12个文件描述符,但是正如我们在上表中所看到的,0、1、2是标准输入、出和错误。可以任意使用文件描述符3到9。

文件重定向

这里写图片描述

一、重定向标准输出

eg:cat file | sort 1 > sort.out 
    cat file | sort >sort.out  这两个命令等同
    pwd >> path.out 

nullfile.txt 如果想创建一个长度为0的空文件,可以用’ > f i l e n a m e ‘:

二、 重定向标准输入

    eg1:    sort < file将file的内容输入到sort进行排序,排序后的结果sort命令输出
        sort < name.txt > name.out
    eg2:分隔符用法 

三、 重定向标准错误

    eg:$ grep "trident" missiles 2>/dev/null 
        在这个例子中,grep命令在文件missiles 中搜索trident字符串:
结合使用标准输出和标准错误
    eg:$ cat account_qtr.doc account_end.doc 1>accounts.out 2>accounts.err
合并标准输出和标准错误
    eg: grep “standard” standard.txt >grep.out 2>&1  

在上面的例子中,我们将 cleanup脚本的输出重定向到cleanup .out文件中,而且其错误也重定向到相同的文件中。
注意:shell是从左至右分析相应的命令

/home/wbm/myshell
[wbm@wmblinux64 myshell]$ cat file1 file2 file3 > err.out 2<&1 
[wbm@wmblinux64 myshell]$ cat err.out 
111
1111
111111
222
22222
2222222
cat: file3: 没有那个文件或目录
[wbm@wmblinux64 myshell]$

四、 exec和文件描述符在一起

1、 exec命令可以用来代替当前shell;换句话说,并没有启动子shell,使用
这一命令时,任何现有环境都将被清除,并重新启动一个shell。
exec command command通常是一个shell脚本。
Eg:测试执行完该命令后,需要重新登录shell,然后export声明的变量都失效了。exec ./hello.sh
2、对文件描述符进行操作时,也只有这个时,它不会覆盖你的当前的shell。

#!/bin/bash
#file_desc
#
exec 3<&0 0<name.txt 
read line1
read line2
exec 0<&3

echo $line1
echo $line2

猜你喜欢

转载自blog.csdn.net/coolwriter/article/details/80227392