脚本编程

解释性和编译型语言区别

  • 编译型 编译型语言是指在执行之前需要先把程序源文件编译为能在目标机器上直接运行的二进制可执行程序。运行时不需要再编译,执行效率高
  • 解释型 解释型语言是指源代码不需要预先进行编译,在运行时,通过解释器解释执行,执行效率低

C++就是纯编译型语言;
java属于编译-解释型语言,在jdk上面解释;
Python是纯解释型语言
shell也是纯解释型语言

一个简单的shell程序

#!/bin/bash

echo "hello"

exit 0
  • 第一行#!后面指定的是执行该脚本的解释器,如果没有第一行信息,当前系统会默认使用shell来执行此脚本
  • echo 命令用来打印,相当于printf
  • exit 指的是退出当前脚本
  • # 可以理解为注释

变量

本地变量

本地变量时用户自己定义的,形式为“变量=值”,注意左右两边不要有空格。

#!/bin/bash

val=100		#不要有空格
str=hello

echo "val=$val"
echo "str=$str"

exit 0

环境变量

环境变量一般是从父进程环境中继承过来的,当一个shell脚本程序开始执行时,一些变量会根据环境变量中的值进行初始化。这些变量通常大写字母做名字,以便把它们和用户在脚本程序里定义的变量区分开来。一些常见的环境变量:

#!/bin/bash

echo "path=$PATH"
echo "home=$HOME"

exit 0

参数变量

参数变量时脚本程序或函数传参时使用,如$1代表传给脚本的一个参数。相当于main函数参数。

#!/bin/bash

echo "\$1=$1"
echo "\$2=$2"

exit 0

条件

在shell脚本中测试条件使用:
test或者[
该命令可使用的条件
可以分为三类:

  • 字符串比较

  • 算数比较

  • 文件条件测试

控制结构

if…then语句

#!/bin/bash
#-f是测试文件是否文件

if [ -f/bin/bash ]	#注意这里都要有空格
then 
	echo "file /bin/bash exists"

fi
exit 0
#!/bin/bash
#测试/bin/bash是目录还是普通文件,-d是测试文件是否为目录

if [ -d/bin/bash ]
then
	echo "/bin/bash is a dir"
else
	echo "/bin/bash is not a dir"
fi

exit 0

#!/bin/bash
#elif的使用
echo "is it morning? please answer yes or no"
read timetoday;

if [ $timetoday="yes"]
then
	echo "good morning"
elif [ $timetoday="no"]
then
	echo "sorry,please enter yes or no"
	exit 1
fi

exit 0
#!/bin/bash
# ||逻辑或

echo "please input:"
read num

if [ $num -lt 0 ] || [ $num -gt 100 ]
then
	echo "num < 0 || num >100"
fi
exit 0
#!/bin/bash
# &&逻辑与

echo "please input:"
read num

if [ $num -gt 10 ] && [ $num -lt 20 ]
then
	echo "10 < $num < 20"
fi
exit 0

循环for语句

# for循环格式
for variable in values
do
	Statements
done
#!/bin/bash

for foo in bar fud 43
do
	echo $foo
done
exit 0

循环while语句

while condition
do
	statements
done
echo "enter password"
read passwd

while [ "$passwd"!="123456" ]
do
	echo "sorry,try again"
	read passwd
done
exit 0

循环until语句

until condition
do 
	statemets
done
#!/bin/bash

echo "enter filename"
read filename

until [ -f "$filename" ]
do
	echo "not find $filename"
	sleep 1
done

echo "$filename exists!"
exit 0

case 语句

case variable in
	Pattern [ |pattern]) statements;;
	Pattern [ |pattern]) statements;;
esac
#!/bin/bash

echo "is it morning? please answer yes or no"
read timeofday

case "$timetoday"  in
	yes) echo "good morning"
	no)	 echo "good afternoon"
easc

exit 0

函数

Fnuction_name(){
   
	statements
}
#!/bin/bash
# 创建函数并调用
foo()
{
   
	echo "function foo is executing"
}

echo "script starting"
foo #调用foo
echo "ecript ended"

exit 0
#!/bin/bash
# 函数传参
foo()
{
   
	echo "function foo si executing"
	echo "function \$#=$#"	#参数个数
	echo "function \$1=$1"	#参数1
	echo "function \$2=$2"	#参数2
}
echo "script starting"
foo "hello" "123"
echo "script ended"

echo "script \$#=$#"
echo "script \$1=$1"	
echo "script \$2=$2"	

运行结果:

#!/bin/bash
#变量生存期
foo()
{
   
	echo "function foo si executing"
	mystr="hello function"
	echo "function:mystr=$mystr"
}
echo "script starting"
foo "hello" "123"
echo "script ended"

echo "script mystr=$mystr"

exit 0

运行结果:

在函数运行结束后,变量mystr已经在解释器中存在,只要没明确删除该变量,则在脚本一直都可以访问。可以理解成全局变量。

如果变量用以下方式定义,在函数外就不可访问了:

local mystr="hello function"
#!/bin/bash
# 获取返回值

foo()
{
   
	echo "function foo is runing"
	return 3
}

echo "ecript starting"
foo "hello" "123"
res=$?		#得到最近的函数返回值
echo "res=$res"
echo "script ended"

exit 0

脚本调用脚本

#!/bin/bash

echo "mybash script run"

./b.sh	#调用脚本b.sh
echo "mybash script ended"

点命令方式执行脚本

在执行脚本时,还可以使用.或者sourse来执行一个脚本,作用是新执行的脚本不会启动新的解释器,而是再原解释器中执行。

#!/bin/bash

echo "mybash script run pid=$$"		#$$得到进程pid值

source ./b.sh		#以source方式调用脚本
echo "mybash ended"

exit 0

C语言中调用脚本

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>

int main()
{
   
	pid_t pid = fork();
	assert(pid != -1);
	
	if(pid == 0)
	{
   
		printf("chile pid = %d\n",getpid());
		excel("./b.sh","b.sh",char*)0);		//进程间替换方式调用
		exit(0);
	}
	
	printf("parent pid = %d\n",getpid());
	wait(NULL);

	exit(0);
}

awk

awk用于格式化报文或者从一个大的文本文件中抽取数据报

awk使用介绍

awk [-F field -separator] 'commands' input-file

//[-F 域分隔符]是可选的,如果分隔符是空格可以不写。
//command指定操作命令,一般使用print进行输出打印 
//input-file是要操作的文件的名字
awk -F. '{printf $1}' a.txt->b.txt

//-F.的.告诉awk,a.txt文件中两个域用点分隔
//命令printf $1,表示只用打印被分隔后的第一个列
//->b.txt,表示把内容输出至b.txt

域和记录
在awk中,将一行信息称作一个“记录”,将一个列称作一个“域”。从左边开始,每个域都用$1 $2 $3...$n来表示

条件操作符

操作符 描述
< 小于
<= 小于等于
== 等于
!= 不等于
>= 大于等于
- 匹配正则表达式
!~ 不匹配正则表达式
//示例
awk -F: '{if ($3 == 0) print $7}' /ect/passwd

sed

sed是个非交互性文本流编辑器。它编辑文本或者标准输入导入的文件拷贝。其可对文件进行添加、删除、替换、抽取等操作。

sed 'some-sed-commands' input-file>myoutfile

部分sed编辑命令:

//以下代码用于在a.txt文件中第三行插入4.5并保存到b.txt文件中
sed '3i\4.5' a.txt>b.txt

参考文献

[1] 图论科技.LINUX程序开发.西安图论科技.