一,shell脚本的执行方式。
1、path/script-name 或./script-name 在当前路径下执行脚本,需要将脚本文件的权限改为可执行。然后使用脚本的绝对路径或相对路径就可以直接执行脚本了。
2、bash script-name 或 sh script-name 这是当脚本文件本身没有执行权限时常使用的方法
3、source script-name 或 . script-name 这种方法通常是使用source或 “.”(点号)读入或加载指定的Shell脚本文件,然后依次执行指定的Shell脚本中的语句。这些语句将在当前父 shell 脚本进程中执行(其他几种模式都会启用新的进程执行该脚本进程)。
二,shell语法
1,第一行
Shell脚本在第一行会指出由哪个程序(解释器)来执行脚本中的内容,这一行内容在Linux bash的编程一般为:#!/bin/bash 或 #! /bin/sh bash 与 sh 的区别 , sh 为 bash的软连接,大多数情况下,脚本使用“#!/bin/bash”和“#!/bin/sh”是没有区别的。
2,判断
if 条件内容
then
内容
fi
或者
if 条件判断
then
命令
else
命令
fi
3,循环
for
do
内容
done
4,shell 中的变量
read -p “提示信息” 变量名 #交互式赋值方法
查看变量内容 echo $B 或 echo ${B}
5,赋值时使用引号的作用
双引号:允许通过$符号引用其他变量值
单引号:禁止引用其他变量值,$视为普通字符
反撇号:命令替换,提取命令执行后的输出结果 全局变量的定义方法 export 变量名
6,位置参数
位置参数是一种在调用 Shell 程序的命令行中按照各自的位置决定的变量,是在程序名之后输入的参数。 位置参数之间用空格分隔,Shell取第一个位置参数替换程序文件中的 $1,第二个替换 $2 , 依次类推。$0 是一个特殊变量,它的内容是当前这个shell程序的文件名,所以 $0 不是一个位置参数。
7,预定义变量
预定义变量和环境变量相类似,也是在Shell一开始就定义的变量,不同的是,用户只能根据shell的定义来使用这些变量,所有预定义变量都是由符号“$”和另一个符号组成。 常见的Shell预定义变量有以下几种。
$# :位置参数的数量
$* :所有位置参数的内容
$? :命令执行后返回的状态,0表示没有错误,非0表示有错误
$$ :当前进程的进程号
$! :后台运行的最后一个进程号
$0 :当前执行的进程名
8,数字比较
#! /bin/bash
read x,y
if test $x –eq $y
then
echo “$x=$y”
else
echo “$x!=$y”
fi
执行结果:
[root@localhost bin]#./ test.sh
50 100
50!=100
[root@localhost bin]#./ test.sh
150 150
150= =150
8,逻辑操作
9,运算符
bc也可以进行非交互式的运算,方法是与 echo 一起使用,所以我们就可以写在脚本里面
bc 是UNIX/Linux下的计算器,除了作为计算器来使用,还可以作为命令行计算工具使用
expr 可以计算字符串的长度
echo "scale=3;9+8-6*3/2^2"|bc 其中scale=n,n是保留小数点后几位,6*3/2^2=18/2=4.5
10,文件测试
常用文件测试操作符 | 说明 |
---|---|
-d , d的全拼为 directory | 文件存在且为目录则为真 |
-f , f的全拼为 file | 文件存在且为文件则为真 |
-e , e的全拼为 exists | 文件存在则为真 |
-s ,s的全拼为 size | 文件存在且大小不为0则为真 |
-r ,r的全拼为 read | 文件存在且可读则为真 |
-w ,w的全拼为write | 文件存在且可写则为真 |
-x ,x的全拼为executable | 文件存在且可执行则为真 |
-L ,L的全拼为link | 文件存在且为链接文件则为真 |
f1 -nt f2 ,nt的全拼为 newer than | 文件f1比文件f2新则为真 |
f1 -ot f2 ,ot的全拼为older than | 文件f1比文件f2旧则为真 |
12,整数二元比较操作符
在[]以及test中使用的比较符号 | 在(())和[[]]中使用的比较符号 | 说明 |
---|---|---|
-eq | == 或 = | 相等,全拼为 equal |
-ne | != | 不相等,全拼为 not equal |
-gt | > | 大于,全拼为 greater than |
-ge | >= | 大于等于,全拼为 greater equal |
-lt | < | 小于,全拼为 less than |
-le | <= | 小于等于 ,全拼为less equal |
13,break、continue、exit 循环控制语句
break 、continue在条件语句及循环语句(for、while、if等)中用于控制程序走向;从循环中退出 break 和 continue 命令
break 立即退出循环continue 忽略本循环中的其他命令 继续下一下循环在 shell 编程中有时我们要用到进行无限循环的技巧 也就是说这种循环一直执行,碰到 break 或 continue 命令 这种无限循环通常是使用 true 或false
#!/bin/sh
iscontinue()
{
while true
do
echo -n "Continue?(Y/N)"
read ANSWER
case $ANSWER in
[Yy]) return 0;;
[Nn]) return 1;;
*) echo "Answer Y or N";;
esac
done
}
if iscontinue
then
continue
else
break
fi
exit则用于终止所有语句并退出当前脚本。
14,在shell脚本中调用其他脚本
执行scrapy爬虫和python脚本
#! /bin/sh
cd /home/alinx/
scrapy crawl xx
python3 mytest.py
15,shell 执行选项
-n 测试 shell script 语法结构 只读取 shell script 但不执行
-x 进入跟踪方式 显示所执行的每一条命令 用于调度
-a Tag all variables for export
-c "string" 从 strings 中读取命令
-e 非交互方式
-f 关闭 shell 文件名产生功能
-h locate and remember functions as defind
-i 交互方式
-k 从环境变量中读取命令的参数
-r 限制方式
-s 从标准输入读取命令
-t 执行命令后退出(shell exits)
-u 在替换中如使用未定义变量为错误
-v verbose,显示 shell 输入行
三,makefile
all:
gcc servo.c -o servo
clean:
rm -rf servo servo.o
main:main.o
gcc main.o -o main
main.o:main.c
gcc -c main.c
clean:
rm -rf main.o main
$* 不包括后缀名的当前依赖文件的名称
$+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
$< 第一个依赖文件的名称
$? 所有时间戳比目标文件晚的依赖文件,并以空格分开
$@ 目标文件的完整名称
$^ 所有不重复的目标依赖文件,以空格分开
-: 告诉make命令忽略所有的错误
@: 告诉make在执行命令前不要将改命令显示在标准输出上
在这里简单解释一下makefile中的相关命令:
CC = gcc #声明编译器
CFLAGS = -g -O -Wall #声明编译的选项
OBJ := add.o sub.o main.o #声明依赖的文件
TOPDIR := $(PWD) #声明顶级目录
OBJDIR := $(TOPDIR)/obj #定义编译中间文件的存放的目录
BINDIR := $(TOPDIR)/bin #定义可执行文件的存放目录
BIN := main #定义可执行文件的名称
SUBDIR := add sub main obj #声明所有的子目录
OBJHEAD := $(TOPDIR)/add/add.h $(TOPDIR)/sub/sub.h #声明所有的头文件
OBJLINK := --std=c99 #声明编译时候需要的链接护着其他的选项
export CC TOPDIR OBJDIR BINDIR BIN OBJLINK OBJ #到处所有的全局变量,给次级目录中的makefile只用
all:CHECKDIR $(SUBDIR)
mkdir -p $(SUBDIR) $(BINDIR)
对于makedir中的的选项:
-m 对新建目录设置存取权限。也可以用chmod命令设置。
-p 可以是一个路径名称。此时若路径中的某些目录尚不存在,加上此选项后,系统将自动建立好那些尚不存在的目录, 即一次可以建立多个目录。
make -C $@
当make的目标为all时,
-C $@ 指明跳转到次级目录下读取那里的Makefile;
M=$(PWD) 表明读取完Makefile(次级目录下Makefile)执行完成后返回到当前目录继续读入、执行当前的Makefile( 顶级目录下Makefile)。
clean:
关于clean的规则,在make clean的时候,并不产生目标文件,且没有依赖文件,所以命令都会执行,但如果目录中存在名为“clean”的文件或者目录,则规则没有依赖文件,且clean始终是最新的,所以命令不会被执行,为了避免这个问题,可以使用.PHONY来指明改目标,则将上述的clean部分修改为:
gcc -DLINUX -ICommon/Common Common/Common/*.cpp *.cpp -lpthread -ldl -fPIC-lpthread -ldl -fPIC