shell 中的for、while循环及if语句
shell与其他语言一样也支持for、while循环
for循环的一般格式如下:
复制代码
#!/bin/sh tips:
以上的理解在于, 你一定要分清楚 unset 与 null 及 non-null 这三种赋值状态.
for 变量 in 列表 一般而言, : 与 null 有关, 若不带 : 的话, null 不受影响, 若带 : 则连 null 也受影响.
do
command 1 还有哦,${#var} 可计算出变量值的长度:
command 2 ${#file} 可得到 27 ,因为 /dir1/dir2/dir3/my.file.txt 刚好是 27 个字节…
command 1
… 接下来,再为大家介稍一下 bash 的组数(array)处理方法。
command n 一般而言,A=“a b c def” 这样的变量只是将 $A 替换为一个单一的字符串,
done 但是改为 A=(a b c def) ,则是将 $A 定义为组数…
复制代码 bash 的组数替换方法可参考如下方法:
列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个值赋给变量。 ${A[@]} 或 ${A[]} 可得到 a b c def (全部组数)
列表也可以是一个文件: A [ 0 ] 可 得 到 a ( 第 一 个 组 数 ) , {A[0]} 可得到 a (第一个组数), A[0]可得到a(第一个组数),{A[1]} 则为第二个组数…
in 列表是可选的,如果不用它,for 循环使用命令行的位置参数。 ${#A[@]} 或 ${#A[]} 可得到 4 (全部组数数量)
KaTeX parse error: Expected '}', got '#' at position 2: {#̲A[0]} 可得到 1 (即第…{#A[3]} 可得到 3 (第四个组数(def)的长度)
#!/bin/sh A[3]=xyz 则是将第四个组数重新定义为 xyz …
for line in 1 2 3 4 5 6 7
do
echo “line is $line”
done
结果:
[root@localhost 1st]# sh test.sh
line is 1
line is 2
line is 3
line is 4
line is 5
line is 6
line is 7
下面用for循环读一个文件:
查看文件内容
[root@localhost 1st]# cat test.txt
hello
wolrd
hello
shell
[root@localhost 1st]#
code:
复制代码
#!/bin/sh
FILE=./test.txt
for line in ( < (< (<FILE)
do
echo “line is: $line”
done
复制代码
Results:
[root@localhost 1st]# sh xx.sh
line is: hello
line is: wolrd
line is: hello
line is: shell
[root@localhost 1st]#
while循环的一般格式如下:
while command
do
statement
done
code:
复制代码
#!/bin/sh
i=0
sum=0
while [ i − l e 100 ] d o s u m = i -le 100 ] do sum= i−le100]dosum=(($sum + i ) ) i = i)) i= i))i=(($i + 1))
done
echo “sum is $sum”
复制代码
rusults:
[root@localhost 1st]# sh xx.sh
sum is 5050
[root@localhost 1st]#
if语句的一般格式如下:
复制代码
if …; then
…
elif …; then
…
else
…
fi
复制代码
if 条件语句:
文件表达式:
复制代码
[ -f “somefile” ] : 判断是否是一个文件
[ -x “/bin/ls” ] : 判断/bin/ls是否存在并有可执行权限
[ -n " v a r " ] : 判 断 var" ] : 判断 var"]: 判断var变量是否有值
[ “ a " = " a" = " a"="b” ] : 判断 a 和 a和 a和b是否相等
-r file 用户可读为真
-w file 用户可写为真
-x file 用户可执行为真
-f file 文件为正规文件为真
-d file 文件为目录为真
-c file 文件为字符特殊文件为真
-b file 文件为块特殊文件为真
-s file 文件大小非0时为真
-t file 当文件描述符(默认为1)指定的设备为终端时为真
复制代码
字符串表达式:
[string string_operator string]
这里string_operator可为如下几种:
= 两个字符串相等。
!= 两个字符串不等。
-z 空串。
-n 非空串
eg:
#!/bin/sh
NUMS=“hello”
[ $NUMS = “hello” ]
echo $?
results:
[root@localhost 1st]# sh xx.sh
0
整数表达式:
-eq 数值相等。
-ne 数值不相等。
-gt 第一个数大于第二个数。
-lt 第一个数小于第二个数。
-le 第一个数小于等于第二个数。
-ge 第一个数大于等于第二个数。
Eg:
复制代码
#!/bin/sh
NUMS=130
if [ $NUMS -eq “130” ]; then
echo "equal"
else
echo “not equal”
fi
复制代码
results:
[root@localhost 1st]# sh xx.sh
equal
下满贴出一个用shell写的简单图书管理系统:
复制代码
#!/bin/bash
#Name:Books Management System(BMS)
#Author:DREAM
file=books.txt
function information
{
echo “Books Management System(BMS)”
echo “---------------------------”
echo -e " 1: ADD Books"
echo -e " 2: Show Books"
echo -e " 3: Select Books"
echo -e " 4: Delete Books"
echo -e " 5: Exit System"
#echo
echo “---------------------------”
read -p “please input your choice:” num
echo
case "$num" in
1) Add
;;
2) Show
;;
3) Select
;;
4) Delete
;;
5) exit
;;
*) information
;;
esac
}
function Add
{
echo -e “please books information eg:(English 101 Jerry)”
echo
read -p "please input books name: " books_name
read -p "please input books number: " books_num
read -p "please input books author: " books_author
echo -e "$books_name\t$books_num\t$books_author" >>$file && {
echo "Add Books success"
echo "---------------------------"
}
if [ $? -ne 0 ]
then
echo "Add Books failure"
fi
information
}
function Show
{
echo -e “Bname\tBnum\tBauthor”
grep -Ev “^$” $file
echo “-----------------------”
echo
information
}
function Search_menu
{
echo “-----------------------”
echo -e " 1: Search By Bname"
echo -e " 2: Search By Bnum"
echo -e " 3: Search By Bauthor"
echo -e " 4: Eixt Search System"
echo
echo “-----------------------”
}
function Select
{
Search_menu
read -p “please input your choice:” ch
case “$ch” in
1)
read -p "please input books name: " name
echo -e “Bname\tBnum\tBauthor\n-------------------------”
awk ‘{if(KaTeX parse error: Expected group after '^' at position 4: 1~/^̲'name’/) print $0}’ $file
echo “-------------------------”
if [ KaTeX parse error: Expected 'EOF', got '\tBnum' at position 165: … echo -e "Bname\̲t̲B̲n̲u̲m̲\tBauthor\n----…num ‘$2==s {print $0}’ $file 2>/dev/null
echo “-------------------------”
if [ $? -ne 0 ]
then
echo “the file no exist”
fi
echo $?
;;
3)
read -p "please input books author: " author
echo -e “Bname\tBnum\tBauthor\n-------------------------”
awk ‘{if( 3 / ′ 3~/' 3 /′author’/) print $0}’ $file
echo “-------------------------”
if [ $? -ne 0 ]
then
echo “the file no exist”
fi
echo $?
;;
4) exit
;;
*) Select
;;
esac
echo
information
}
function Delete
{
read -p “please input your want delete boos number:” num
sed -i “/$num/d” $file
if [ $? -ne 0 ]
then
echo "success failure"
fi
information
}
information
复制代码
利用popen快速获取一个shell命令的返回值
优点:避免了生成临时文件
函数原型:
#include
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
函数说明:
popen()函数通过创建一个管道,调用fork()产生一个子进程,执行一个shell以运行命令来开启一个进程。这个管道必须由pclose()函数关闭,而不是fclose()函数。pclose()函数关闭标准I/O流,等待命令执行结束,然后返回shell的终止状态。如果shell不能被执行,则pclose()返回的终止状态与shell已执行exit一样。
type参数只能是读(“r”)或者写(“w”)中的一种,得到的返回值(标准I/O流)也具有和type相应的只读或只写类型。如果type是"r"则文件指针连接到command的标准输出;如果type是"w"则文件指针连接到command的标准输入。
command参数是一个指向以NULL结束的shell命令字符串的指针。这行命令将被传到bin/sh并使用-c标志,shell将执行这个命令。
popen()的返回值是个标准I/O流,必须由pclose来终止。前面提到这个流是单向的(只能用于读或写)。向这个流写内容相当于写入该命令的标准输入,命令的标准输出和调用popen()的进程相同;与之相反的,从流中读数据相当于读取命令的标准输出,命令的标准输入和调用popen()的进程相同。
返回值:
如果调用fork()或pipe()失败,或者不能分配内存将返回NULL,否则返回标准I/O流。popen()没有为内存分配失败设置errno值。如果调用fork()或pipe()时出现错误,errno被设为相应的错误类型。如果type参数不合法,errno将返回EINVAL。
下面是使用popen获取主机中虚拟机个数的范例:
复制代码
#include
#include
int main()
{
FILE *fp;
size_t value = 0;
int nums;
char cmd[1024] = {0};
int guestnums;
strcpy(cmd, "virsh list --all | sed -n '3, $p' | grep -v '^$' | wc -l");
/使用popen获取shell命令返回值/
if((fp = popen(cmd, “r”)) != NULL) {
if(fgets((char *)&nums, 2, fp))
{
guestnums = atoi((char *)&nums);
}
}
printf("%d\n", guestnums);
pclose(fp);
return 0;
}