让.sh文件变为可执行的脚本文件命令:
1 | chmod 777 xxx.sh |
1.for循环
for循环一般格式为:
1 | for 变量名 in 列表 |
当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的shell命令和语句。in列表可以包含替换、字符串和文件名。in列表是可选的,如果不用它,for循环使用命令行的位置参数。
例如,顺序输出当前列表中的数字:
1 | for loop in 1 2 3 4 5 |
输出:
1 | The value is: 1 |
顺序输出字符串中的字符:
1 | for str in 'This is a string' |
输出:
1 | This is a string |
2.获取当前时间,并进行格式转换的方法
1)原格式输出
1 | time1=$(date) |
输出:2018年 09月 30日 星期日 15:55:15 CST
2)时间串输出
1 | 1 #!bin/bash |
输出:20180930155515
3)格式转换输出
1 | #!bin/bash |
输出:2018-09-30 15:55:15
1 | #!bin/bash |
输出:2018.09.30
注意:
①$(date "")
类似的格式转换时,date后面要留有空格
②time4=$(date "+%Y.%m.%d")
time4变量赋值前后不能有空格
相关变量解释:
Y显示4位年份,如:2018;y显示2位年份,如:18。
m表示月份;M表示分钟。
d表示天;D则表示当前日期,如:1/18/18(也就是2018.1.18)。
H表示小时,而h显示月份。
s显示当前秒钟,单位为毫秒;S显示当前秒钟,单位为秒。
3.获取指定文件夹大小
3.1 获取指定文件夹大小
1 | #/!bin/base |
3.2 获取指定文件大小
1 | #/!bin/base |
4.脚本变量$[#,@,0,1,2,*,$,?]含义
$# 是传给脚本的参数个数
$0 是脚本本身的名字
$1 是传递给该shell脚本的第一个参数
$2 是传递给该shell脚本的第二个参数
$@ 是传给脚本的所有参数的列表
$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
$$ 是脚本运行的当前进程ID号
$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误
$@, $*两者的区别:
相同点:都是引用所有参数
不同点:$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(“ “)包含时,都以”$1” “$2” … “$n” 的形式输出所有参数。但是当它们被双引号(“ “)包含时,”$*“ 会将所有的参数作为一个整体,以”$1 $2 … $n”的形式输出所有参数;”$@” 会将各个参数分开,以”$1” “$2” … “$n” 的形式输出所有参数。
5.if [ $# -ne 1 ];then命令
if [ $# -ne 1 ];then 是什么意思?
$# 是启动脚本时携带的参数个数
-ne 是不等于,这个语句的意思是“如果shell的启动参数不等于1个”
$# 表示提供到shell脚本或者函数的参数总数;
$1 表示第一个参数。
-ne 表示 不等于
另外:
整数比较
-eq 等于,如:if [“$a” -eq “$b” ]
-ne 不等于,如:if [“$a” -ne “$b” ]
-gt 大于,如:if [“$a” -gt “$b” ]
-ge 大于等于,如:if [“$a” -ge “$b” ]
-lt 小于,如:if [“$a” -lt “$b” ]
-le 小于等于,如:if [“$a” -le “$b” ]
< 小于(需要双括号),如:((“$a” < “$b”))
<= 小于等于(需要双括号),如:((“$a” <= “$b”))
大于(需要双括号),如:((“$a” > “$b”))
= 大于等于(需要双括号),如:((“$a” >= “$b”))
另外:$?是shell变量,表示”最后一次执行命令”的退出状态.0为成功,非0为失败.
参考链接:Linux 脚本编写基础知识
6.shell脚本实现scp文件传输
scp是一个基于ssh的Linux环境下传输文件的好工具,但是使用shell脚本调用scp时会面临一个问题,即scp强制要求通过交互方式输入密码,而不像mysql等拥有-u -p选项。下面有两种方法帮助shell脚本跨过输入密码这个障碍。
6.1 建立机器间完全信任关系(这种方式没有操作过,不确定可靠性)
假设需要从机器A传输文件至机器B
1)在机器A上运行
1 | ssh-keygen -t rsa |
上述命令会在~/.ssh/目录生成私钥证书id_rsa和公钥证书id_rsa.pub;
2)将公钥证书id_rsa.pub复制到机器B的用户根目录的.ssh子目录中,再将文件内容append到文件authorized_keys中。
其实只要用一条单行命令就可以完成步骤2,它被commandlinefu.com的用户投票选为十大最酷的Linux单行命令之一:
1 | ssh-copy-id [-i [identity_file]] [user@]machine |
identity_file是公钥证书的路径,默认情况下是~/.ssh/id_rsa.pub.
如果要建立双方向的完全信任关系,还要从机器B到机器A再重复一遍上面的操作。
不过这样的方法并不完美,一是运维成本太高,二是机器间的安全屏障完全消失,安全代价太大,所以强烈推荐第二种方法。
6.2 expect脚本
expect脚本是一种建立在tcl基础上的脚本语言,曝光率不高,却堪称shell脚本的好基友。expect脚本为交互而生,被设计为专门针对交互式程序的工具,常与对telnet、ftp、fsck、rlogin、tip、scp等配合使用。例如:
1 | #! /bin/sh |
这段脚本的含义是监听scp命令,如果输入包含*assword,则输入密码“passwd”;如果输入包含yes/no,输入yes并继续进行交互(exp_continue)。
注:两个用户第一次scp连接时会提示“… Are you sure you want to continue connecting (yes/no)? …”,所以要考虑yes/no的情况。
6.3 使用sshpass免密操作
使用sshpass命令可以在脚本中提前输入密码便于直接运行命令:
eg:
1 | sshpass -p aiidc@2019 scp -r aiidc-parse-rundata-1.0-SNAPSHOT.jar root@172.16.16.184:/root |
注意:在使用sshpass操作ssh命令时,通过ssh连接目标服务器后,如果有多个命令要执行,可将多条命令书写在一条命令上通过&&间隔,比如:
1 | sshpass -p aiidc@2019 ssh root@172.16.16.184 'cd /opt/parse-etl/kafka/ && rm -rf aiidc-parse-rundata-1.0-SNAPSHOT.jar && ls && mv /root/aiidc-parse-rundata-1.0-SNAPSHOT.jar ./' |
该命令的意思连接184服务器后,进入指定目录,先删除jar,然后将新jar移动到目标位置
ssh 用户名@目的主机地址 ‘要执行的命令或者脚本’
注意:
在调用脚本时,必须写全该脚本所在的全路径。
要执行的命令用单引号’ ’扩起来,引号扩起来的命令要和前面的内容写在一行,不能换行。
centos 7 jar包发布服务并开机启动
7.1 jar启动脚本start.sh
1 | #!/bin/sh |
启动的时候会生成pid文件(这个在制作启动服务地方会用到)
注意:start.sh里面路径都要写成绝对路径
7.2 制作启动服务
服务名称:xxx.service
以解析应用为例:parse.service
服务脚本
1 | [Unit] |
需要修改的地方
Description 修改为自己的名字或者描述
PIDFile 修改为自己服务启动后保存的pid文件路径
ExecStart 修改为自己的启动脚本路径
7.3 通过服务启动
将做好的服务拷贝到/etc/systemd/system/路径下
执行systemctl daemon-reload
加入开机启动systemctl enable data-application.service
看到这个表示加入开机自启成功
另:
1 | #通过服务启动程序 |