Linux操作系统编程(3)—— shell编程基础
Linux操作系统编程(3)—— shell编程基础
前两篇文章分别是 常用linux操作命令
,已经讲述了linux基本命令和文件系统、帮助系统等,因此本文来梳理一下shell编程的语法和样例
变量
在shell中可以直接定义变量并给变量赋值,使用起来感觉类似python
p=1
a=123
#要注意,这里不能有空格,因为添加空格之后就变成一个命令了
如果我们要编写一个脚本的话,就需要先创建一个脚本文件, vim 1.sh 即可
这个脚本的第一行是告诉大家,计算机要用bash解释这个文件,实际上,由于现在的系统比较智能,即便删除了这句话也是可以执行的。
**命令替换符 **
A=`pwd`
#这里的``就是命令替换符,不是单引号,而是键盘左上角,esc下边的那个键
WorkDir=`pwd`
echo -e "ln\033[31;32m${WorkDir}\033[0m"
这里的$是将变量的值取出来,{}起到了确定变量范围的作用,如果是比较简单的命令,不写{}也是可以的。
除了我们自己定义的变量之外,我们编写脚本的时候还要注意有一些特殊的变量、
$0 表示程序自己
$1 表示第一个参数,以此类推,$2 表示第2个参数
$# 得到执行当前脚本的参数个数
$* 获取当前shell的所有参数,将所有命令参数视为单个字符串
[email protected] 也表示所有参数, 但是所有参数是分开的,保留参数之间的空白,可以传参给别的程序
$? 判断上一条指令是否执行成功, 0 表示成功,其他数字表示不成功
$$ 取当前进程的PID
$! 上一个指令的PID
#!/bin/bash
echo "hello, everyone!"
#是注释,第一行是固定格式,说明解释器
WorkDir=`pwd`
echo -e "In\033[31;32m ${WorkDir} \033[0m"
echo "program Name : $0"
echo "arg1: $1"
echo "arg2: $2"
echo "arg3: $3"
echo "arg4: $4"
echo "arg5: $5"
echo "arg6: $6"
echo "\[email protected] : [email protected]"
echo "\$* : $*"
echo "\$# : $#"
ls /etc1
echo "\$? : $?"
last | grep "xxx" 1>/dev/null 2>/dev/null
if [[ $? -eq 0 ]];then
echo -e "$Name logged In!\n"
fi
参数展开
${parameter:-word} 如果变量未定义,则表达式的值为word
${parameter:=word} 如果变量未定义,则设置变量的值为word,返回表达式的值也是word
${parameter:?word} 用于捕捉由于变量未定义而导致的错误并退出程序
${parameter:+word} 如果变量已经定义,返回word也就是真
${!prefix*}
${[email protected]} prefix 开头的变量
字符串展开
${#parameter} 输出字符串的长度
${parameter:offset} 从第offset开始截取
${parameter:offset:length} 从offset开始截取,取length长度
${parameter#pattern} 从头删除最短匹配
${parameter##pattern} 最长
${parameter%pattern}从尾删除最短
${parameter%%pattern} 从尾删除最长
${parameter/pattern/string}第一个匹配被替换
${parameter//pattern/string} 全部匹配被替换
${parameter/#pattern/string} 字符串开头的替换
${parameter/%pattern/string} 字符串结尾被替换
${parameter,} ${parameter^^} 全部转换为小写、大写
${parameter,} ${parameter^} 首字母转换为小写、大写
分支判断结构
条件判断语句
if [[ contdition ]];then
#statements
fi
#或
if [[ condition ]];then
#statements
else
#statements
fi
在if 的括号里边,左右必须有空格,中间的条件判断就是test表达式
-n 针对字符串,长度不为0
-z 针对字符串,长度为0
== != 这是常规的用法
对于整型
-eq 等于
-ge 大于等于 greater than or equal
-gt 大于
-le 小于等于
-lt 小于
-ne 不等于
对于文件
-ef 是否是同一个文件
-nt 前一个是不是更新的
-ot 前一个是不是更老的
-b 判断是否存在,且是二进制格式文件
-c 判断是否存在且是字符
-d 判断是否存在且是目录
-e 文件存在
-f 存在且是普通文件
-g 存在且是一个组
-G存在且所属组是有效地
Targetfile='a.c'
if [[ -r ${Targetfile} ]];then
gcc a.c -o a
./a
else
echo "${Targetfile} not found!"
fi
while语句
while [[ condition ]];do
#statements
done
循环语句
for i in words;do
#statements
done
#for循环也可以 for i in `seq 1 100` 这个是用系统生成序列
for (( i=0; i<10; i++ ));do
#statements
done
until [[ condition ]];do
#statement
done
case word in
pattern)
;;
*)
;;
esac
read a
case $a in
1)
echo 1
;;
2)
echo 2
;;
*)
echo "not found!"
;;
esac
num=0
while [[ $num -lt 100 ]];do
echo ${num}
num=$[ ${num} + 1 ]
done
数组
declare -a a
name[subsript]=value
name=(value1 value2...)
D=(1 2 3 4 5 6 7)
File=(`ls`)
#输出数组内容如下
${array[*]}
#或
${array[@]}
#确定数组元素的个数
${#array[@]}
#找到数组下标,看看有多少个
${!array[@]}
#数组追加
array+=(a b c)
#数组排序
sort
#删除数组与元素
Unset
基本的流程结构就这些,如何使用下面举几个例子
求偶数和
sum=0
for (( i=1; i<=100; i++));do
if [[ $[ ${i} % 2 ] -eq 0 ]];then
sum=$[ ${sum} + ${i} ]
fi
done
echo "sum = ${sum}"
暴力求素数
#!/bin/bash
#首先定义一个函数,用来输出脚本的用法
function Usage(){
echo "Usage : $0 start_num end_num"
exit
}
#暴力判断是不是素数
function is_prime(){
num=$1
#num就是传入的参数
for(( j=2; j<${num}; j++));do
if[[ $[ ${num} % $j ] -eq 0 ]];then
return 1
fi
done
return 0
}
#如果调用脚本时参数数量少于两个,就返回Usage
if [[ $# -ne 2 ]];then
Usage
fi
#分别用脚本的第一个和第二个参数为start和end 赋值,并将sum初始化
Start=$1
End=$2
sum=0
for (( i=${Start}; i<=${End}; i++ ));do
is_prime $i
#判断这个数是不是素数,如果上一条命令执行结果是零就加和进去
if [[ $? -eq 0 ]];then
sum=$[ ${sum} + $i ]
fi
done
echo ${sum}
用素数筛法求素数和
if [[ $# -ne 2 ]];then
echo "error"
exit
fi
Start=$1
End=$2
declare -a Prime
#定义数组
function init_prime(){
local end=$1
#定义了一个局部的变量
local i
Prime[1]=1
for (( i=2; i<=${end}; i++ ));do
for(( j=$[ ${i} * ${i} ]; j<=${end}; j+=i ));do
Prime[${j}]=1
#被标记为1,不是素数
done
done
}
init_prime ${End}
sum=0
#下面的命令可以输出数组所有内容
echo ${Prime[*]}
for (( i=${Start}; i<=${End};i++ ));do
if [[ ${Prime[$i]}x == x ]];then
#这句话就是判断是不是零,如果是零,拼接上x还是等于x
sum=$[ ${sum} + $i]
fi
done
echo ${sum}
在此基础上还有线性筛,主要的改动如下
function init_prime(){
local end=$1
local i
Prime[1]=1
for (( i=2; i<=${end}; i++ ));do
if [[ ${Prime[$i]}x == x ]];then
Prime[0]=$[ ${Prime[0]} + 1 ]
Prime[${Prime[0]}]=$i
sum=$[ ${sum} + $i ]
fi
for (( j=1; j<=${Prime[0]}; j++ ));do
if [[ $[ $i * ${Prime[$j]} ] -gt ${End} ]];then
break;
fi
Prime[ $[ $i * ${Prime[$j]} ] ]=1
if [[ $[ $i % ${Prime[$j]} ] -eq 0 ]];then
break;
fi
done
done
}
上一篇: 【Linux】——Shell编程基础
下一篇: 预览图片