文章预览
三、Shell基本编程
1、Shell编程介绍
Linux体系中的shell编程在实现系统管理与维护、系统使用、用户环境定制等方面作用突出。
使用shell写的程序通常也称为脚本。
在用户主目录中,在/etc目录中,随处可见脚本文件。
脚本是由各种变量、表达式、命令等通过一定的逻辑组装而成的,具有顺序解释执行的特性。
2、Shell脚本基本结构
#!/bin/bash
脚本支持:变量、表达式、流程控制、函数、注释,各种外部命令和程序调用、命令行参数、系统变量等等。
脚本就是将上述各种元素通过一定的逻辑关系进行组装已完成特定任务的程序。
3、Shell脚本及运行
1、利用vi编辑如下脚本并保持成
first.sh
#!/bin/bash
echo "Hello,welcome to Linux world"
echo "Today is $( date ) "
2、设置执行权限
chmod u+x first.sh
3、执行脚本
./first.sh 或 sh first.sh 或 bash first.sh
4、Shell变量及表达式 - 变量类型
环境变量(系统工作环境需要的全局变量)
$PATH, $BASH, $HOME,
P
W
D
,
P
W
D
,
TERM, $PWD
自定义变量(仅在脚本中使用局部变量)
语法格式
:变量名=变量值
#变量名约定大写
A= 10; echo $A
SA= "hello Linux" ; echo $SA
只读变量
readonly 变量名
导出局部变量
export 变量名 或者 export 变量名=变量值
函数中的同名局部变量: local 变量名=变量值
注意问题
变量指向一个字符串(含有空格),则变量值必须使用双引号括起来。例如:
SA=“Hello Linux”
引用时变量前加$,单引号和双引号的区别
echo ‘Oh$SA$SA’; echo “Oh$SA$SA”
清除不需要的变量:unset 变量名
如:unset SA
5、常用的Shell预定义变量
变量名
功能
$#
位置参数的数量
$*
所有位置参数的内容
$?
命令执行后返回的状态
$$
当前进程的进程号
$!
后台运行的最后一个进程号
$0
当前执行的进程名
6、Shell变量及表达式 - 位置参数
echo “完整的命令行:$0 $* ”
echo “程序是:$0 ”
echo “所有的参数:$* ”
echo “参数个数:$
echo “第1个参数: $1 ”
问题:如果参数没输入,但程序中需要怎么办?
7、Shell变量及表达式 –缺省参数
比如脚本 mycal.sh 5 6 +; mycal.sh 5 6 *
如果没有输入 + 或者 * ,我能否默认取为 + 呢?而不是认为程序执行出错呢?
VAR=${参数-word} :有则用参数,否则用word
VAR=${参数=word} :有则用参数, 否则两个用word
VAR=${参数? word} :有则用参数,否则报错退出
VAR=${参数+word} :有则用word,否则不做
注意:上述四条经常用在位置参数的使用上。
LEFT= ${1-100}
RIGHT= ${2-100}
RE= ` expr $LEFT + $RIGHT`
echo "$LEFT + $RIGHT = $RE "
8、Shell变量表达式 概述
Shell中的变量表达式主要利用各种测试语句、条件来获得字符串、文件、数字等所处的状态。
表达式的操作符主要包括:
字符操作符: =, !=, -n , -z
数字操作符:-eq, -ne, -ge, -gt, -le, -lt
==, !=, >=, >, <=, <
逻辑操作符:!, -a, -o
文件操作符:-d, -f, -L,-r, -w, -x, -s, -e, -z,-c, -b,-o
可以使用 test 命令来测试上述各种表达式状态
test是Shell程序中的一个表达式,通过和Shell提供的if等条件语句相结合可以方便地测试字符串、文件状态和数字。其语法如下:
test [表达式]
表达式所代表的操作符有字符串操作符、数字操作符、逻辑操作符以及文件操作符。
作用:测试字符串是否相等,长度是否为零,字符串是否为NULL。
常用的字符串比较符号如下。
=:比较两个字符串是否相同,相同则为“是”。
!=:比较两个字符串是否相同,不同则为“是”。
-n:比较字符串的长度是否大于0,如果大于0则为“是”。
-z:比较字符串的长度是否等于0,如果等于0则为“是”。
A= abcd; test $A = abcd; echo $?
A= " " ; test –z $A ; echo $?
test –n $A ; echo $?
test –z “$A ”; echo $?
B= 1234; test $B –eq 1234; echo $?
test $B –gt 1000; echo $?
文件测试表达式通常是为了测试文件的文件操作逻辑,测试符号如下。
-d:对象存在且为目录,则返回值为“是”。
-f:对象存在且为文件,则返回值为“是”。
-L:对象存在且为符号连接,则返回值为“是”。
-r:对象存在且可读,则返回值为“是”。
-s:对象存在且长度非0,则返回值为“是”。
-w:对象存在且可写,则返回值为“是”。
-x:对象存在且可执行,则返回值为“是”。
逻辑比较:
test -f /etc/passwd –a –s /etc/passwd; echo $?
test -f /etc/passwd –a –d /etc/passwd; echo $?
test -d /root ; echo $?
test ! –z /etc/passwd; echo $?
9、Shell脚本流程控制 - 分支语句if
Shell支持的流程控制语句主要有:
分支语句:if elif else fi, case … esac
- 循环语句:for, while, until
- 函数定义:function funname()
if (( 条件)) ; then
语句
fi
或者
if [ 条件 ] ; then
语句
elif[ 条件 ] ; then
语句
else
语句
fi
10、Shell脚本流程控制 - 分支语句case
echo -n "Input A="
read A
case $A in
1) echo "select 11" ; ;
2) echo "select 22" ; ;
*) echo "select else" ; ;
esac
echo -n "Input A="
read A
case $A in
"fuzhou city" ) echo "select 11" ; ;
"xiamen city" ) echo "seelct 22" ; ;
*) echo "select else" ; ;
esac
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
菜单式
OPTIONS= "fuzhou xiamen"
select opt in $OPTIONS ; do
case "$opt " in
fuzhou) echo "select fuzhou" ; ;
xiamen) echo "select xiamen" ; ;
*) exit ; ;
esac
done
11、Shell脚本流程控制—循环控制 for
for 变量 [ in 数值列表]
do
命令
done
len= 10;
for (( i= 0; i< "$len " ; i= i+1 ))
do
命令
done
例子:实现1加到100
sum= 0
for (( i= 1 ; i< 101 ; i= i+ 1 ))
do
let sum= sum+$i
done
echo $sum
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
12、Shell脚本流程控制—循环控制 while
while 条件命令为真
do
命令
done
while :
do
命令
done
例子:实现1加到100
k= 1
sum= 0
while [ $k -le 100 ]
do
let sum= $sum +$k
let k++
done
echo $sum
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
13、Shell脚本流程控制—循环控制 until
until 条件命令为假
do
命令
done
until :
do
命令
done
例子:实现1加到100
k= 1
sum= 0
until [ $k –gt 100 ]
do
let sum= $sum +$k
let k++
done
echo $sum
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
3种方法实现1加到100;4种i++;2种while
14、Shell脚本流程控制—函数
function funname( )
{
[ return 整数]
}
例1:
function sum( )
{
return $(( $1 + $2 ))
}
sum 10 20
echo "sum=$? "
funname( )
{
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#!/bin/bash
gsum= 0
function sumn( )
{ sum= 0
for (( i= 1 ; i<= $1 ; i++ ))
do
let sum= $sum +$i
done
gsum= $sum
return $sum
}
sumn 10
echo "sum=$? "
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#!/bin/bash
gsum= 0
function sumn( )
{ local gsum= 0
for (( i= 1 ; i<= $1 ; i++ ))
do
let gsum= $gsum +$i
done
return $gsum
}
sumn 10
echo "sum=$? "
echo $gsum
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
15、Shell脚本流程控制—数组
定义:
A=(元素列表,空格隔开)
下标从0开始 如A=(a b c d)
数组长度
${#A[*]}
引用第i个元素
KaTeX parse error: Expected '}', got 'EOF' at end of input: {A[
i]}
赋值
A[$i]=value
以字符串输出所有元素
echo ${A[*]}
循环输出所有元素
A= ( a b c 123 ad 21)
Len= ${#A[*]}
for(( i= 0; i< "$Len " ; i++))
do
echo ${A[$i]}
done
或者
for value in ${A[*]}
do
echo $value
done
16、Shell脚本流程控制—序列函数seq
seq 1 100
Len= ${#A[*]}
for(( i= 0; i< "$Len " ; i++))
do
echo ${A[$i]}
done
17、细节问题1:整数的四则运算
A= 10
B= 20
C= ` expr $A + $B`
D= $(( $A+ $B))
D= $[ $A +$B ]
let E= A+B
(( F= A+ B))
let A++
let A+= 10
18、细节问题2:字符串函数
字符串A= "HELL:LINUX:WORLD"
LEN= ${#A}
SUB1= ${A:5:5}
结果 LINUX
SUB2= ${A:5}
结果 LINUX:WORLD
REP= ${A//:/\/}
结果 HELL/LINUX/WORLD
REP= ${A//:/cc}
19、细节问题3:浮点数运算
A= $( echo "scale=4; 5-2/3" | bc )
bc –q
scale= 4
5-2/3
quit
bc –q file
define is_prime( n)
{
auto prime,i;
prime= 1;
for ( i= 2; i^2<= n; ++i)
{
if ( n%i== 0) { prime= 0; break ; }
}
return prime;
}
print "\nPlease enter a positive integer n:\n" ;
n= read( ) ;
print "\n\n"
for ( i= 2; i<= n; ++i)
{
if ( is_prime( i)) { print i; print "\n" ; }
}
quit;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
=4; 5-2/3"|bc)
#2.
bc –q #进入bc计算器环境
scale=4 #设置小数点4位
5-2/3
quit #退出环境
#3.
bc –q file #执行file文件中的代码,类C代码
```shell
#prime.txt文件 使用 bc –q prime.txt
define is_prime(n)
{
auto prime,i;
prime=1;
for (i=2;i^2<=n;++i)
{
if (n%i==0){ prime=0; break; }
}
return prime;
}
print "\nPlease enter a positive integer n:\n";
n=read();
print "\n\n"
for (i=2;i<=n;++i)
{
if (is_prime(i)){ print i; print "\n"; }
}
quit;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
专栏 《linux网络编程》 将持续更新中…
从linux 零基础 到 高并发服务器架构
如果我的文章能够帮到您,可以顺手点个赞!
您的每次 点赞、关注、收藏 都是对我最大的鼓励!
………………………………