Bourne-Again Shell
Bourne-Again Shell,即bash,是一个开源的GNU项目,旨在替换Bourne Shell。Bourne-Again Shell由Brian Fox开发,现在已经成为最流行的Shell之一,被广泛应用在Linux、Darwin、Windows和Cygwin之上。
除了支持脚本的向后兼容性,bash还吸收了Korn Shell和C Shell的一些特性。例如,命令历史记录,命令行编辑,目录堆栈,很多实用的环境变量,命令行自动完成,等等。
Bash继续发展了一些新的特性,如支持正则表达式和关联数组。
虽然一些特性是bash独有的,但我们仍然可以编写与其他脚本语言相兼容的脚本。下面是在bash中统计可执行文件数目的脚本示例。
代码3:在Bourne-Again Shell中统计可执行文件的数目
这些Shell之间的一个关键区别是它们使用了不同的授权。Bash是一个GNU项目,遵循GPL授权,而C Shell则遵循了BSD许可,Korn Shell则遵循了通用公共许可证。
早期Shell的许多理念和接口在35年之后依然保持不变,这对其作者是一个巨大的肯定。任何一个行业都在不断重塑自我,Shell也在发生着历史的变迁。尽管许多新的Shell被开发出来,但Bourne Shell及其后继者依然是现在的首选。
#!/bin/sh
#set -x
echo -n "Can you write device drivers?"
....
其中如果去掉set -X前面的注释的话会跟踪整个脚本的运行,echo函数对于调试是很有帮助的,但是有时候代码多了之后,想去掉也是很难的。
根据debug的等级来决定输出
#!/bin/sh
debug=1
test $debug -gt 0 &&echo "Debug is on"
echo -n "Can you write device drivers?"
read answer
...
debug=2
test $debug -gt 0 &&echo "A little data"
test $debug -gt 1 &&echo "Some more data"
test $debug -gt 2 &&echo "Even some more data"
用一个函数来检查错误
alert(){
if[ "$1" -ne 0 ]
then
echo "WARNING: $2 did not complete successfully.">&2
exit $1
else
echo "INFO:$2 completed successfully">&2
fi
}
如下所示的调用:
cat $LOG|mail -s "$FROM attempting to get $FILE" $TO
alert $? "Mail of $LOG to $TO"
输出如下:
INFO:Mail of $LOG to $TO completed successfully.
INFO:Mail of $LOG to $TO did not complete successfully.
还有就是根据我们的输入去逐条的人工去执行,查看结果
第二章:标准函数库(需要进行实践,还不确定怎么用)
一:被反复使用的函数和例程写到库函数文件中。
#!/bin/echo Waring: this library should be sourced!
ostype()
{
osname=`uname -s`
OSTYPE=UNKNOW
case $osname in
"Linux") OSTYPE="LINUX"
;;
esac
return 0
}
ostype
echo "system is $OSTYPE"
第一行必须以source命令执行该库文件,将变量OSTYPE的值载入到环境中
避免直接执行库文件
例如:source ./test.sh
优秀的shell库实例:Gentoo Linux
/etc/inti.d/funcitons.sh
二:几个函数:
例子1.
传入任一数字,判断数字奇偶性
evenodd()
{
LAST_DIGIT=`echo $1 |sed 's//(.*/)/(./)$//2/'`
case $LAST_DIGIT in
0|2|4|6|8)
echo "o"
return 1
;;
*)
echo "j"
return 0
;;
esac
}
evenodd 123
例子2.
判断远程系统是否运行,是否接入网络。
isalive()
{
NODE=$1
ping -c 3 $NODE >/dev/null 2>&1
if [ $? -eq 0 ]
then
echo "a"
return 1
else
echo "ua"
return 0
fi
}
isalive 10.192.39.11
三:库函数的调用
1.在shell文件中添加
source std_lib
载入库函数
2.点句法(source 换成 .)
. std_lib
第三章: 操纵时间和日期
//errHunter的示例程序,包括所有能检测出的错误
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<dirent.h>
#include<string>
void function(){
chara;
//errHunter的示例程序,包括所有能检测出的错误
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<dirent.h>
#include<string>
void function(){
char a;
/******语义的检查******/
//变量为初始化使用,case语句缺少break,重复break
switch(a)
{
case 'a':
break;
case 'b':
break;
break;
case 'c':
case 'd':
return;
default:
}
/******对内存的检查******/
//c和c++动态申请内存中创建和释放语句的匹配
int *p=(int*)malloc(sizeof(int)*10);
free(p);
int *p=new int(10);
delete p;
/******未用的函数或变量,未初始化的变量******/
//对文件进行操作,在用fclose之前是否判断指针为空(指针)
FILE* fp;
fp=fopen("example.txt","r+");
fclose(fp);
//未使用的变量
int i;
//未使用的函数
int g(){
return 0;
}
/******STL的错误使用******/
/******对废弃函数的使用会给出警告******/
//bcmp bcopy bzero ftime getwd .......
/******对不可冲入函数的调用会给出警告******/
//asctime crypt ctermid ctime ecvt fcvt fgetgrent gcvt getlogin getgrnam ......
/******其他的一些检查******/
//把一个bool值赋给指针
bool m=false;
p=m;
//对bool进行增加操作
m++;
//sprintf的错误使用
char *str="Hello World!";
sprintf(str,"<%s>",str);
//除以0
int num=10;
num=num/0;
//对输入流使用fflush
//fflush(in);
//在assert语句中赋值
assert(num=5);
//substr和strncmp中不正确的参数
std::string str2;
std::string str="We are the best!";
str2=str.substr(16);
//对output不正确的使用
std::cout<<std::cout;
//在sizeof()中做计算
i=sizeof(num*2)
//不可到达的代码,冗余代码
if(true)
{
}
else
{
//这里不可到达
printf("Hello World!");
}
}
//
int main(){
f();
return 0;
}
/******语义的检查******/
//变量为初始化使用,case语句缺少break,重复break
switch(a)
{
case 'a':
break;
case 'b':
break;
break;
case 'c':
case 'd':
return;
default:
}
/******对内存的检查******/
//c和c++动态申请内存中创建和释放语句的匹配
int *p=(int*)malloc(sizeof(int)*10);
free(p);
int *p=new int(10);
delete p;
/******未用的函数或变量,未初始化的变量******/
//对文件进行操作,在用fclose之前是否判断指针为空(指针)
FILE* fp;
fp=fopen("example.txt","r+");
fclose(fp);
//未使用的变量
int i;
//未使用的函数
int g(){
return 0;
}
/******STL的错误使用******/
/******对废弃函数的使用会给出警告******/
//bcmp bcopy bzero ftime getwd .......
/******对不可冲入函数的调用会给出警告******/
//asctime crypt ctermid ctime ecvt fcvt fgetgrent gcvt getlogin getgrnam ......
/******其他的一些检查******/
//把一个bool值赋给指针
bool m=false;
p=m;
//对bool进行增加操作
m++;
//sprintf的错误使用
char *str="Hello World!";
sprintf(str,"<%s>",str);
//除以0
int num=10;
num=num/0;
//对输入流使用fflush
//fflush(in);
//在assert语句中赋值
assert(num=5);
//substr和strncmp中不正确的参数
std::string str2;
std::string str="We are the best!";
str2=str.substr(16);
//对output不正确的使用
std::cout<<std::cout;
//在sizeof()中做计算
i=sizeof(num*2)
//不可到达的代码,冗余代码
if(true)
{
}
else
{
//这里不可到达
printf("Hello World!");
}
}
//
int main(){
f();
return 0;
}
//errHunter的示例程序,包括所有能检测出的错误
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<dirent.h>
#include<string>
void function(){
char a;
/******语义的检查******/
//变量为初始化使用,case语句缺少break,重复break
switch(a)
{
case 'a':
break;
case 'b':
break;
break;
case 'c':
case 'd':
return;
default:
}
/******对内存的检查******/
//c和c++动态申请内存中创建和释放语句的匹配
int *p=(int*)malloc(sizeof(int)*10);
free(p);
int *p=new int(10);
delete p;
/******未用的函数或变量,未初始化的变量******/
//对文件进行操作,在用fclose之前是否判断指针为空(指针)
FILE* fp;
fp=fopen("example.txt","r+");
fclose(fp);
//未使用的变量
int i;
//未使用的函数
int g(){
return 0;
}
/******STL的错误使用******/
/******对废弃函数的使用会给出警告******/
//bcmp bcopy bzero ftime getwd .......
/******对不可冲入函数的调用会给出警告******/
//asctime crypt ctermid ctime ecvt fcvt fgetgrent gcvt getlogin getgrnam ......
/******其他的一些检查******/
//把一个bool值赋给指针
bool m=false;
p=m;
//对bool进行增加操作
m++;
//sprintf的错误使用
char *str="Hello World!";
sprintf(str,"<%s>",str);
//除以0
int num=10;
num=num/0;
//对输入流使用fflush
//fflush(in);
//在assert语句中赋值
assert(num=5);
//substr和strncmp中不正确的参数
std::string str2;
std::string str="We are the best!";
str2=str.substr(16);
//对output不正确的使用
std::cout<<std::cout;
//在sizeof()中做计算
i=sizeof(num*2)
//不可到达的代码,冗余代码
if(true)
{
}
else
{
//这里不可到达
printf("Hello World!");
}
}
//
int main(){
f();
return 0;
}