shell脚本编写遇到的问题--循环

shell脚本编写遇到的问题

0 背景

工作中需要修补数据,大概半年的数据;跑数据是scala脚本+python脚本,如果手动补充数据,需要运行180次…
于是,shell脚本搞起来…

1 规划思路

此处省略100字;最后的思路:
首先传日期参数,分为开始+结束;毕竟补充数据是一个费时间的活,跑一天的数据就要很久,180天,不拆分开,要爆炸的
其次是利用循环,每天跑一次scala脚本+python脚本
同时需要传递一些基本参数,比如路径

shell脚本中涉及相关操作

2.0 指定格式!(很重要)

在创建shell脚本文件时,必须在文件的第一行指定要使用的shell.其格式为:
#!/bin/bash
参见<Linux命令行与shell脚本编程大全>11.2节
井号("#")用作注释行

2.1 传参数
sh x.sh 20200601 20200631

是我希望实现的在linux或者git上运行shell脚本的形式;这里的20200601是start_day,20200631是end_day
那么我就需要利用这两个参数作为我的起始终止日期

bash shell会将一些称为位置参数( positional parameter)的特殊变量分配给输入到命令行中的
所有参数.这也包括shell所执行的脚本名称.位置参数变量是标准的数字: $0是程序名, $1是第
一个参数, $2是第二个参数,依次类推,直到第九个参数$9.
参见<Linux命令行与shell脚本编程大全>14.1节

sday=$1
eday=$2

注意这里的sday和eday,是我自己定义的用户变量.
shell脚本还允许在脚本中定义和使用自己的变量.定义变量允许临时存储数
据并在整个脚本中使用,从而使shell脚本看起来更像一个真正的计算机程序.

2.2 print参数

你可能想要添加自己的文本消息来告诉脚本用户脚本正在做什么.
换句话,就是你想打印一下结果,print一下;
可以通过echo命令来实现这一点.如果在echo命令后面加上了一个字符串,该命令就能显示出这个文本字符串.

echo $sday
echo $eday

有同学要问了,这里的$又是啥

2.3赋值

shell脚本中最有用的特性之一就是可以从命令输出中提取信息,并将其赋给变量.把输出赋
给变量之后,就可以随意在脚本中使用了.
$()格式是命令替换的一种,允许你将shell命令的输出赋给变量.

以上参见<Linux命令行与shell脚本编程大全> 11.4节
这里已经实现了基本功能

#!/bin/sh
#每天调度IO13接口
#sh x.sh 20200601, 20200631;需要按照月份来调度

sday=$1
eday=$2

echo $sday
echo $eday

jar_path="XXX"
2.4循环

shell脚本也具备结构化命令,比如 if&else,for,while 循环等,逻辑完全一样
这里使用for循环
bash shell中for命令的基本格式.

for var in list
do
	commands
done
注意事项

01:commands部分需要缩进
02:在list参数中,你需要提供迭代中要用到的一系列值;比如python里面,for i in range(10); for each in []; for i in "zhangsan"等;
var好说,关键是list.python里面可以充当list的变量是很多的.
目前我了解的,也是从<Linux命令行与shell脚本编程大全>13.1节了解的如下
第一种

for test in Alabama Alaska Arizona Arkansas California Colorado
do
	echo The next state is $test
done

这里,直接用a b c的形式,充当list;注意,空格,而不是逗号,充当间隔符号
当然,这里的var也可以用"$var"来书写

第二种
书中还提到了复杂值,比如dont’t know 中的’号等,暂且不提
第三种,变量

list="Alabama Alaska Arizona Arkansas Colorado"
for state in $list
do
	echo "Have you ever visited $state?"
done

这种其实也比较常见
第四种,从命令读取值

file="states"
for state in $(cat $file)
do
	echo "Visit beautiful $state"
done

用了cat命令来输出文件states的内容;简单的脚本一般用不到

但是这里的都不是我想要的,因为我想传递一个sday和eday,剩下的是range范围,因此需要用其他的方式来循环

第五种,C语言形式
<Linux命令行与shell脚本编程大全>13.2节 C 语言的 for 命令
以下是bash中C语言风格的for循环的基本格式.

for (i = 0; i < 10; i++)
{
	printf("The next number is %d\n", i);
}

以下例子是在bash shell程序中使用C语言风格的for命令.

$ cat test8
#!/bin/bash
# testing the C-style for loop
for (( i=1; i <= 10; i++ ))
do
	echo "The next number is $i"
done

还可以使用多个变量

#!/bin/bash
# multiple variables
for (( a=1, b=10; a <= 10; a++, b-- ))
do
	echo "$a - $b"
done

这里不赘述了

截止这里可以得到

for (( c = $sday; c <= $eday; c++))
do
    echo $c
done
2.5 调用spark和python脚本

在shell里面调用python脚本以及传参数,都很简单

python xx.py ${c}

注意这里的{$c}是for循环的c

至于spark-shell调用的scala脚本,因为需要传参数进去,所以麻烦一些

spark-shell --jars xxx.jar -i <( echo 'val mday = "'$c'"'; cat xxx.scala)

参考链接:https://www.bbsmax.com/A/QV5ZjeYw5y/
注意,这里的-i <( echo ‘val mday = "’$c’"’; cat xxx.scala)是需要利用spark-shell运行的内容;
这里首先运行一个echo,从而把想要的参数传进去;这样脚本里面就可以调用这个mday了

如果有同学有其他传参方式,麻烦评论区评论,大家相互学习~

3 未曾设想的bug

3.1 脚本格式问题

linux shell脚本无法执行,报错syntax error near unexpected token ‘$’\r’'解决方法
脚本是在win10+sublime编辑;传到服务器上,运行的时候,报错
脚本检查了没有错误的,为什么会有这个提示呢。
使用vi 命令打开检查下脚本

vi xxx.sh

还是没什么问题呢
这个脚本是从txt文件中粘贴出来的,会不会是格式的问题
于是抱着这个问题查找的态度。我们再次执行下vim命令,不过需要加参数了

vim -b XXX.sh

果然如此,在复制进来后,怎么每行后面都多了"^M"
这里我们来进行快速处理

sed -i 's/\r//g' xxx.sh

就可以了
参考链接https://blog.csdn.net/xzm5708796/article/details/88344074
类似的问题还有Shell脚本$’\r’: command not found问题

3.2 语法错误,syntax error: operand expected

运行的时候,报错语法问题

a.sh: line 12: ((: c = : syntax error: operand expected (error token is "= ")

但是我已经check过了
最后同事告诉我
在开头加上一句

set +o posix

经过查询,是shell脚本的格式要求…

4,最后的脚本

#!/bin/sh
#每天调度IO13接口
#sh x.sh 20200601, 20200631;需要按照月份来调度
set +o posix

sday=$1
eday=$2
echo $sday
echo $eday
jar_path="/target"
for (( c = $sday; c <= $eday; c++))
do
    echo $c
    spark-shell --jars aaa.jar -i <( echo 'val mday = '$c; cat     bbb.scala)
    python ccc.py ${c}
    sleep 10s
done

完结撒花~

参考

参考书籍:<Linux命令行与shell脚本编程大全>
参考链接:
[1]: https://www.bbsmax.com/A/QV5ZjeYw5y/
[2]: https://blog.csdn.net/xzm5708796/article/details/88344074
[3]: https://mermaidjs.github.io/
[4]: http://adrai.github.io/flowchart.js/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值