linux的shell进化简史

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;
}




你可能感兴趣的:(linux)