一般情况下, 成果物只有一个(各模块). 因此开启服务只需简单的 ./成果物名字; 但是很多情况下, 我们都会为自身的模块服务提供一个看门狗进程, 即当服务出现意外而挂掉时候, 希望看门狗进程能够立即将服务拉起来, 而不是让服务处于瘫痪状态. 这时候服务启动时候, 则涉及两个进程. 而且这两个进程的顺序是:
看门狗进程启动ok, 则继续启动模块进程服务; 反之, 则启动服务失败. 如下图所示:
如下示例1, 分别有两个进程hello(打印helo . . . )和world(打印world . . .).
///// hello.c文件内容 gcc hello.c -o hello (进程名hello)
#include
#include
int main()
{
printf("hello ...\n");
return 0;
}
///// world.c文件内容 gcc world.c -o world (进程名world)
#include
#include
int main()
{
printf("world ...\n");
return 0;
}
若不使用“&&”, 那么其shell脚本应该如下. 若hello进程启动成功, 则继续启动world进程, 反之, 则结束.
#!/bin/sh
./hello
if [ $? -eq 0 ]
then
./world
fi
现在修改为使用“&&”命令来替换if. . . else规则. 如下:
#!/bin/sh
# 如果./hello命令启动成功(返回真, 即$? = 0), 则继续启动 ./world进程; 若失败, 则结束.
./hello && ./world
为了测试“&&”的使用规则, 现在启动一个不存在的进程hello_1. 观察其结果:
#!/bin/sh
./hello_1 && ./world
因为不存在hello_1进程, 因此直接报错, hello和world都没有启动和打印. 报错提示如下:
start.sh: line 2: ./hello_1: No such file or directory
对于Shell环境中“||”命令的功能. 若命令1执行失败, 不会退出, 转而执行命令2. 若命令1执行成功, 则不会执行命令2.
先来一个命令1执行成功的示例.
///// start.sh 脚本
#!/bin/sh
./hello || ./world
打印结果:
hello . . .
现在修改start.sh脚本. 其中命令1不存在, 然后执行:
///// start.sh 脚本
#!/bin/sh
# hello_1成果物是不存在的. 所以hello_1执行失败. 观察world执行情况.
./hello_1 || ./world
打印结果:
start.sh: line 2: ./hello_1: No such file or directory
world . . .
命令1执行失败并报错. 但并不影响脚本的继续执行. world进程仍然执行并打印数据了.
对于shell, 可以在一行中指定要依次执行的一系列命令. 各命令之间用分号(";")隔开; 这些命令依次执行.如下示例:
lixiaogang5@Cpl-Backend-General-14-115:~/work/test/06_29$ ls
1.sh hello hello.c start.sh world world.c
# 使用pwd;ls两个组合命令来查看当前位置和文件列表.
lixiaogang5@Cpl-Backend-General-14-115:~/work/test/06_29$ pwd;ls
/data1/lixiaogang5/work/test/06_29
1.sh hello hello.c start.sh world world.c
所谓进程列表, 即命令分组. 若只是简单的将一个或多个命令使用分号隔开写在一行中, 并不会成为进程列表. 想要成为进程列表, 有两种方式, 分别是: 使用圆括号() 或 使用花括号{}来将命令放入其中. 并在每个命令的末尾加上分号(";"). 语法格式如下:
{commond 1; commond 2; commond 3} /*使用花括号方式*/
(commond 1; commond 2; commond 3}) /*使用圆括号方式*/
尽管使用圆括号和花括号方式都可以达到进程列表的目的与效果. 但是两者是有区别的. 圆括号方式会生成一个子shell来执行对应的命令; 而使用花括号方式进行命令分组时候, 并不创建子shell.
为了验证是否生产子shell, 可以使用环境变量 BASH_SUBSHELL. 若返回0, 则表示没有创建子shell; 反之, 若返回1或是其他数字, 则表示创建了子shell进程.
lixiaogang5@Cpl-Backend-General-14-115:~/work/test/06_29$ (pwd; ls; echo $BASH_SUBSHELL)
/data1/lixiaogang5/work/test/06_29
1.sh hello hello.c start.sh world world.c
1 //echo $BASH_SUBSHELL 返回结果大于0, 表示创建了子shell进程环境.
使用花括号方式来创建进程列表, 如下:
lixiaogang5@Cpl-Backend-General-14-115:~/work/test/06_29$ {pwd; ls; echo $BASH_SUBSHELL}
/data1/lixiaogang5/work/test/06_29
1.sh hello hello.c start.sh world world.c
0 //使用花括号方式, echo $BASH_SUBSHELL 返回结果为0, 表示没有创建子shell.
圆括号或花括号创建进程列表时候, 内部还可以嵌套圆括号或花括号. 如下:
lixiaogang5@Cpl-Backend-General-14-115:~/work/test/06_29$ (pwd; ls; (echo $BASH_SUBSHELL))
/data1/lixiaogang5/work/test/06_29
1.sh hello hello.c start.sh world world.c
2 //这个时候环境变量BASH_SUBSHELL为2, 表示创建了2个子shell环境》
很多时候, 对于一些比较耗时的操作, 可以另起一个子shell环境并在其中去执行. 模拟多进程的场景效果. 如下所示:
lixiaogang5@Cpl-Backend-General-14-115:~/work/test/06_29$ ./hello && ./world || (echo "execute failed.")
hello ...
world ...
# 执行失败范例
lixiaogang5@Cpl-Backend-General-14-115:~/work/test/06_29$ ./hello_1 && ./world || (echo "execute failed.")
bash: ./hello_1: No such file or directory
execute failed.