From 87e02f78b93c86fdfa14a7f30ffc7f9912f5b66f Mon Sep 17 00:00:00 2001 From: root Date: Thu, 24 Oct 2019 18:59:15 +0800 Subject: [PATCH] --- Linux_man_cn/awk.md | 37 ++- Linux_man_cn/cd.md | 2 +- Linux_man_cn/dmesg.md | 2 - Linux_man_cn/exit.md | 52 +-- Linux_man_cn/gdb.md | 2 +- Linux_man_cn/less.md | 3 +- Linux_man_cn/ls.md | 2 +- Linux_man_cn/lscpu.md | 6 +- Linux_man_cn/mkdir.md | 1 - Linux_man_cn/more.md | 2 - Linux_man_cn/mv.md | 7 +- Linux_man_cn/pwd.md | 1 - Linux_man_cn/telnet.md | 4 +- Linux_man_cn/touch.md | 12 +- Linux_man_cn/uniq.md | 2 +- Py3Scripts/AliDDNS.py | 45 +++ Py3Scripts/CloudXNS_APISDK.py | 485 ++++++++++++++++++++++++++++ Py3Scripts/NumberToChinese.py | 44 +++ Py3Scripts/get_Public_Ip.py | 56 ++++ Py3Scripts/morsecode.py | 34 ++ Py3Scripts/parse_aliyun_oss.py | 29 ++ Py3Scripts/万年历假期.py | 38 +++ Py3Scripts/免费天气.py | 37 +++ Py3Scripts/墨迹天气和新闻.py | 23 ++ Py3Scripts/新闻头条.py | 20 ++ ShellScripts/read-only-fs.sh | 313 ++++++++++++++++++ ShellScripts/swap.sh | 90 ++++++ ShellScripts/syscheck.sh | 205 ++++++++++++ 28 files changed, 1459 insertions(+), 95 deletions(-) create mode 100644 Py3Scripts/AliDDNS.py create mode 100644 Py3Scripts/CloudXNS_APISDK.py create mode 100644 Py3Scripts/NumberToChinese.py create mode 100644 Py3Scripts/get_Public_Ip.py create mode 100644 Py3Scripts/morsecode.py create mode 100644 Py3Scripts/parse_aliyun_oss.py create mode 100644 Py3Scripts/万年历假期.py create mode 100644 Py3Scripts/免费天气.py create mode 100644 Py3Scripts/墨迹天气和新闻.py create mode 100644 Py3Scripts/新闻头条.py create mode 100644 ShellScripts/read-only-fs.sh create mode 100644 ShellScripts/swap.sh create mode 100644 ShellScripts/syscheck.sh diff --git a/Linux_man_cn/awk.md b/Linux_man_cn/awk.md index 7a926b7..417caac 100644 --- a/Linux_man_cn/awk.md +++ b/Linux_man_cn/awk.md @@ -278,7 +278,6 @@ awk 'BEGIN{a="b";arr[0]="b";arr["b"]="c";print (a in arr);}' # 输出:1 * !级别越高越优先 * 级别越高越优先 - ## awk高级输入输出 ```bash @@ -649,16 +648,16 @@ strftime日期和时间格式说明符 ## 文件间隔 ```bash -# 双空间文件 -awk'1; {print“”}' -awk'BEGIN {ORS =“\ n \ n”}; 1' +# 文件添加两个空格 +awk '1;{print“”}' +awk 'BEGIN{ORS =“\n\n”};1' # 双空间的文件已经有空行。输出文件,在文本行之间应该包含不超过一个空白行 # 注意:在Unix系统上,只有CRLF(\ r \ n)的DOS行是经常被视为非空白,因此仅'NF'将返回TRUE awk'NF {print $ 0“\ n”}' -# 三重空间文件 -awk'1; {print“\ n”}' +# 文件添加三个空格 +awk '1;{print“\n”}' ``` ## 编号和计算 @@ -723,7 +722,7 @@ gawk --re-interval'BEGIN {while(a ++ <49)s = s“”}; {sub(/ ^。{6} /, ## 阵列创作 -```sh +```bash #接下来的2个条目不是单行脚本,而是技术 #非常方便,因此在这里值得一试 @@ -738,9 +737,9 @@ for(i = 1; i <= 12; i ++)mdigit [month [i]] = i ``` -## 文本转换和替换: +## 文本转换和替换 -```sh +```bash #在UNIX环境中:将DOS换行符(CR / LF)转换为Unix格式 awk'{sub(/ \ r $ /,“”)}; 1'#假设每行都以Ctrl-M结尾 @@ -773,15 +772,15 @@ awk'{$ 1 = $ 1}; 1'#也会删除字段之间的额外空间 awk'{sub(/ ^ /,“”)}; 1' #将所有文本均匀对齐到79列宽度 -awk'{printf'%79s \ n“,$ 0}'文件* +awk '{printf'%79s \ n“,$ 0}'文件* #将所有文字放在79个字符的宽度上 -awk'{l = length(); s = int((79-1)/ 2); printf“%”(s + l)“s \ n”,$ 0}'文件* +awk '{l = length(); s = int((79-1)/ 2); printf“%”(s + l)“s \ n”,$ 0}'文件* #在每行上用“bar”代替(查找并替换)“foo” -awk'{sub(/ foo /,“bar”)}; 1'#只替换第一个实例 -gawk'{$ 0 = gensub(/ foo /,“bar”,4)}; 1'#只替换第四个实例 -awk'{gsub(/ foo /,“bar”)}; 1'#将所有实例替换成一行 +awk '{sub(/ foo /,“bar”)}; 1'#只替换第一个实例 +gawk '{$ 0 = gensub(/ foo /,“bar”,4)}; 1'#只替换第四个实例 +awk '{gsub(/ foo /,“bar”)}; 1'#将所有实例替换成一行 #将“foo”替换为“bar”,仅用于包含“baz” awk'/ baz / {gsub(/ foo /,“bar”)}; 1' @@ -822,7 +821,7 @@ awk'ORS = NR%5?“,”:“\ n”'文件 ## 选择性印刷某些线条 -```sh +```bash #打印前10行文件(模拟“head”的行为) awk'NR <11' @@ -887,13 +886,13 @@ awk'NR == 52' awk'NR == 52 {print; exit}'#在大文件上效率更高 #打印两个正则表达式之间的文件部分(含) -awk'/爱荷华州/,/蒙大拿州/'#区分大小写 +awk'/Iowa/,/Montana/'#区分大小写 ``` ## 选择性删除某些行 -```sh +```bash # 删除文件中的所有空白行(与“grep”。'相同) awk NF @@ -927,9 +926,9 @@ sed's/- -.*$//g' access.log|sort|uniq -c|sort -rn -k1 ``` -## 打印行号和内容: +## 打印行号和内容 -```sh +```bash awk '{print NR":"$0}' diff --git a/Linux_man_cn/cd.md b/Linux_man_cn/cd.md index 1afc0b1..18d9b66 100644 --- a/Linux_man_cn/cd.md +++ b/Linux_man_cn/cd.md @@ -19,4 +19,4 @@ cd .. # 返回上级目录(若当前目录为“/“,则执行 cd ../.. # 返回上两级目录 cd !$ # 把上个命令的参数作为cd参数使用 cd dir && command # 进入目录dir,执行命令command然后回到当前目录 -``` \ No newline at end of file +``` diff --git a/Linux_man_cn/dmesg.md b/Linux_man_cn/dmesg.md index 900c4f6..3e3f80f 100644 --- a/Linux_man_cn/dmesg.md +++ b/Linux_man_cn/dmesg.md @@ -60,5 +60,3 @@ dmesg | grep sda # 查看硬盘基础信息 ``` - - diff --git a/Linux_man_cn/exit.md b/Linux_man_cn/exit.md index 9bb5565..1a587c3 100644 --- a/Linux_man_cn/exit.md +++ b/Linux_man_cn/exit.md @@ -1,60 +1,18 @@ -exit -=== - -退出当前的shell +# exit ## 说明 **exit命令** 同于退出shell,并返回给定值。在shell脚本中可以终止当前脚本执行。执行exit可使shell以指定的状态值退出。若不设置状态值参数,则shell以预设值退出。状态值0代表执行成功,其他值代表执行失败 -## 选项 - -``` -exit(参数) -``` - -### 参数 - -返回值:指定shell返回值 - ## 实例 -退出当前shell: - -``` -[root@localhost ~]# exit -logout -``` - -在脚本中,进入脚本所在目录,否则退出: - -``` -cd $(dirname $0) || exit 1 -``` +```bash +cd $(dirname $0) || exit 1 # 在脚本中,进入脚本所在目录,否则退出 +trap "rm -f tmpfile; echo Bye." exit # 在脚本中,退出时删除临时文件 -在脚本中,判断参数数量,不匹配就打印使用方式,退出: - -``` +# 在脚本中,判断参数数量,不匹配就打印使用方式,退出 if [ "$#" -ne "2" ]; then echo "usage: $0 " exit 2 fi ``` - -在脚本中,退出时删除临时文件: - -``` -trap "rm -f tmpfile; echo Bye." EXIT -``` - -检查上一命令的退出码: - -``` -./mycommand.sh -EXCODE=$? -if [ "$EXCODE" == "0" ]; then - echo "O.K" -fi -``` - - diff --git a/Linux_man_cn/gdb.md b/Linux_man_cn/gdb.md index 7ced79d..ae966b8 100644 --- a/Linux_man_cn/gdb.md +++ b/Linux_man_cn/gdb.md @@ -34,6 +34,6 @@ ```bash g++ -g hello.cpp -o hello # 对C/C++程序的调试,需要在编译前就加上-g选项 gdb hello # 调试可执行文件hello - +gdb --args 程序或命令 # 在gdb下启动程序 ``` diff --git a/Linux_man_cn/less.md b/Linux_man_cn/less.md index 7d7fe98..c79d5e9 100644 --- a/Linux_man_cn/less.md +++ b/Linux_man_cn/less.md @@ -6,7 +6,7 @@ ## 选项 -``` +```markdown -e:文件内容显示完毕后,自动退出 -f:强制显示文件 -g:不加亮显示搜索到的所有关键词,仅显示当前显示的关键字,以提高显示速度 @@ -16,4 +16,3 @@ -S:在单行显示较长的内容,而不换行显示 -x<数字>:将TAB字符显示为指定个数的空格字符 ``` - diff --git a/Linux_man_cn/ls.md b/Linux_man_cn/ls.md index 0b8361e..3e57ba6 100644 --- a/Linux_man_cn/ls.md +++ b/Linux_man_cn/ls.md @@ -62,4 +62,4 @@ ls -l | awk '/^-/' | wc -l # 统计一个目录中的文件个数 for i in `ls *test.log`;do mv $i `echo ${i//test/}`;done # 批量将*test.log文件重命名去掉test字符 ls -lrt | awk '{print $9}'|xargs file|grep ELF| awk '{print $1}'|tr -d ':' # 查找当前目录所有二进制文件[尽量避免解析ls输出] -``` \ No newline at end of file +``` diff --git a/Linux_man_cn/lscpu.md b/Linux_man_cn/lscpu.md index 4a19675..310a6b8 100644 --- a/Linux_man_cn/lscpu.md +++ b/Linux_man_cn/lscpu.md @@ -36,8 +36,8 @@ ## 实例 ```bash -lscpu - -``` +# CPUs = Threads per core X cores per socket X sockets +lscpu | grep -E '^Thread|^Core|^Socket|^CPU\(' # 查看cpu线程数、核心数等 +``` diff --git a/Linux_man_cn/mkdir.md b/Linux_man_cn/mkdir.md index 6639dc6..a668778 100644 --- a/Linux_man_cn/mkdir.md +++ b/Linux_man_cn/mkdir.md @@ -25,4 +25,3 @@ Mandatory arguments to long options are mandatory for short options too. ```bash mkdir -p -m 700 /usr/meng/test # 在目录`/usr/meng`下建立子目录test,并且只有文件主有读、写和执行权限,其他人无权访问 ``` - diff --git a/Linux_man_cn/more.md b/Linux_man_cn/more.md index ebcbbcf..8432f41 100644 --- a/Linux_man_cn/more.md +++ b/Linux_man_cn/more.md @@ -38,5 +38,3 @@ more -dc file # 显示文件file的内容,但在显示之前先清屏,并且在屏幕的最下方显示完核的百分比 more -c -10 file # 显示文件file的内容,每10行显示一次,而且在显示之前先清屏 ``` - - diff --git a/Linux_man_cn/mv.md b/Linux_man_cn/mv.md index bb73f40..e8d58b4 100644 --- a/Linux_man_cn/mv.md +++ b/Linux_man_cn/mv.md @@ -7,8 +7,8 @@ mv命令可以用来将源文件移至一个目标文件中,或将一组文件移至一个目标目录中。源文件被移至目标文件有两种不同的结果: -1. 如果目标文件是到某一目录文件的路径,源文件会被移到此目录下,且文件名不变 -2. 如果目标文件不是目录文件,则源文件名(只能有一个)会变为此目标文件名,并覆盖己存在的同名文件。如果源文件和目标文件在 +1. 如果目标文件是到某一目录文件的路径,源文件会被移到此目录下,且文件名不变 +2. 如果目标文件不是目录文件,则源文件名(只能有一个)会变为此目标文件名,并覆盖己存在的同名文件。如果源文件和目标文件在 同一个目录下,mv的作用就是改文件名。当目标文件是目录文件时,源文件或目录参数可以有多个,则所有的源文件都会被移至目标文件 中。所有移到该目录下的文件都将保留以前的文件名 @@ -48,6 +48,3 @@ the VERSION_CONTROL environment variable. Here are the values: ```bash mv -- ``` - - - diff --git a/Linux_man_cn/pwd.md b/Linux_man_cn/pwd.md index 85e609a..eeb1ddf 100644 --- a/Linux_man_cn/pwd.md +++ b/Linux_man_cn/pwd.md @@ -17,4 +17,3 @@ ```bash ``` - diff --git a/Linux_man_cn/telnet.md b/Linux_man_cn/telnet.md index 6c55c13..af3b776 100644 --- a/Linux_man_cn/telnet.md +++ b/Linux_man_cn/telnet.md @@ -9,7 +9,7 @@ ```markdown 用法:telnet [-4] [-6] [-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user] - [-n tracefile] [-b hostalias ] [-r] + [-n tracefile] [-b hostalias ] [-r] [host-name [port]] -8:允许使用8位字符资料,包括输入与输出 @@ -38,5 +38,3 @@ telnet 192.168.2.10 ``` - - diff --git a/Linux_man_cn/touch.md b/Linux_man_cn/touch.md index a5a6c34..fb3f1c0 100644 --- a/Linux_man_cn/touch.md +++ b/Linux_man_cn/touch.md @@ -10,12 +10,12 @@ ```markdown 用法:touch [选项]... 文件.. --a 只更改访问时间 --c, --no-create 不创建任何文件 --d, --date=字符串 使用指定字符串表示时间而非当前时间 --f (忽略) --h, --no-dereference 会影响符号链接本身,而非符号链接所指示的目的地,(当系统支持更改符号链接的所有者时,此选项才有用) --m 只更改修改时间 +-a 只更改访问时间 +-c, --no-create 不创建任何文件 +-d, --date=字符串 使用指定字符串表示时间而非当前时间 +-f (忽略) +-h, --no-dereference 会影响符号链接本身,而非符号链接所指示的目的地,(当系统支持更改符号链接的所有者时,此选项才有用) +-m 只更改修改时间 -r, --reference=FILE 用参考文件的时间取代当前时间 -t STAMP 使用指定的[[CC]YY]MMDDhhmm[.ss]时间取代当前时间 --time=WORD change the specified time: diff --git a/Linux_man_cn/uniq.md b/Linux_man_cn/uniq.md index d48ac4e..024bb68 100644 --- a/Linux_man_cn/uniq.md +++ b/Linux_man_cn/uniq.md @@ -25,7 +25,7 @@ Mandatory arguments to long options are mandatory for short options too. -s, --skip-chars=N 忽略比较指定的字符 -u, --unique 仅显示出一次的行列 -z, --zero-terminated end lines with 0 byte, not newline --w, --check-chars=N 对每行第N 个字符以后的内容不作对照;即指定要比较的字符 +-w, --check-chars=N 对每行第N 个字符以后的内容不作对照;即指定要比较的字符 若域中为先空字符(通常包括空格以及制表符),然后非空字符,域中字符前的空字符将被跳过 diff --git a/Py3Scripts/AliDDNS.py b/Py3Scripts/AliDDNS.py new file mode 100644 index 0000000..71cf36b --- /dev/null +++ b/Py3Scripts/AliDDNS.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- +import os +from aliyunsdkcore import client +from aliyunsdkcore.request import RpcRequest + +product = "Domain" +version = "2016-05-11" +accesskey = "XXXXXXXXXXXXXXXXXXXX" # 请替换成自己的accesskey +accesspasswd = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX" # 请替换成自己的accesspasswd + + +def getip(): + return os.popen("curl http://members.3322.org/dyndns/getip -s").read().replace('\n', '').replace('\r\n', '') + + +def getDNSrecords(): + global product, version, accesskey, accesspasswd + clt = client.AcsClient(accesskey, accesspasswd, 'cn-hangzhou') + request = RpcRequest('Alidns', '2015-01-09', 'DescribeDomainRecords') + request.add_query_param("DomainName", "XXXXXXXXXXXXXXX") # 请替换成自己的域名 + request.set_accept_format('json') + response = clt.do_action_with_exception(request) + return eval(response.replace('false', '0')) + + +def setDNSrecord(record, ip): + global product, version, accesskey, accesspassw + clt = client.AcsClient(accesskey, accesspasswd, 'cn-hangzhou') + request = RpcRequest('Alidns', '2015-01-09', 'UpdateDomainRecord') + request.add_query_param("RecordId", record['RecordId']) + request.add_query_param("RR", record['RR']) + request.add_query_param("Type", record['Type']) + request.add_query_param("Value", ip) + request.set_accept_format('json') + response = clt.do_action_with_exception(request) + print(response) + + +if __name__ == "__main__": + ip = getip() + print(ip) + recordlist = getDNSrecords() + for record in recordlist["DomainRecords"]["Record"]: + setDNSrecord(record, ip) diff --git a/Py3Scripts/CloudXNS_APISDK.py b/Py3Scripts/CloudXNS_APISDK.py new file mode 100644 index 0000000..9bd58b7 --- /dev/null +++ b/Py3Scripts/CloudXNS_APISDK.py @@ -0,0 +1,485 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import hashlib +import time +import json +import urllib +from urllib import request + + +class CloudXNS_API(): + api_key = None + secret_key = None + debug_log = False + + def __init__(self, api_key=None, secret_key=None, debug_log=False): + self.api_key = api_key + self.secret_key = secret_key + self.debug_log = debug_log + + def print_debug(self, msg): + if self.debug_log != False: + print(msg) + + def json_strtodict(self, json_str): + jsonData = {} + try: + if len(json_str) != 0: + jsonData = json.loads(json_str) + except Exception as e: + self.print_debug(e) + finally: + return jsonData + + # 计算api头数据 + def get_api_headers(self, URL, BODY): + API_REQUEST_DATE = time.strftime('%a %b %d %H:%M:%S %Y', + time.localtime()) + API_HMAC = hashlib.md5(( + self.api_key + URL + BODY + API_REQUEST_DATE + self.secret_key).encode()).hexdigest() + headers = { + 'Content-Type': 'application/json', + 'user-agent': 'CloudXNS-Python/v3', + 'API-KEY': self.api_key, + 'API-REQUEST-DATE': API_REQUEST_DATE, + 'API-HMAC': API_HMAC, + 'API-FORMAT': 'json', + } + return headers + + def urlopen(self, URL, BODY='', METHOD='GET'): + strdata = '' + try: + req = urllib.request.Request(URL) + req.method = METHOD + if len(BODY) != 0: + req.data = BODY.encode('UTF-8', 'ignore') + resp = urllib.request.urlopen(req) + strdata = resp.read().decode('UTF-8', 'ignore') + except urllib.error.HTTPError as e: + self.print_debug(e) + pass + except urllib.error.URLError as e: + self.print_debug(e) + pass + except Exception as e: + self.print_debug(e) + pass + finally: + return strdata + + def urlopen_api(self, URL, BODY, METHOD='GET'): + strdata = '' + try: + req = urllib.request.Request(URL, headers=self.get_api_headers(URL, + BODY)) + req.method = METHOD + if len(BODY) != 0: + req.data = BODY.encode('UTF-8', 'ignore') + resp = urllib.request.urlopen(req) + strdata = resp.read().decode('UTF-8', 'ignore') + except urllib.error.HTTPError as e: + self.print_debug(e) + pass + except urllib.error.URLError as e: + self.print_debug(e) + pass + except Exception as e: + self.print_debug(e) + pass + finally: + return strdata + + """ + 功能 域名列表 + HTTP 请求方式 GET + URL https://www.cloudxns.net/api2/domain + :return: String + """ + + def domain_list(self): + url = 'https://www.cloudxns.net/api2/domain' + body = '' + strdata = self.urlopen_api(url, body) + # json_strtodict + return strdata + + """ + 功能 主机记录 + HTTP 请求方式 GET + URL https://www.cloudxns.net/api2/host/:domain_id?offset=:offset&row_num=:row_num + 请求参数: + 参数名称 类型 必填 描述 + domain_id Integer 是 域名ID + offset Integer 否 记录开始的偏移,第一条记录为 0,依次类推 + row_num Integer 否 要获取的记录的数量,比如获取 30 条,则为 30,最大可取 2000条 + :return: String + """ + + def domain_host_list(self, domain_id, offset=0, row_num=30, hostname=None): + if row_num > 2000: + row_num = 2000 + url = 'https://www.cloudxns.net/api2/host/' + str( + domain_id) + '?offset=' + str(offset) + '&row_num=' + str( + row_num) + if hostname != None: + url += '&host_name=' + hostname + body = '' + strdata = self.urlopen_api(url, body) + return strdata + + """ + 功能 暂停、启用解析记录 + 参数名称 类型 必填 描述 + domain_id Integer 是 域名ID + host_id Integer 是 主机记录ID + pause_record bool 是 暂停还是启用 + """ + + def domain_host_record_pause(self, domain_id, host_id, pause_record=False): + url = 'https://www.cloudxns.net/api2/record/pause' + object_body = {} + object_body['id'] = str(host_id) + object_body['domain_id'] = str(domain_id) + # 0暂停1启用 + if pause_record == False: + object_body['status'] = str(0) + else: + object_body['status'] = str(1) + body = json.dumps(object_body) + strdata = self.urlopen_api(url, body, 'POST') + return strdata + + """ + 功能 删除主机记录 + HTTP 请求方式 GET + URL https://www.cloudxns.net/api2/host/:id + 请求参数: + 参数名称 类型 必填 描述 + host_id Integer 是 主机记录id + :return: String + """ + + def domain_host_delete(self, domain_host_id): + url = 'https://www.cloudxns.net/api2/host/' + str(domain_host_id) + body = '' + strdata = self.urlopen_api(url, body, 'DELETE') + return strdata + + """ + 功能 获取解析记录列表 + HTTP 请求方式 GET + URL https://www.cloudxns.net/api2/record/:domain_id?host_id=0&offset=:offset&row_num=:row_num + URL 参数说明 + domain_id:域名 id + host_id:主机记录 id(传 0 查全部) + offset:记录开始的偏移,第一条记录为 0,依次类推,默认取 0 + row_num:要获取的记录的数量, 比如获取 30 条, 则为 30,最大可取 2000 + 条,默认取 30 条. + :return: + code int 请求状态,详见附件 code 对照表 + message String 操作信息,提示操作成功或错误信息 + total int 总记录条数 + offset int 记录开始的偏移 + row_num int 要获取的记录的数量 + data array 记录列表 + record_id: 解析记录 id + host_id:主机记录 id + host:主机记录名 + line_id:线路 ID + line_zh:中文名称 + line_en:英文名称 + mx:优先级 + Value:记录值 + Type:记录类型 + Status:记录状态(ok 已生效 userstop 暂停) + create_time:创建时间 + update_time:更新时间 + """ + + def domain_host_record_list(self, domain_id, host_id=0, offset=0, + row_num=30, host_name=None): + if row_num > 2000: + row_num = 2000 + #:domain_id?host_id=0&offset=:offset&row_num=:row_numURL + if host_name == None: + url = 'https://www.cloudxns.net/api2/record/' + str( + domain_id) + '?host_id=' + str(host_id) \ + + '&offset=' + str(offset) + '&row_num=' + str(row_num) + else: + url = 'https://www.cloudxns.net/api2/record/' + str( + domain_id) + '?host_name=' + str(host_name) \ + + '&offset=' + str(offset) + '&row_num=' + str(row_num) + + body = '' + strdata = self.urlopen_api(url, body) + return strdata + + """ + 功能 添加解析记录 + HTTP 请求方式 GET + URL https://www.cloudxns.net/api2/record + 请求参数: + 参数名称 类型 必填 描述 + domain_id Integer 域名 id + host_name String 主机记录名称 如 www, 默认@ + value String 记录值, 如IP:8.8.8.8,CNAME:cname.cloudxns.net., MX: mail.cloudxns.net. + type String 记录类型,通过 API 获得记录类型,大写英文,比如:A + mx Integer 优先级,范围 1-100。当记录类型是 MX/AX/CNAMEX 时有效并且必选 + ttl Integer TTL,范围 60-3600,不同等级域名最小值不同 + line_id Integer 线路id,(通过 API 获得记录线路 id) + :return: String + """ + + def domain_host_record_add(self, domain_id, host, host_value, record_type, + line_id=1, mx=10, ttl=600): + url = 'https://www.cloudxns.net/api2/record' + object_body = {} + object_body['domain_id'] = domain_id + if host != '@': + object_body['host'] = host + object_body['value'] = host_value + object_body['type'] = record_type + object_body['line_id'] = line_id + if record_type == 'MX' or record_type == 'CNAMEX' or record_type == 'AX': + object_body['mx'] = mx + object_body['ttl'] = ttl + body = json.dumps(object_body) + strdata = self.urlopen_api(url, body, 'POST') + return strdata + + """ + 功能 添加备记录 + HTTP 请求方式 GET + URL https://www.cloudxns.net/api2/record/spare + 请求参数: + 参数名称 类型 必填 描述 + domain_id Integer 域名 id + host_id Integer 主机记录名称 如 www, 默认@ + record_id Integer 解析记录id + value String 记录值, 如IP:8.8.8.8,CNAME:cname.cloudxns.net., MX: mail.cloudxns.net. + :return: String + """ + + def domain_host_record_spare(self, domain_id, host_id, record_id, value): + url = 'https://www.cloudxns.net/api2/record' + object_body = {} + object_body['domain_id'] = domain_id + object_body['host_id'] = host_id + object_body['record_id'] = record_id + object_body['value'] = value + body = json.dumps(object_body) + strdata = self.urlopen_api(url, body, 'POST') + return strdata + + """ + 功能 更新解析记录 + HTTP 请求方式 GET + URL https://www.cloudxns.net/api2/record/:id + 请求参数: + 参数名称 类型 必填 描述 + record_id Integer 解析记录id + domain_id Integer 域名id + host_name String 主机记录名称 如 www, 默认@ + value String 记录值, 如IP:8.8.8.8,CNAME:cname.cloudxns.net., MX: mail.cloudxns.net. + record_type String 记录类型,通过 API 获得记录类型,大写英文,比如:A + mx Integer 优先级,范围 1-100。当记录类型是 MX/AX/CNAMEX 时有效并且必选 + ttl Integer TTL,范围 60-3600,不同等级域名最小值不同 + line_id Integer 线路 id,(通过 API 获得记录线路 id) + spare_data String 备IP + :return: String + """ + + def domain_host_record_update(self, domain_id, record_id, host, host_value, + record_type, line_id=1, mx=10, ttl=600, + bak_ip=None): + url = 'https://www.cloudxns.net/api2/record/' + str(record_id) + object_body = {} + object_body['domain_id'] = domain_id + if host != '@': + object_body['host'] = host + object_body['value'] = host_value + object_body['type'] = record_type + object_body['line_id'] = line_id + if record_type == 'MX' or record_type == 'CNAMEX' or record_type == 'AX': + object_body['mx'] = mx + object_body['ttl'] = ttl + if bak_ip != None: + object_body['bak_ip'] = bak_ip + body = json.dumps(object_body) + strdata = self.urlopen_api(url, body, 'PUT') + return strdata + + """ + 功能 删除解析记录 + HTTP 请求方式 GET + URL https://www.cloudxns.net/api2/record/:id/:domain_id + 请求参数: + 参数名称 类型 必填 描述 + record_id Integer 解析记录id + domain_id Integer 域名 id + :return: String + """ + + def domain_host_record_delete(self, domain_id, host_id): + url = 'https://www.cloudxns.net/api2/record/' + str( + host_id) + '/' + str(domain_id) + body = '' + strdata = self.urlopen_api(url, body, 'DELETE') + return strdata + + """功能:是否启用X优化""" + + def domain_host_record_x_ai(self, domain_id, host_id, enable=False): + url = 'https://www.cloudxns.net/api2/record/ai' + object_body = {} + object_body['id'] = host_id + object_body['domain_id'] = domain_id + if enable == False: + object_body['status'] = 0 + else: + object_body['status'] = 1 + body = json.dumps(object_body) + strdata = self.urlopen_api(url, body, 'POST') + return strdata + + """ + 功能:设置DDNS解析 + 修改 domain 下线路为 line_id(默认为 1(全网默认))、 + 记录类型为 A 的记录值为新的 IP 值(为空时 API 自动获取客户端 IP); + 如果 domain 存在但不存在线路为line_id的记录类型为A的解析记录则添加新的解析记录 + 参数名称 类型 描述 + domain string 含主机记录的域名(如主机记录为@时 domain 是 cloudxns.net,为 www 时 domain 是 www.cloudxns.net) + ip string 记录 IP 值(8.8.8.8)或者多个 IP 值中间用|分割 (8.8.8.8|1.1.1.1) ;为空时 IP 值由 API 自动获取客户端 IP + line_id int 线路 id(通过 API 获取),默认值 1(全网默认) + """ + + def domain_host_DDNS(self, domain, ip='', line_id=1): + url = 'https://www.cloudxns.net/api2/ddns' + object_body = {} + object_body['domain'] = domain + if len(ip) != 0: + object_body['ip'] = ip + object_body['line_id'] = line_id + body = json.dumps(object_body) + strdata = self.urlopen_api(url, body, 'POST') + return strdata + + """ + 功能 添加域名 + HTTP 请求方式 POST + URL https://www.cloudxns.net/api2/domain + :return: String + """ + + def domain_add(self, domain): + url = 'https://www.cloudxns.net/api2/domain' + object_body = {} + object_body['domain'] = domain + body = json.dumps(object_body) + strdata = self.urlopen_api(url, body, 'POST') + return strdata + + """ + 功能 删除域名 + HTTP 请求方式 DELETE + URL https://www.cloudxns.net/api2/domain + 请求参数: + 参数名称 类型 必填 描述 + domain_id Integer 是 域名ID + :return: String + """ + + def domain_delete(self, domain_id): + url = 'https://www.cloudxns.net/api2/domain/' + str(domain_id) + body = '' + strdata = self.urlopen_api(url, body, 'DELETE') + return strdata + + # 获取 NS 服务器列表信息 + def get_domain_ns(self): + url = 'https://www.cloudxns.net/api2/ns_server' + body = '' + strdata = self.urlopen_api(url, body) + return strdata + + # 获取记录类型列表 + def get_record_type(self): + url = 'http://www.cloudxns.net/api2/type' + body = '' + strdata = self.urlopen_api(url, body) + return strdata + + # 获取线路列表 + def get_line(self): + url = 'https://www.cloudxns.net/api2/line' + body = '' + strdata = self.urlopen_api(url, body) + return strdata + + # 获取区域列表 + def get_line_region(self): + url = 'https://www.cloudxns.net/api2/line/region' + body = '' + strdata = self.urlopen_api(url, body) + return strdata + + # 获取 ISP 列表 + def get_isp_list(self): + url = 'https://www.cloudxns.net/api2/line/isp' + body = '' + strdata = self.urlopen_api(url, body) + return strdata + + """ + 功能 获取某域名解析量统计数据 + HTTP 请求方式 GET + URL https://www.cloudxns.net/api2/domain_stat/:id + URL 参数说明 Id:域名 ID + 请求参数: + 参数名称 类型 必填 描述 + host String 是 主机名,查询全部传 all + code String 是 统计区域 Id 或统 ISP Id,查询全部传 all + start_date Date 是 开始时间 格式:yyyy-mm-dd + end_date Date 是 结束时间 格式:yyyy-mm-dd + :return: + """ + + def domain_get_domain_stat(self, domain_id, host, code, start_date, + end_date): + url = 'https://www.cloudxns.net/api2/domain_stat/' + str(domain_id) + object_body = {} + object_body['host'] = host + object_body['code'] = code + object_body['start_date'] = start_date + object_body['end_date'] = end_date + body = json.dumps(object_body) + strdata = self.urlopen_api(url, body, 'POST') + return strdata + + def http_dns_get(self, domain, client_ip='', ttl='', + http_dns_interface='http://httpdnsv3.ffdns.net'): + if domain == None or len(domain) == 0: + return '' + url = http_dns_interface + '/httpdns?dn=' + str(domain) + if client_ip != None and len(client_ip) != 0: + url += '&cip=' + str(client_ip) + if ttl != None and len(ttl) != 0: + url += '&ttl=' + str(ttl) + strdata = self.urlopen(url) + return strdata + + +if __name__ == '__main__': + api = CloudXNS_API(api_key='a7fe5ecbb823e7b0c968b2a885a18e98', + secret_key='a5e984dd94e24f60891cc32746b115d7', + debug_log=True) + api.domain_add('test.org') + print(api.domain_list()) + # api.domain_host_record_add(216271,'test','127.0.0.1','A',1) + api = CloudXNS_API() + # str=api.http_dns_get('www.test.net') + # dict=api.json_strtodict(str) + # print(str) + pass diff --git a/Py3Scripts/NumberToChinese.py b/Py3Scripts/NumberToChinese.py new file mode 100644 index 0000000..491f385 --- /dev/null +++ b/Py3Scripts/NumberToChinese.py @@ -0,0 +1,44 @@ +def digital_to_chinese(digital): + str_digital = str(digital) + chinese = {'1': '壹', '2': '贰', '3': '叁', '4': '肆', '5': '伍', '6': '陆', '7': '柒', '8': '捌', '9': '玖', '0': '零'} + chinese2 = ['拾', '佰', '仟', '万', '厘', '分', '角'] + jiao = '' + bs = str_digital.split('.') + yuan = bs[0] + if len(bs) > 1: + jiao = bs[1] + r_yuan = [i for i in reversed(yuan)] + count = 0 + for i in range(len(yuan)): + if i == 0: + r_yuan[i] += '圆' + continue + r_yuan[i] += chinese2[count] + count += 1 + if count == 4: + count = 0 + chinese2[3] = '亿' + + s_jiao = [i for i in jiao][:3] # 去掉小于厘之后的 + + j_count = -1 + for i in range(len(s_jiao)): + s_jiao[i] += chinese2[j_count] + j_count -= 1 + last = [i for i in reversed(r_yuan)] + s_jiao + + last_str = ''.join(last) + print(str_digital) + print(last_str) + for i in range(len(last_str)): + digital = last_str[i] + if digital in chinese: + last_str = last_str.replace(digital, chinese[digital]) + print(last_str) + return last_str + + +number = float(input("输入需要转换的数字:")) + +if __name__ == '__main__': + digital_to_chinese(number) diff --git a/Py3Scripts/get_Public_Ip.py b/Py3Scripts/get_Public_Ip.py new file mode 100644 index 0000000..285b0fa --- /dev/null +++ b/Py3Scripts/get_Public_Ip.py @@ -0,0 +1,56 @@ +""" +# 基于Python3、requests +# 获取公网ip方式一 +from json import load +from urllib.request import urlopen + +public_ip = load(urlopen("http://jsonip.com"))["ip"] +print(public_ip) +""" + + +# import re +# import requests +# +# link = urllib.urlopen("http://txt.go.sohu.com/ip/soip") +# text = link.read() +# public_ip = re.findall(r'\d+.\d+.\d+.\d+', text) +# print(public_ip[0]) + + +""" +# 基于Python3、requests +# 输出ip为bytes类型 +# 获取公网ip方式二 +from urllib.request import urlopen + +public_ip = urlopen("http://ip.42.pl/raw").read() +print(public_ip) +""" + +""" +from json import load +from urllib.request import urlopen + +public_ip = load(urlopen("http://httpbin.org/ip"))["origin"] +print(public_ip) +""" + + +""" +# 利用阿里获取公网IP +import requests + +url = 'https://amdc.alipay.com/squery' + +headers = { + 'Host': 'amdc.alipay.com', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0;) Gecko/20100101 Firefox/60.0', + 'Accept': 'text/html,application/xhtml,application/xml;q=0.9,*/*;q=0.8', + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' +} +response = requests.get(url, headers=headers) +print(eval(response.text)['clientIp']) + +""" \ No newline at end of file diff --git a/Py3Scripts/morsecode.py b/Py3Scripts/morsecode.py new file mode 100644 index 0000000..e23554d --- /dev/null +++ b/Py3Scripts/morsecode.py @@ -0,0 +1,34 @@ +# 读取文本文件并转为莫尔斯电码,然后使用白色和黑色输出到屏幕。再加上冗余和效验码输出成视频 + +CODE = {'A': '●▬', 'B': '▬●●●', 'C': '▬●▬●', 'D': '▬●●', 'E': '●', + 'F': '●●▬●', 'G': '▬▬●', 'H': '●●●●', 'I': '●●', + 'J': '●▬▬▬', 'K': '▬●▬', 'L': '●▬●●', 'M': '▬▬', 'N': '▬●', + 'O': '▬▬▬', 'P': '●▬▬●', 'Q': '▬▬●▬', 'R': '●▬●', + 'S': '●●●', 'T': '▬', 'U': '●●▬', 'V': '●●●▬', 'W': '●▬▬', + 'X': '▬●●▬', 'Y': '▬●▬▬', 'Z': '▬▬●●', + + '0': '▬▬▬▬▬', '1': '●▬▬▬▬', '2': '●●▬▬▬', '3': '●●●▬▬', + '4': '●●●●▬', '5': '●●●●●', '6': '▬●●●●', '7': '▬▬●●●', + '8': '▬▬▬●●', '9': '▬▬▬▬●', + + '.': '●▬●▬●▬', ',': '▬▬●●▬▬', ':': '▬▬▬●●●', + '?': '●●▬▬●●', '\'': '●▬▬▬▬●', '-': '▬●●●●▬', + '/': '▬●●▬●', '@': '●▬▬●▬●', '=': '▬●●●▬', ' ': '/' + } + +CODE_REVERSED = {value: key for key, value in CODE.items()} + + +def to_morse(s): + return ' '.join(CODE.get(i.upper()) for i in s) + + +def from_morse(s): + return ''.join(CODE_REVERSED.get(i) for i in s.split()) + + +morse = to_morse('living') +space = to_morse(' ') +text = from_morse('▬▬●●▬▬') +print(morse) +print(text) diff --git a/Py3Scripts/parse_aliyun_oss.py b/Py3Scripts/parse_aliyun_oss.py new file mode 100644 index 0000000..668f49c --- /dev/null +++ b/Py3Scripts/parse_aliyun_oss.py @@ -0,0 +1,29 @@ +import xml.etree.ElementTree as ET +import requests +import json +import re +import os + +# 请求解析url +url = 'http://xxx.oss-cn-hangzhou.aliyuncs.com' +request = requests.get(url) +response = request.text +# print(response) + +# xml解析 +tree = ET.ElementTree(ET.fromstring(response)) +root = tree.getroot() +# print(root.attrib) + +for content in root.findall('Contents'): + key = content.find('Key').text + full_url = url + key + request = requests.get(full_url) + content_type = request.headers.get('content-type') + # print(content_type) + if 'octet-stream' not in content_type: + # print(full_url) + filename = os.path.basename(full_url) + # print(filename) + local_path = '本地路径' + open(local_path + filename, 'wb').write(request.content) diff --git a/Py3Scripts/万年历假期.py b/Py3Scripts/万年历假期.py new file mode 100644 index 0000000..883d958 --- /dev/null +++ b/Py3Scripts/万年历假期.py @@ -0,0 +1,38 @@ +from urllib.request import urlopen, Request +import ssl +import json + +host = 'https://jisuwnl.market.alicloudapi.com' +# path = '/calendar/holiday' +path = '/calendar/query' +method = 'GET' +appcode = '32394ce559ff4551936f79a7ea8237f0' +querys = 'date=2019-08-28' +bodys = {} +# url = host + path +url = host + path + '?' + querys + +request = Request(url) +request.add_header('Authorization', 'APPCODE ' + appcode) +ctx = ssl.create_default_context() +ctx.check_hostname = False +ctx.verify_mode = ssl.CERT_NONE +response = urlopen(request, context=ctx) +content = response.read() +content_dict = json.loads(content.decode('utf-8')) +# print(content_dict['result']['2019-10-01']['content']) +print(content_dict['result']) + +""" +输出格式 + +{'status': 0, 'msg': 'ok', +'result': {'2018-12-30': {'name': '元旦', 'content': '12月30日至1月1日放假,共三天,与周末连休。'}, +'2019-02-04': {'name': '春节', 'content': '2月04日至2月10日放假调休,共7天。2月2日(周六)、2月3日(周日)上班。'}, +'2019-04-05': {'name': '清明节', 'content': '4月5日至7日放假调休,共3天,与周末连休。'}, +'2019-05-01': {'name': '劳动节', 'content': '无调休,共1天。'}, +'2019-06-07': {'name': '端午节', 'content': '6月07日至09日放假,共3天,与周末连休。'}, +'2019-09-13': {'name': '中秋节', 'content': '9月13日至15日放假,共3天,与周末连休。'}, +'2019-10-01': {'name': '国庆节', 'content': '10月1日至7日放假调休,共7天。9月29日(周日)、10月12日(周六)上班。'}}} +""" + diff --git a/Py3Scripts/免费天气.py b/Py3Scripts/免费天气.py new file mode 100644 index 0000000..eacbf2d --- /dev/null +++ b/Py3Scripts/免费天气.py @@ -0,0 +1,37 @@ +import requests + +header = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0;) Gecko/20100101 Firefox/60.0', + 'Accept': 'text/html,application/xhtml,application/xml;q=0.9,*/*;q=0.8', + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2' +} + +link = 'https://pv.sohu.com/cityjson' +url1 = 'https://www.tianqiapi.com/api/' +url2 = url1 + '?version=v6&ip=223.6.6.6&appid=22441771&appsecret=jook9nFg' + + +def get_city_code(url): + response = requests.get(url, headers=header) + response_1 = response.text.rsplit('var returnCitySN = ')[1] + response_dict = response_1.rsplit(';')[0] + city_code = eval(response_dict)['cid'] + # return city_code + # print(city_code) + + +def get_weather(url2): + response = requests.get(url2, headers=header) + response_dict = eval(response.text) + response_list = list(response_dict.values()) + num_list = [1, 2, 4, 8, 13, 14, 21, 22] + for x in num_list: + print(response_list[x]) + + +# get_city_code(link) +get_weather(url2) + + +# https://fleet.mdihi.com/chat/chatClient/chatbox.jsp?companyID=365030391&configID=1489&jid=6765387387&s=1 diff --git a/Py3Scripts/墨迹天气和新闻.py b/Py3Scripts/墨迹天气和新闻.py new file mode 100644 index 0000000..72c4aa1 --- /dev/null +++ b/Py3Scripts/墨迹天气和新闻.py @@ -0,0 +1,23 @@ +import requests + + +def get_weather(url): + # 定义http head伪装成curl浏览器获取IP数据 + headers = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0",} + request = requests.get(url, headers=headers) + response = eval(request.text) + print(response) + + +def get_mfw_news(url): + # 定义http head伪装成curl浏览器获取IP数据 + headers = {'User-Agent': "curl/10.0", + "Content-type": "application/x-www-form-urlencoded", + "Accept": "text/plain"} + request = requests.get(url, headers=headers) + response = eval(request.text) + print(response) + + +get_mfw_news('http://www.moji.com/mojiweather/news.php') +get_weather('http://www.moji.com/mojiweather/forecast.php') diff --git a/Py3Scripts/新闻头条.py b/Py3Scripts/新闻头条.py new file mode 100644 index 0000000..86e1eaa --- /dev/null +++ b/Py3Scripts/新闻头条.py @@ -0,0 +1,20 @@ +# 到期时间2020-08-29 +from urllib.request import urlopen, Request +import json + +host = 'http://toutiao-ali.juheapi.com' +path = '/toutiao/index' +method = 'GET' +appcode = '32394ce559ff4551936f79a7ea8237f0' +querys = 'type=keji' +bodys = {} +url = host + path + '?' + querys + + +request = Request(url) +request.add_header('Authorization', 'APPCODE ' + appcode) +response = urlopen(request) +content = response.read() +content_dict = json.loads(content) +# print(content.decode('utf-8')) +print(content_dict) diff --git a/ShellScripts/read-only-fs.sh b/ShellScripts/read-only-fs.sh new file mode 100644 index 0000000..199d3e9 --- /dev/null +++ b/ShellScripts/read-only-fs.sh @@ -0,0 +1,313 @@ +#!/bin/bash + +# CREDIT TO THESE TUTORIALS: +# petr.io/en/blog/2015/11/09/read-only-raspberry-pi-with-jessie +# hallard.me/raspberry-pi-read-only +# k3a.me/how-to-make-raspberrypi-truly-read-only-reliable-and-trouble-free + +if [ $(id -u) -ne 0 ]; then + echo "Installer must be run as root." + echo "Try 'sudo bash $0'" + exit 1 +fi + +clear + +echo "This script configures a Raspberry Pi" +echo "SD card to boot into read-only mode," +echo "obviating need for clean shutdown." +echo "NO FILES ON THE CARD CAN BE CHANGED" +echo "WHEN PI IS BOOTED IN THIS STATE. Either" +echo "the filesystems must be remounted in" +echo "read/write mode, card must be mounted" +echo "R/W on another system, or an optional" +echo "jumper can be used to enable read/write" +echo "on boot." +echo +echo "Links to original tutorials are in" +echo "script source. THIS IS A ONE-WAY" +echo "OPERATION. THERE IS NO SCRIPT TO" +echo "REVERSE THIS SETUP! ALL other system" +echo "config should be complete before using" +echo "this script. MAKE A BACKUP FIRST." +echo +echo "Run time ~5 minutes. Reboot required." +echo +echo -n "CONTINUE? [y/N] " +read +if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then + echo "Canceled." + exit 0 +fi + +# FEATURE PROMPTS ---------------------------------------------------------- +# Installation doesn't begin until after all user input is taken. + +INSTALL_RW_JUMPER=0 +INSTALL_HALT=0 +INSTALL_WATCHDOG=0 + +# Given a list of strings representing options, display each option +# preceded by a number (1 to N), display a prompt, check input until +# a valid number within the selection range is entered. +selectN() { + for ((i=1; i<=$#; i++)); do + echo $i. ${!i} + done + echo + REPLY="" + while : + do + echo -n "SELECT 1-$#: " + read + if [[ $REPLY -ge 1 ]] && [[ $REPLY -le $# ]]; then + return $REPLY + fi + done +} + +SYS_TYPES=(Pi\ 3\ /\ Pi\ Zero\ W All\ other\ models) +WATCHDOG_MODULES=(bcm2835_wdog bcm2708_wdog) +OPTION_NAMES=(NO YES) + +echo -n "Enable boot-time read/write jumper? [y/N] " +read +if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then + INSTALL_RW_JUMPER=1 + echo -n "GPIO pin for R/W jumper: " + read + RW_PIN=$REPLY +fi + +echo -n "Install GPIO-halt utility? [y/N] " +read +if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then + INSTALL_HALT=1 + echo -n "GPIO pin for halt button: " + read + HALT_PIN=$REPLY +fi + +echo -n "Enable kernel panic watchdog? [y/N] " +read +if [[ "$REPLY" =~ (yes|y|Y)$ ]]; then + INSTALL_WATCHDOG=1 + echo "Target system type:" + selectN "${SYS_TYPES[0]}" \ + "${SYS_TYPES[1]}" + WD_TARGET=$? +fi + +# VERIFY SELECTIONS BEFORE CONTINUING -------------------------------------- + +echo +if [ $INSTALL_RW_JUMPER -eq 1 ]; then + echo "Boot-time R/W jumper: YES (GPIO$RW_PIN)" +else + echo "Boot-time R/W jumper: NO" +fi +if [ $INSTALL_HALT -eq 1 ]; then + echo "Install GPIO-halt: YES (GPIO$HALT_PIN)" +else + echo "Install GPIO-halt: NO" +fi +if [ $INSTALL_WATCHDOG -eq 1 ]; then + echo "Enable watchdog: YES (${SYS_TYPES[WD_TARGET-1]})" +else + echo "Enable watchdog: NO" +fi +echo +echo -n "CONTINUE? [y/N] " +read +if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then + echo "Canceled." + exit 0 +fi + +# START INSTALL ------------------------------------------------------------ +# All selections have been validated at this point... + +# Given a filename, a regex pattern to match and a replacement string: +# Replace string if found, else no change. +# (# $1 = filename, $2 = pattern to match, $3 = replacement) +replace() { + grep $2 $1 >/dev/null + if [ $? -eq 0 ]; then + # Pattern found; replace in file + sed -i "s/$2/$3/g" $1 >/dev/null + fi +} + +# Given a filename, a regex pattern to match and a replacement string: +# If found, perform replacement, else append file w/replacement on new line. +replaceAppend() { + grep $2 $1 >/dev/null + if [ $? -eq 0 ]; then + # Pattern found; replace in file + sed -i "s/$2/$3/g" $1 >/dev/null + else + # Not found; append on new line (silently) + echo $3 | sudo tee -a $1 >/dev/null + fi +} + +# Given a filename, a regex pattern to match and a string: +# If found, no change, else append file with string on new line. +append1() { + grep $2 $1 >/dev/null + if [ $? -ne 0 ]; then + # Not found; append on new line (silently) + echo $3 | sudo tee -a $1 >/dev/null + fi +} + +# Given a filename, a regex pattern to match and a string: +# If found, no change, else append space + string to last line -- +# this is used for the single-line /boot/cmdline.txt file. +append2() { + grep $2 $1 >/dev/null + if [ $? -ne 0 ]; then + # Not found; insert in file before EOF + sed -i "s/\'/ $3/g" $1 >/dev/null + fi +} + +echo +echo "Starting installation..." +echo "Updating package index files..." +apt-get update + +echo "Removing unwanted packages..." +#apt-get remove -y --force-yes --purge triggerhappy logrotate dbus \ +# dphys-swapfile xserver-common lightdm fake-hwclock +# Let's keep dbus...that includes avahi-daemon, a la 'raspberrypi.local', +# also keeping xserver & lightdm for GUI login (WIP, not working yet) +apt-get remove -y --force-yes --purge triggerhappy logrotate \ + dphys-swapfile fake-hwclock +apt-get -y --force-yes autoremove --purge + +# Replace log management with busybox (use logread if needed) +echo "Installing ntp and busybox-syslogd..." +apt-get -y --force-yes install ntp busybox-syslogd; dpkg --purge rsyslog + +echo "Configuring system..." + +# Install boot-time R/W jumper test if requested +GPIOTEST="gpio -g mode $RW_PIN up\n\ +if [ \`gpio -g read $RW_PIN\` -eq 0 ] ; then\n\ +\tmount -o remount,rw \/\n\ +\tmount -o remount,rw \/boot\n\ +fi\n" +if [ $INSTALL_RW_JUMPER -ne 0 ]; then + apt-get install -y --force-yes wiringpi + # Check if already present in rc.local: + grep "gpio -g read" /etc/rc.local >/dev/null + if [ $? -eq 0 ]; then + # Already there, but make sure pin is correct: + sed -i "s/^.*gpio\ -g\ read.*$/$GPIOTEST/g" /etc/rc.local >/dev/null + + else + # Not there, insert before final 'exit 0' + sed -i "s/^exit 0/$GPIOTEST\\nexit 0/g" /etc/rc.local >/dev/null + fi +fi + +# Install watchdog if requested +if [ $INSTALL_WATCHDOG -ne 0 ]; then + apt-get install -y --force-yes watchdog + # $MODULE is specific watchdog module name + MODULE=${WATCHDOG_MODULES[($WD_TARGET-1)]} + # Add to /etc/modules, update watchdog config file + append1 /etc/modules $MODULE $MODULE + replace /etc/watchdog.conf "#watchdog-device" "watchdog-device" + replace /etc/watchdog.conf "#max-load-1" "max-load-1" + # Start watchdog at system start and start right away + # Raspbian Stretch needs this package installed first + apt-get install -y --force-yes insserv + insserv watchdog; /etc/init.d/watchdog start + # Additional settings needed on Jessie + append1 /lib/systemd/system/watchdog.service "WantedBy" "WantedBy=multi-user.target" + systemctl enable watchdog + # Set up automatic reboot in sysctl.conf + replaceAppend /etc/sysctl.conf "^.*kernel.panic.*$" "kernel.panic = 10" +fi + +# Install gpio-halt if requested +if [ $INSTALL_HALT -ne 0 ]; then + apt-get install -y --force-yes wiringpi + echo "Installing gpio-halt in /usr/local/bin..." + cd /tmp + curl -LO https://github.com/adafruit/Adafruit-GPIO-Halt/archive/master.zip + unzip master.zip + cd Adafruit-GPIO-Halt-master + make + mv gpio-halt /usr/local/bin + cd .. + rm -rf Adafruit-GPIO-Halt-master + + # Add gpio-halt to /rc.local: + grep gpio-halt /etc/rc.local >/dev/null + if [ $? -eq 0 ]; then + # gpio-halt already in rc.local, but make sure correct: + sed -i "s/^.*gpio-halt.*$/\/usr\/local\/bin\/gpio-halt $HALT_PIN \&/g" /etc/rc.local >/dev/null + else + # Insert gpio-halt into rc.local before final 'exit 0' + sed -i "s/^exit 0/\/usr\/local\/bin\/gpio-halt $HALT_PIN \&\\nexit 0/g" /etc/rc.local >/dev/null + fi +fi + +# Add fastboot, noswap and/or ro to end of /boot/cmdline.txt +append2 /boot/cmdline.txt fastboot fastboot +append2 /boot/cmdline.txt noswap noswap +append2 /boot/cmdline.txt ro^o^t ro + +# Move /var/spool to /tmp +rm -rf /var/spool +ln -s /tmp /var/spool + +# Move /var/lib/lightdm and /var/cache/lightdm to /tmp +rm -rf /var/lib/lightdm +rm -rf /var/cache/lightdm +ln -s /tmp /var/lib/lightdm +ln -s /tmp /var/cache/lightdm + +# Make SSH work +replaceAppend /etc/ssh/sshd_config "^.*UsePrivilegeSeparation.*$" "UsePrivilegeSeparation no" +# bbro method (not working in Jessie?): +#rmdir /var/run/sshd +#ln -s /tmp /var/run/sshd + +# Change spool permissions in var.conf (rondie/Margaret fix) +replace /usr/lib/tmpfiles.d/var.conf "spool\s*0755" "spool 1777" + +# Move dhcpd.resolv.conf to tmpfs +touch /tmp/dhcpcd.resolv.conf +rm /etc/resolv.conf +ln -s /tmp/dhcpcd.resolv.conf /etc/resolv.conf + +# Make edits to fstab +# make / ro +# tmpfs /var/log tmpfs nodev,nosuid 0 0 +# tmpfs /var/tmp tmpfs nodev,nosuid 0 0 +# tmpfs /tmp tmpfs nodev,nosuid 0 0 +replace /etc/fstab "vfat\s*defaults\s" "vfat defaults,ro " +replace /etc/fstab "ext4\s*defaults,noatime\s" "ext4 defaults,noatime,ro " +append1 /etc/fstab "/var/log" "tmpfs /var/log tmpfs nodev,nosuid 0 0" +append1 /etc/fstab "/var/tmp" "tmpfs /var/tmp tmpfs nodev,nosuid 0 0" +append1 /etc/fstab "\s/tmp" "tmpfs /tmp tmpfs nodev,nosuid 0 0" + +# PROMPT FOR REBOOT -------------------------------------------------------- + +echo "Done." +echo +echo "Settings take effect on next boot." +echo +echo -n "REBOOT NOW? [y/N] " +read +if [[ ! "$REPLY" =~ ^(yes|y|Y)$ ]]; then + echo "Exiting without reboot." + exit 0 +fi +echo "Reboot started..." +reboot +exit 0 diff --git a/ShellScripts/swap.sh b/ShellScripts/swap.sh new file mode 100644 index 0000000..5cb392b --- /dev/null +++ b/ShellScripts/swap.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +#Blog:https://www.moerats.com/ + +Green="\033[32m" +Font="\033[0m" +Red="\033[31m" + +#root权限 +root_need(){ + if [[ $EUID -ne 0 ]]; then + echo -e "${Red}Error:This script must be run as root!${Font}" + exit 1 + fi +} + +#检测ovz +ovz_no(){ + if [[ -d "/proc/vz" ]]; then + echo -e "${Red}Your VPS is based on OpenVZ,not supported!${Font}" + exit 1 + fi +} + +add_swap(){ +echo -e "${Green}请输入需要添加的swap,建议为内存的2倍!${Font}" +read -p "请输入swap数值:" swapsize + +#检查是否存在swapfile +grep -q "swapfile" /etc/fstab + +#如果不存在将为其创建swap +if [ $? -ne 0 ]; then + echo -e "${Green}swapfile未发现,正在为其创建swapfile${Font}" + fallocate -l ${swapsize}M /swapfile + chmod 600 /swapfile + mkswap /swapfile + swapon /swapfile + echo '/swapfile none swap defaults 0 0' >> /etc/fstab + echo -e "${Green}swap创建成功,并查看信息:${Font}" + cat /proc/swaps + cat /proc/meminfo | grep Swap +else + echo -e "${Red}swapfile已存在,swap设置失败,请先运行脚本删除swap后重新设置!${Font}" +fi +} + +del_swap(){ +#检查是否存在swapfile +grep -q "swapfile" /etc/fstab + +#如果存在就将其移除 +if [ $? -eq 0 ]; then + echo -e "${Green}swapfile已发现,正在将其移除...${Font}" + sed -i '/swapfile/d' /etc/fstab + echo "3" > /proc/sys/vm/drop_caches + swapoff -a + rm -f /swapfile + echo -e "${Green}swap已删除!${Font}" +else + echo -e "${Red}swapfile未发现,swap删除失败!${Font}" +fi +} + +#开始菜单 +main(){ +root_need +ovz_no +clear +echo -e "———————————————————————————————————————" +echo -e "${Green}Linux VPS一键添加/删除swap脚本${Font}" +echo -e "${Green}1、添加swap${Font}" +echo -e "${Green}2、删除swap${Font}" +echo -e "———————————————————————————————————————" +read -p "请输入数字 [1-2]:" num +case "$num" in + 1) + add_swap + ;; + 2) + del_swap + ;; + *) + clear + echo -e "${Green}请输入正确数字 [1-2]${Font}" + sleep 2s + main + ;; + esac +} +main \ No newline at end of file diff --git a/ShellScripts/syscheck.sh b/ShellScripts/syscheck.sh new file mode 100644 index 0000000..68178a1 --- /dev/null +++ b/ShellScripts/syscheck.sh @@ -0,0 +1,205 @@ +#!/bin/bash +# auth:kaliarch +# func:sys info check +# version:v1.0 +# sys:centos6.x/7.x + +[ $(id -u) -gt 0 ] && echo "请用root用户执行此脚本!" && exit 1 +sysversion=$(rpm -q centos-release|cut -d- -f3) +line="-------------------------------------------------" + + +[ -d logs ] || mkdir logs + +sys_check_file="logs/$(ip a show dev eth0|grep -w inet|awk '{print $2}'|awk -F '/' '{print $1}')-`date +%Y%m%d`.txt" + +# 获取系统cpu信息 +function get_cpu_info() { + Physical_CPUs=$(grep "physical id" /proc/cpuinfo| sort | uniq | wc -l) + Virt_CPUs=$(grep "processor" /proc/cpuinfo | wc -l) + CPU_Kernels=$(grep "cores" /proc/cpuinfo|uniq| awk -F ': ' '{print $2}') + CPU_Type=$(grep "model name" /proc/cpuinfo | awk -F ': ' '{print $2}' | sort | uniq) + CPU_Arch=$(uname -m) +cat </dev/null) + if [ ${sysversion} -gt 6 ];then + service_config=$(systemctl list-unit-files --type=service --state=enabled|grep "enabled") + run_service=$(systemctl list-units --type=service --state=running |grep ".service") + else + service_config=$(/sbin/chkconfig | grep -E ":on|:启用" |column -t) + run_service=$(/sbin/service --status-all|grep -E "running") + fi +cat </dev/null|cut -d/ -f5;egrep -v "^$|^#" ${cronuser} 2>/dev/null;echo "";done) +cat < ${sys_check_file} \ No newline at end of file