├── AndroidAppInfo ├── AppInspector.bat ├── AppInspectorExecutor.sh └── result.py ├── AndroidMemchek ├── Readme.md ├── memory_check.sh ├── pull_memory_log.bat ├── run_memory_check.bat └── showmap ├── FileManuplite ├── Readme.md └── autoCheck.sh ├── README.md ├── SSLAutoInstall ├── Readme.md ├── SSLAutoInstall.sh └── media │ ├── bda84fbc2ede834deaba1c173a932223.png │ └── d13ffd6a73f938d1037d0708e31433bf.png ├── ShellConfig └── ExampleConfig.conf ├── ShellUtils └── ShellUtils.sh ├── TelegramBot └── SSHLoginAlert.sh ├── crontabBot └── CheckPeriodicStatus.sh ├── x-ui └── x-ui.sh └── xrayUtils └── xrayTrafficCheck.sh /AndroidAppInfo/AppInspector.bat: -------------------------------------------------------------------------------- 1 | rem Description:AppInspector,a tool for checking App details such runtime CPU,MEM info etc 2 | rem Autor:FranzKafkaYu 3 | rem Date:2024/10/30 4 | 5 | rem set up encoding to utf-8 6 | 7 | chcp 65001 8 | 9 | @echo off 10 | echo ========================获取root权限========================= 11 | 12 | adb wait-for-device 13 | adb root 14 | adb remount 15 | adb wait-for-device 16 | 17 | echo ========================推入相关文件======================== 18 | adb shell setenforce 0 19 | adb push AppInspectorExecutor.sh /data/ 20 | adb shell chmod 777 /data/AppInspectorExecutor.sh 21 | 22 | echo ========================删除旧有资料======================== 23 | adb shell rm -rf /data/appinspector 24 | 25 | echo ========================执行Shel任务======================== 26 | adb shell "sh -T- /data/AppInspectorExecutor.sh" 27 | ping 127.0.0.1 -n 30 -w 1000 > NUL 28 | adb shell ls -al /data/appinspector 29 | echo ========================结束执行任务======================== 30 | PAUSE -------------------------------------------------------------------------------- /AndroidAppInfo/AppInspectorExecutor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #constants 4 | APP_PACKAGE_NAME="com.example.smartscene" 5 | #NOTE:APP_PROCESS_NAME normally same as APP_PACKAGE_NAME,but if it defined in manifest:android.process 6 | #NOTE:AND the progress name will be changed 7 | APP_PROCESS_NAME="com.example.smartscene" 8 | APP_INSPECTOR_RESULT_DIR="/data/appinspector" 9 | APP_INSPECTOR_RESULT_OUTPUT="result.txt" 10 | 11 | #some info need to record 12 | APP_APK_SIZE="" 13 | APP_PACKAGE_LOCATION="" 14 | 15 | #print version 16 | function printVersion() { 17 | echo "current version:${TOOL_VERSION}" 18 | } 19 | 20 | #如果之前存在执行中的进程,则需要kill掉 21 | function clearSession() { 22 | local current_pid=$$ 23 | # 获取所有与当前脚本相同的进程,排除当前进程 24 | local existing_pid=$(pgrep -f "AppInspectorExecutor.sh" | grep -v "^$" | grep -v "^$current_pid$") 25 | #Kill掉旧进程 26 | if [ -n "$existing_pid" ]; then 27 | echo "killing progress: $existing_pid" 28 | for pid in $existing_pid; do 29 | kill -9 $pid 30 | done 31 | fi 32 | } 33 | 34 | function disableSelinux() { 35 | setenforce 0 36 | } 37 | 38 | function createResultDir() { 39 | rm -rf ${APP_INSPECTOR_RESULT_DIR} 40 | mkdir -p ${APP_INSPECTOR_RESULT_DIR} 41 | } 42 | 43 | function getAppLocation() { 44 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 45 | APP_PACKAGE_LOCATION=$(pm list packages -a -f | grep ${APP_PACKAGE_NAME} | sed 's/package://' | awk -F '=com.example.smartscene' '{print $1}') 46 | echo "name ${APP_PACKAGE_NAME} location:${APP_PACKAGE_LOCATION}" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 47 | } 48 | 49 | function getAppAPKSize() { 50 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 51 | APP_APK_SIZE=$(du -h ${APP_PACKAGE_LOCATION} | cut -f1) 52 | echo "name ${APP_PACKAGE_NAME} size:${APP_APK_SIZE}" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 53 | } 54 | 55 | function getAppPermissions() { 56 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 57 | dumpsys package ${APP_PACKAGE_NAME} | grep permission >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 58 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 59 | } 60 | 61 | #here we need check different type memory,such as PSS,RSS,USS 62 | #PSS:Propotional Set Size 63 | #USS:Unique Set Size 64 | #RSS:Resident Set Size 65 | function getAppMemoryInfo() { 66 | local pid=$(pidof ${APP_PROCESS_NAME}) 67 | local Time=$(TZ=UTC-8 date) 68 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 69 | echo "Time:${Time}" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 70 | echo "dumpsys procstats begin" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 71 | dumpsys procstats | grep -A 1 ${APP_PROCESS_NAME} >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 72 | echo "dumpsys procstats end" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 73 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 74 | echo "dumpsys meminfo begin" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 75 | dumpsys meminfo -p ${pid} >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 76 | echo "dumpsys meminfo end" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 77 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 78 | echo "shomap meminfo begin" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 79 | showmap ${pid} >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 80 | echo "shomap meminfo end" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 81 | echo "\r\n" 82 | } 83 | 84 | function getAppCpuInfo() { 85 | //NOTE:here we may find multi progress in Android with same progress name 86 | local pid=$(pidof ${APP_PROCESS_NAME}) 87 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 88 | echo "get cpu usage begin" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 89 | top -b -n 1 | grep -E 'PID|${APP_PROCESS_NAME}' >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 90 | echo "get cpu usage end" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 91 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 92 | echo "each thread usage begin" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 93 | top -b -H -p ${pid} -n 1 | sed 's/\x1b\[[0-9;]*m//g' >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 94 | echo "each thread usage end" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 95 | echo "---------------------------------------------" >> ${APP_INSPECTOR_RESULT_DIR}/${APP_INSPECTOR_RESULT_OUTPUT} 96 | } 97 | 98 | function main() { 99 | disableSelinux 100 | createResultDir 101 | getAppLocation 102 | getAppAPKSize 103 | getAppPermissions 104 | while true 105 | do 106 | getAppMemoryInfo 107 | getAppCpuInfo 108 | sleep 10 109 | done 110 | 111 | } 112 | 113 | main $* 114 | 115 | -------------------------------------------------------------------------------- /AndroidAppInfo/result.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Author: FranzKafka 3 | Date: 2024-11-11 09:21:03 4 | LastEditTime: 2024-11-11 09:24:57 5 | LastEditors: Franzkafka 6 | Description: 7 | FilePath: \AppInspector\result.py 8 | 可以输入预定的版权声明、个性签名、空行等 9 | ''' 10 | import re 11 | from datetime import datetime 12 | from typing import Dict, List, Any 13 | import matplotlib.pyplot as plt 14 | from collections import defaultdict 15 | 16 | class PerformanceParser: 17 | def __init__(self): 18 | self.result: Dict[str, Any] = { 19 | 'timestamps': [], 20 | 'app_info': { 21 | 'package_name': '', 22 | 'location': '', 23 | 'size': '', 24 | }, 25 | 'permissions': { 26 | 'requested': [], 27 | 'install': {}, 28 | 'runtime': {} 29 | }, 30 | 'performance_data': defaultdict(list) # 存储时间序列数据 31 | } 32 | self.current_timestamp = None 33 | 34 | def parse_file(self, file_path: str) -> Dict[str, Any]: 35 | """解析性能数据文件""" 36 | current_section = '' 37 | section_content = [] 38 | in_permission_section = False 39 | last_timestamp = None # 用于跟踪上一个时间戳 40 | 41 | try: 42 | with open(file_path, 'r', encoding='utf-8') as file: 43 | content = file.readlines() 44 | 45 | for line in content: 46 | line = line.strip() 47 | 48 | # 检测时间戳 49 | if 'Time:' in line: 50 | current_timestamp = line.split('Time:')[1].strip() 51 | # 只有当时间戳变化时才更新 52 | if current_timestamp != last_timestamp: 53 | self.current_timestamp = current_timestamp 54 | last_timestamp = current_timestamp 55 | if self.current_timestamp not in self.result['timestamps']: 56 | self.result['timestamps'].append(self.current_timestamp) 57 | continue 58 | 59 | # 检测权限部分 60 | if 'requested permissions:' in line: 61 | in_permission_section = True 62 | current_section = 'requested' 63 | continue 64 | elif 'install permissions:' in line: 65 | in_permission_section = True 66 | current_section = 'install' 67 | continue 68 | elif 'runtime permissions:' in line: 69 | in_permission_section = True 70 | current_section = 'runtime' 71 | continue 72 | 73 | # 解析权限 74 | if in_permission_section and line: 75 | if current_section == 'requested' and (line.startswith('android.') or 76 | line.startswith('com.') or 77 | line.startswith('ohos.')): 78 | if line not in self.result['permissions']['requested']: 79 | self.result['permissions']['requested'].append(line) 80 | elif current_section in ['install', 'runtime'] and ':' in line: 81 | if 'granted=' in line: 82 | permission, status = line.split(':', 1) 83 | permission = permission.strip() 84 | granted = 'granted=true' in status.lower() 85 | self.result['permissions'][current_section][permission] = granted 86 | 87 | # 解析应用信息 88 | if 'name' in line and 'location:' in line.lower(): 89 | parts = line.split('location:') 90 | self.result['app_info']['package_name'] = parts[0].split('name')[1].strip() 91 | self.result['app_info']['location'] = parts[1].strip() 92 | elif 'name' in line and 'size:' in line: 93 | self.result['app_info']['size'] = line.split('size:')[1].strip() 94 | 95 | # 解析性能数据 96 | if self.current_timestamp: 97 | if 'e.unity3d' in line and 'grep' not in line: 98 | try: 99 | parts = line.split() 100 | if len(parts) >= 9: 101 | cpu_usage = float(parts[8].strip('[]%')) 102 | # 检查是否已经有该时间戳的数据 103 | existing_data = next( 104 | (item for item in self.result['performance_data']['cpu'] 105 | if item['timestamp'] == self.current_timestamp), 106 | None 107 | ) 108 | if existing_data: 109 | # 更新现有数据,取最大值 110 | existing_data['value'] = max(existing_data['value'], cpu_usage) 111 | else: 112 | # 添加新数据 113 | self.result['performance_data']['cpu'].append({ 114 | 'timestamp': self.current_timestamp, 115 | 'value': cpu_usage 116 | }) 117 | except (ValueError, IndexError) as e: 118 | print(f"Error parsing CPU usage: {e}") 119 | 120 | # 解析内存信息 121 | if 'TOTAL PSS:' in line: 122 | try: 123 | pss_match = re.search(r'TOTAL PSS:\s*(\d+)', line) 124 | if pss_match: 125 | pss_value = int(pss_match.group(1)) 126 | existing_data = next( 127 | (item for item in self.result['performance_data']['memory'] 128 | if item['timestamp'] == self.current_timestamp), 129 | None 130 | ) 131 | if existing_data: 132 | # 更新现有数据,取最大值 133 | existing_data['value'] = max(existing_data['value'], pss_value) 134 | else: 135 | # 添加新数据 136 | self.result['performance_data']['memory'].append({ 137 | 'timestamp': self.current_timestamp, 138 | 'value': pss_value 139 | }) 140 | except (ValueError, IndexError) as e: 141 | print(f"Error parsing memory: {e}") 142 | 143 | return self.result 144 | 145 | except Exception as e: 146 | print(f"Error parsing file: {e}") 147 | return self.result 148 | 149 | def plot_performance_data(result): 150 | """绘制性能数据图表""" 151 | plt.style.use('bmh') 152 | 153 | # 创建图表 154 | fig = plt.figure(figsize=(15, 10)) 155 | 156 | # 准备数据 157 | cpu_data = result['performance_data']['cpu'] 158 | memory_data = result['performance_data']['memory'] 159 | 160 | # 确保数据和时间戳一一对应 161 | cpu_timestamps = [x['timestamp'] for x in cpu_data] 162 | cpu_values = [x['value'] for x in cpu_data] 163 | memory_timestamps = [x['timestamp'] for x in memory_data] 164 | memory_values = [x['value']/1024 for x in memory_data] # 转换为MB 165 | 166 | # 优化时间戳显示 167 | def format_timestamp(timestamp): 168 | try: 169 | dt = datetime.strptime(timestamp, "%a %b %d %H:%M:%S %Z-%Y") 170 | return dt.strftime("%H:%M:%S") # 只显示时:分:秒 171 | except: 172 | return timestamp 173 | 174 | formatted_cpu_timestamps = [format_timestamp(ts) for ts in cpu_timestamps] 175 | formatted_memory_timestamps = [format_timestamp(ts) for ts in memory_timestamps] 176 | 177 | # CPU使用率子图 178 | ax1 = plt.subplot(211) 179 | ax1.plot(range(len(cpu_values)), cpu_values, 'b-o', linewidth=2, markersize=6) 180 | ax1.set_title('CPU Usage Over Time', fontsize=14, pad=15) 181 | ax1.set_xlabel('Time', fontsize=12) 182 | ax1.set_ylabel('CPU Usage (%)', fontsize=12) 183 | ax1.grid(True, linestyle='--', alpha=0.7) 184 | 185 | # 设置CPU图的x轴标签 186 | num_ticks = min(10, len(cpu_timestamps)) # 最多显示10个标签 187 | tick_indices = list(range(0, len(cpu_timestamps), max(1, len(cpu_timestamps) // num_ticks))) 188 | if tick_indices[-1] != len(cpu_timestamps) - 1: 189 | tick_indices.append(len(cpu_timestamps) - 1) 190 | 191 | ax1.set_xticks(tick_indices) 192 | ax1.set_xticklabels([formatted_cpu_timestamps[i] for i in tick_indices], rotation=45, ha='right') 193 | 194 | # 内存使用子图 195 | ax2 = plt.subplot(212) 196 | ax2.plot(range(len(memory_values)), memory_values, 'g-s', linewidth=2, markersize=6) 197 | ax2.set_title('Memory Usage Over Time', fontsize=14, pad=15) 198 | ax2.set_xlabel('Time', fontsize=12) 199 | ax2.set_ylabel('Memory Usage (MB)', fontsize=12) 200 | ax2.grid(True, linestyle='--', alpha=0.7) 201 | 202 | # 设置内存图的x轴标签 203 | memory_tick_indices = list(range(0, len(memory_timestamps), max(1, len(memory_timestamps) // num_ticks))) 204 | if memory_tick_indices[-1] != len(memory_timestamps) - 1: 205 | memory_tick_indices.append(len(memory_timestamps) - 1) 206 | 207 | ax2.set_xticks(memory_tick_indices) 208 | ax2.set_xticklabels([formatted_memory_timestamps[i] for i in memory_tick_indices], rotation=45, ha='right') 209 | 210 | # 添加数据标签(每隔几个点添加一个标签,避免过密) 211 | label_interval = max(len(cpu_values) // 10, 1) # 根据数据点数量调整标签间隔 212 | 213 | # 只为非零值添加标签 214 | for i in range(0, len(cpu_values), label_interval): 215 | if cpu_values[i] > 0.1: # 只为大于0.1%的值添加标签 216 | ax1.annotate(f'{cpu_values[i]:.1f}%', 217 | (i, cpu_values[i]), 218 | textcoords="offset points", 219 | xytext=(0,10), 220 | ha='center', 221 | fontsize=8) 222 | 223 | # 为内存图添加首尾和关键点的标签 224 | important_points = [0, -1] # 首尾点 225 | for i in important_points: 226 | ax2.annotate(f'{memory_values[i]:.1f}MB', 227 | (i, memory_values[i]), 228 | textcoords="offset points", 229 | xytext=(0,10), 230 | ha='center', 231 | fontsize=8) 232 | 233 | # 调整布局 234 | plt.tight_layout() 235 | 236 | # 保存图表 237 | plt.savefig('performance_analysis.png', dpi=300, bbox_inches='tight') 238 | plt.close() 239 | 240 | def main(): 241 | parser = PerformanceParser() 242 | result = parser.parse_file('result.txt') 243 | 244 | # 打印应用基本信息 245 | print("\nApplication Information:") 246 | print(f"Package Name: {result['app_info']['package_name']}") 247 | print(f"Location: {result['app_info']['location']}") 248 | print(f"Size: {result['app_info']['size']}") 249 | 250 | # 打印权限信息 251 | print("\nPermissions Summary:") 252 | print(f"Total Requested Permissions: {len(result['permissions']['requested'])}") 253 | print("\nRequested Permissions:") 254 | for perm in result['permissions']['requested']: 255 | print(f" - {perm}") 256 | 257 | print("\nInstall Permissions:") 258 | for perm, granted in result['permissions']['install'].items(): 259 | print(f" - {perm}: {'Granted' if granted else 'Not Granted'}") 260 | 261 | print("\nRuntime Permissions:") 262 | for perm, granted in result['permissions']['runtime'].items(): 263 | print(f" - {perm}: {'Granted' if granted else 'Not Granted'}") 264 | 265 | # 打印性能数据摘要 266 | print("\nPerformance Summary:") 267 | if result['performance_data']['cpu']: 268 | avg_cpu = sum(x['value'] for x in result['performance_data']['cpu']) / len(result['performance_data']['cpu']) 269 | max_cpu = max(x['value'] for x in result['performance_data']['cpu']) 270 | min_cpu = min(x['value'] for x in result['performance_data']['cpu']) 271 | print(f"CPU Usage:") 272 | print(f" Average: {avg_cpu:.2f}%") 273 | print(f" Maximum: {max_cpu:.2f}%") 274 | print(f" Minimum: {min_cpu:.2f}%") 275 | 276 | if result['performance_data']['memory']: 277 | avg_memory = sum(x['value'] for x in result['performance_data']['memory']) / len(result['performance_data']['memory']) 278 | max_memory = max(x['value'] for x in result['performance_data']['memory']) 279 | min_memory = min(x['value'] for x in result['performance_data']['memory']) 280 | print(f"\nMemory Usage:") 281 | print(f" Average: {avg_memory/1024:.2f} MB") 282 | print(f" Maximum: {max_memory/1024:.2f} MB") 283 | print(f" Minimum: {min_memory/1024:.2f} MB") 284 | 285 | # 生成性能图表 286 | plot_performance_data(result) 287 | print("\nPerformance charts have been saved to 'performance_analysis.png'") 288 | 289 | if __name__ == "__main__": 290 | main() 291 | -------------------------------------------------------------------------------- /AndroidMemchek/Readme.md: -------------------------------------------------------------------------------- 1 | # 使用说明 2 | 3 | 1. 使用该脚本前需保证无adb验证密码,且车机OS非user版本 4 | 5 | 2. 在保证adb正常可以使用的情况下,点击bat脚本run_memory_check.bat 6 | 7 | 3. 观察屏幕输出,提示”按任意键继续时表明执行完成“ 8 | 9 | 4. run_memory_check.bat执行完成后,可将adb模式切换为usb模式,进行常规测试 10 | 11 | # 注意事项 12 | 13 | 1. 测试过程中如发现系统卡顿,可以执行pull_memory_log.bat拉出相关信息,请及时将拉取出的文件传递给相关方 14 | -------------------------------------------------------------------------------- /AndroidMemchek/memory_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #This file will be used for shell excute memory check periodic 4 | #Authored By FranzKafka 5 | 6 | #Close Selinux 7 | setenforce 0 8 | path=/data/output 9 | 10 | #Path Check 11 | if [ ! -d $path ];then 12 | echo "no output file,will create it" 13 | mkdir $path 14 | else 15 | echo "output file exist,will remove it" 16 | rm -rf $path 17 | echo "now re-create it" 18 | mkdir $path 19 | fi 20 | 21 | #Get pid,there we used evsserver,you can replace it 22 | evsserver_pid=`pidof evsserver` 23 | echo "current pid $evsserver_pid ,we will begin check memory" 24 | while true 25 | do 26 | #Get time 27 | Time=$(TZ=UTC-8 date) 28 | evsserver_pid=`pidof evsserver` 29 | #Get rss data 30 | rss_evsserver=$(cat /proc/${evsserver_pid}/status | grep -i vmrss | awk '{print $2}') 31 | #Vss unit tranformed to G 32 | rss_evsserver_unit_M=`expr $rss_evsserver / 1024 ` 33 | echo "Current time $Time ,and the pid of evsserver is $evsserver_pid,RSS is $rss_evsserver KBytes($rss_evsserver_unit_M M)" >> /data/output/evsmemcheck.log 34 | 35 | 36 | #get all meminfo 37 | date >> /data/output/dumpsys_meminfo.txt 38 | echo "dumpsys -t 30 begin" 39 | dumpsys -t 30 meminfo >> /data/output/dumpsys_meminfo.txt 40 | 41 | #get evsserver info 42 | date >> /data/output/dumpsys_meminfo_evsserver.txt 43 | echo "dumpsys evsserver begin" 44 | dumpsys meminfo -p ${evsserver_pid} >> /data/output/dumpsys_meminfo_evsserver.txt 45 | 46 | #get evsserver showmap info 47 | 48 | date >> /data/output/showmap_evsserver.txt 49 | echo "showmap evsserver begin" 50 | showmap ${evsserver_pid} >> /data/output/showmap_evsserver.txt 51 | 52 | #get ion mm status 53 | 54 | date >> /data/output/ion_mm_heap.txt 55 | echo "cat ion_mm_heap begin" 56 | cat /sys/kernel/debug/ion/ion_mm_heap >> /data/output/ion_mm_heap.txt 57 | 58 | #get all proc meminfo 59 | 60 | date >> /data/output/proc_meminfo.txt 61 | echo "cat meminfo begin" 62 | cat /proc/meminfo >> /data/output/proc_meminfo.txt 63 | 64 | #get DMA info 65 | date >> /data/output/dma_buf.txt 66 | cat /d/dma_buf/bufinfo >> /data/output/dma_buf.txt 67 | 68 | date >> /data/output/dumpsys.txt 69 | echo "dumpsys begin" 70 | dumpsys > /data/output/dumpsys.txt 71 | 72 | #if rss is great than 1G,will generate tag file 73 | if [ $rss_evsserver -gt 1048576 ];then 74 | echo " $Time now evsserver(pid-> $evsserver_pid ) RSS beyond 1G,memory leak detected " >> /data/output/evsmemleakTag.txt 75 | exit 76 | fi 77 | #perioic time is 5s 78 | sleep 5 79 | 80 | done 81 | -------------------------------------------------------------------------------- /AndroidMemchek/pull_memory_log.bat: -------------------------------------------------------------------------------- 1 | adb root 2 | adb pull /data/output -------------------------------------------------------------------------------- /AndroidMemchek/run_memory_check.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FranzKafkaYu/BashScripts/28adb22f2ea31ef558b11cd55a613ca493f8c191/AndroidMemchek/run_memory_check.bat -------------------------------------------------------------------------------- /AndroidMemchek/showmap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FranzKafkaYu/BashScripts/28adb22f2ea31ef558b11cd55a613ca493f8c191/AndroidMemchek/showmap -------------------------------------------------------------------------------- /FileManuplite/Readme.md: -------------------------------------------------------------------------------- 1 | 1.该脚本是我在使用X-UI的过程中根据自己需求所写的,目的一是为了定时检测xray日志文件,当发现日志超过一定大小后即删除日志,二是隔一段时间更新geo数据,并重启X-UI 2 | 2.该脚本将通过cron定时任务执行,在cron中添加定时任务如下: 3 | 00 4 */2 * * /usr/local/x-ui/bin/autoCheck.sh >> /usr/local/x-ui/bin/autoCheck.log 4 | 5 | 表明每隔两天执行该脚本进行检测 6 | -------------------------------------------------------------------------------- /FileManuplite/autoCheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #This file will be used check whether these logs are too big 3 | #If the files are bigger than 10M,then will automated deleted and restart X-UI 4 | #Attention:if this script need be excuted by cron,the file path mast be absolute. 5 | Time=$(TZ=UTC-8 date) 6 | ErrorLogPath=/usr/local/x-ui/bin/error.log 7 | AccessLogPath=/usr/local/x-ui/bin/access.log 8 | rmErrorLogPath=/usr/local/x-ui/bin/rmError.log 9 | rmAccessLogPath=/usr/local/x-ui/bin/rmAccess.log 10 | urlForGeoip='https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat' 11 | urlForGeosite='https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat' 12 | 13 | #更新geo数据 14 | curl -s -L -o /usr/local/x-ui/bin/geoip.dat ${urlForGeoip} 15 | if [[ $? -ne 0 ]]; then 16 | echo "update geoip.dat failed" 17 | else 18 | echo "update geoip.dat succeed" 19 | fi 20 | curl -s -L -o /usr/local/x-ui/bin/geosite.dat ${urlForGeosite} 21 | if [[ $? -ne 0 ]]; then 22 | echo "update geosite.dat failed" 23 | else 24 | echo "update geosite.dat succeed" 25 | fi 26 | 27 | #检测文件是否存在 28 | if [ ! -f "$AccessLogPath" ]; then 29 | echo "error:$AccessLogPath not exist" 30 | fi 31 | 32 | if [ ! -f "$ErrorLogPath" ]; then 33 | echo "error:$ErrorLogPath not exist" 34 | fi 35 | 36 | #判断文件大小,使用“M”为计量单位,并取纯数字 37 | ErrorLogdata=$(ls -lah $ErrorLogPath --block-size=M | awk '{print $5}' | awk -F 'M' '{print$1}') 38 | #或者使用stat -c %s $AccessLogPath 39 | echo "ErrorLogdata is $ErrorLogdata M,date=$Time" 40 | AccessLogdata=$(ls -lah $AccessLogPath --block-size=M | awk '{print $5}' | awk -F 'M' '{print$1}') 41 | #或者使用stat -c %s $AccessLogPath 42 | echo "AccessLogdata is $AccessLogdata M,date=$Time" 43 | 44 | if [ $ErrorLogdata -gt 15 ]; then 45 | rm $ErrorLogPath 46 | echo "$ErrorLogPath is beyond 15M,remove it and restart X-ui,date=$Time" >>$rmErrorLogPath 47 | else 48 | echo "$ErrorLogPath is $ErrorLogdata M,date=$Time" >>$rmErrorLogPath 49 | fi 50 | 51 | if [ $AccessLogdata -gt 15 ]; then 52 | rm $AccessLogPath 53 | echo "$AccessLogPath is beyond 15M,remove it and restart X-ui,date=$Time" >>$rmAccessLogPath 54 | else 55 | echo "$AccessLogPath is $AccessLogdata M,date=$Time" >>$rmAccessLogPath 56 | fi 57 | 58 | systemctl restart x-ui 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 中文版介绍: 2 | 这是我的个人常用的一些脚本集合,通过这些脚本,我一边学习Linux知识一边方便我个人的使用,以下是关于这些脚本的一些摘要。 3 | 4 | 1. FileManuplite:该脚本主要用于定时删除xray/v2ray中产生的日志,当他们超过特定大小时就会删除日志同时重启进程 5 | 6 | 2. SSLAutoInstall:该脚本主要用于利用Cloudflare的DNS 7 | API进行Let’sEncrypt的证书申请,默认申请为RSA泛域名证书 8 | 9 | 3. ShellConfig:该脚本主要用于加深自己对shell中.conf配置文件的理解,以及其他相关应用 10 | 11 | 4. androidMemCheck:该脚本主要用于Android系统的内存问题排查,包含bat脚本于shell脚本两部分 12 | 13 | 5. crontabBot:该脚本主要用于定时检查系统状态,当系统异常时通过TG bot进行通知 14 | 15 | 6. telegramBot:该脚本主要用于登录SSH时通过TG bot进行通知 16 | 17 | 7. x-ui:该脚本基于x-ui项目的基础脚本进行修改,添加了我个人认为比较合适的功能 18 | 19 | 8. xrayUtils:该脚本主要用于xray的流量统计,然后定时通知 20 | -------------------------------------------------------------------------------- /SSLAutoInstall/Readme.md: -------------------------------------------------------------------------------- 1 | # 使用说明: 2 | 3 | 1. 使用该脚本需要root权限 4 | 2. 当前脚本提供两种方式完成证书申请,包括`stanalone`模式以及`cloudflare DNS API`模式 5 | 3. `standalone`模式较为简单,只需要保证端口开放即可,但只能申请单域名证书;`cloudflare DNS API`模式则可以申请泛域名证书且不依赖于端口开放 6 | 4. 使用`cloudflare DNS API`需要获取cloudflare的Global API Key以及注册邮箱,Global API 7 | Key获取方式如下: 8 | 9 | ![](media/bda84fbc2ede834deaba1c173a932223.png) 10 | 11 | ![](media/d13ffd6a73f938d1037d0708e31433bf.png) 12 | 13 | 4. 该脚本所使用的证书CA方为Let‘sEncrypt,暂不支持其他CA方 14 | 15 | 5. 该脚本所使用的证书申请模式为DNS,利用DNS解析服务提供商提供的API进行解析。 16 | 6. 使用方法:bash <(curl -Ls https://raw.githubusercontent.com/FranzKafkaYu/BashScripts/main/SSLAutoInstall/SSLAutoInstall.sh) 17 | 7. 由于本人能力有限,无法保证该脚本在所有平台都可以正常运行,自测环境:ubantu 20.0,如使用有问题,可以在我的TG群组内私信我:https://t.me/franzkafayu 18 | 8. 假设解析到服务器对应IP的域名为`a.example.com`,使用方式1申请证书时,请输入域名为`a.example.com`,使用方式2申请证书时,请输入域名为`example.com` 19 | 20 | -------------------------------------------------------------------------------- /SSLAutoInstall/SSLAutoInstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #This shell script is used for issue a Let'sEncrypt Cert And installation more convenitenly 4 | #This shell script now provids two methods for cert issue 5 | # 1.Standalone Mode:the easiest way to issue certs,but need to keep port open alaways 6 | # 2.DNS API Mode:the most strong method but a little bit complicated,which can help u issue wildcard certs 7 | # No need to keep port open 8 | 9 | #No matter what method you adopt,the cert will be auto renew in 60 days,no need to worry expirations 10 | #For more info,please check acme official document. 11 | 12 | #Author:FranzKafka 13 | #Date:2022-08-18 14 | #Version:0.0.1 15 | 16 | #Some constans here 17 | OS_CHECK='' 18 | CERT_DOMAIN='' 19 | CERT_DEFAULT_INSTALL_PATH='/root/cert/' 20 | 21 | #Some basic settings here 22 | plain='\033[0m' 23 | red='\033[0;31m' 24 | green='\033[0;32m' 25 | yellow='\033[0;33m' 26 | 27 | function LOGD() { 28 | echo -e "${yellow}[DEG] $* ${plain}" 29 | } 30 | 31 | function LOGE() { 32 | echo -e "${red}[ERR] $* ${plain}" 33 | } 34 | 35 | function LOGI() { 36 | echo -e "${green}[INF] $* ${plain}" 37 | } 38 | 39 | #Check whether you are root 40 | LOGI "权限检查..." 41 | currentUser=$(whoami) 42 | LOGD "currentUser is $currentUser" 43 | if [ $currentUser != "root" ]; then 44 | LOGE "$Attention:请检查是否为root用户,please check whether you are root" 45 | exit 1 46 | fi 47 | 48 | # check OS_CHECK 49 | LOGI "系统类型检查..." 50 | if [[ -f /etc/redhat-release ]]; then 51 | OS_CHECK="centOS_CHECK" 52 | elif cat /etc/issue | grep -Eqi "debian"; then 53 | OS_CHECK="debian" 54 | elif cat /etc/issue | grep -Eqi "ubuntu"; then 55 | OS_CHECK="ubuntu" 56 | elif cat /etc/issue | grep -Eqi "centOS_CHECK|red hat|redhat"; then 57 | OS_CHECK="centos" 58 | elif cat /proc/version | grep -Eqi "debian"; then 59 | OS_CHECK="debian" 60 | elif cat /proc/version | grep -Eqi "ubuntu"; then 61 | OS_CHECK="ubuntu" 62 | elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then 63 | OS_CHECK="centos" 64 | else 65 | LOGE "未检测到系统版本,请联系脚本作者!\n" && exit 1 66 | fi 67 | 68 | #function for user choice 69 | confirm() { 70 | if [[ $# > 1 ]]; then 71 | echo && read -p "$1 [默认$2]: " temp 72 | if [[ x"${temp}" == x"" ]]; then 73 | temp=$2 74 | fi 75 | else 76 | read -p "$1 [y/n]: " temp 77 | fi 78 | if [[ x"${temp}" == x"y" || x"${temp}" == x"Y" ]]; then 79 | return 0 80 | else 81 | return 1 82 | fi 83 | } 84 | 85 | #function for user choice 86 | install_acme() { 87 | cd ~ 88 | LOGI "开始安装acme脚本..." 89 | curl https://get.acme.sh | sh 90 | if [ $? -ne 0 ]; then 91 | LOGE "acme安装失败" 92 | return 1 93 | else 94 | LOGI "acme安装成功" 95 | fi 96 | return 0 97 | } 98 | 99 | #function for domain check 100 | domain_valid_check() { 101 | local domain="" 102 | read -p "请输入你的域名:" domain 103 | LOGD "你输入的域名为:${domain},正在进行域名合法性校验..." 104 | #here we need to judge whether there exists cert already 105 | local currentCert=$(~/.acme.sh/acme.sh --list | tail -1 | awk '{print $1}') 106 | if [ ${currentCert} == ${domain} ]; then 107 | local certInfo=$(~/.acme.sh/acme.sh --list) 108 | LOGE "域名合法性校验失败,当前环境已有对应域名证书,不可重复申请,当前证书详情:" 109 | LOGI "$certInfo" 110 | exit 1 111 | else 112 | LOGI "证书有效性校验通过..." 113 | CERT_DOMAIN=${domain} 114 | fi 115 | } 116 | #function for domain check 117 | install_path_set() { 118 | cd ~ 119 | local InstallPath='' 120 | read -p "请输入证书安装路径:" InstallPath 121 | if [[ -n ${InstallPath} ]]; then 122 | LOGD "你输入的路径为:${InstallPath}" 123 | else 124 | InstallPath=${CERT_DEFAULT_INSTALL_PATH} 125 | LOGI "输入路径为空,将采用默认路径:${CERT_DEFAULT_INSTALL_PATH}" 126 | fi 127 | 128 | if [ ! -d "${InstallPath}" ]; then 129 | mkdir -p "${InstallPath}" 130 | else 131 | rm -rf "${InstallPath}" 132 | mkdir -p "${InstallPath}" 133 | fi 134 | 135 | if [ $? -ne 0 ]; then 136 | LOGE "设置安装路径失败,请确认" 137 | exit 1 138 | fi 139 | CERT_DEFAULT_INSTALL_PATH=${InstallPath} 140 | } 141 | 142 | #fucntion for port check 143 | port_check() { 144 | if [ $# -ne 1 ]; then 145 | LOGE "参数错误,脚本退出..." 146 | exit 1 147 | fi 148 | port_progress=$(lsof -i:$1 | wc -l) 149 | if [[ ${port_progress} -ne 0 ]]; then 150 | LOGD "检测到当前端口存在占用,请更换端口或者停止该进程" 151 | return 1 152 | fi 153 | return 0 154 | } 155 | 156 | #function for cert issue entry 157 | ssl_cert_issue() { 158 | local method="" 159 | echo -E "" 160 | LOGI "该脚本目前提供两种方式实现证书签发" 161 | LOGI "方式1:acme standalone mode,需要保持端口开放" 162 | LOGI "方式2:acme DNS API mode,需要提供Cloudflare Global API Key" 163 | LOGI "如域名属于免费域名,则推荐使用方式1进行申请" 164 | LOGI "如域名非免费域名且使用Cloudflare进行解析使用方式2进行申请" 165 | read -p "请选择你想使用的方式,请输入数字1或者2后回车": method 166 | LOGI "你所使用的方式为${method}" 167 | 168 | if [ "${method}" == "1" ]; then 169 | ssl_cert_issue_standalone 170 | elif [ "${method}" == "2" ]; then 171 | ssl_cert_issue_by_cloudflare 172 | else 173 | LOGE "输入无效,请检查你的输入,脚本将退出..." 174 | exit 1 175 | fi 176 | } 177 | 178 | #method for standalone mode 179 | ssl_cert_issue_standalone() { 180 | #install acme first 181 | install_acme 182 | if [ $? -ne 0 ]; then 183 | LOGE "无法安装acme,请检查错误日志" 184 | exit 1 185 | fi 186 | #install socat second 187 | if [[ x"${OS_CHECK}" == x"centos" ]]; then 188 | yum install socat -y 189 | else 190 | apt install socat -y 191 | fi 192 | if [ $? -ne 0 ]; then 193 | LOGE "无法安装socat,请检查错误日志" 194 | exit 1 195 | else 196 | LOGI "socat安装成功..." 197 | fi 198 | #creat a directory for install cert 199 | install_path_set 200 | #domain valid check 201 | domain_valid_check 202 | #get needed port here 203 | local WebPort=80 204 | read -p "请输入你所希望使用的端口,如回车将使用默认80端口:" WebPort 205 | if [[ ${WebPort} -gt 65535 || ${WebPort} -lt 1 ]]; then 206 | LOGE "你所选择的端口${WebPort}为无效值,将使用默认80端口进行申请" 207 | WebPort=80 208 | fi 209 | LOGI "将会使用${WebPort}端口进行证书申请,现进行端口检测,请确保端口处于开放状态..." 210 | #open the port and kill the occupied progress 211 | port_check ${WebPort} 212 | if [ $? -ne 0 ]; then 213 | LOGE "端口检测失败,请确保不被其他程序占用,脚本退出..." 214 | exit 1 215 | else 216 | LOGI "端口检测成功..." 217 | fi 218 | 219 | ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt 220 | ~/.acme.sh/acme.sh --issue -d ${CERT_DOMAIN} --standalone --httpport ${WebPort} 221 | if [ $? -ne 0 ]; then 222 | LOGE "证书申请失败,原因请参见报错信息" 223 | exit 1 224 | else 225 | LOGI "证书申请成功,开始安装证书..." 226 | fi 227 | #install cert 228 | ~/.acme.sh/acme.sh --installcert -d ${CERT_DOMAIN} --ca-file /root/cert/ca.cer \ 229 | --cert-file /root/cert/${CERT_DOMAIN}.cer --key-file /root/cert/${CERT_DOMAIN}.key \ 230 | --fullchain-file /root/cert/fullchain.cer 231 | 232 | if [ $? -ne 0 ]; then 233 | LOGE "证书安装失败,脚本退出" 234 | exit 1 235 | else 236 | LOGI "证书安装成功,开启自动更新..." 237 | fi 238 | ~/.acme.sh/acme.sh --upgrade --auto-upgrade 239 | if [ $? -ne 0 ]; then 240 | LOGE "自动更新设置失败,脚本退出" 241 | chmod 755 ${CERT_DEFAULT_INSTALL_PATH} 242 | exit 1 243 | else 244 | LOGI "证书已安装且已开启自动更新,具体信息如下" 245 | ls -lah ${CERT_DEFAULT_INSTALL_PATH} 246 | chmod 755 ${CERT_DEFAULT_INSTALL_PATH} 247 | fi 248 | 249 | } 250 | 251 | #method for DNS API mode 252 | ssl_cert_issue_by_cloudflare() { 253 | echo -E "" 254 | LOGI "该脚本将使用Acme脚本申请证书,使用时需保证:" 255 | LOGI "1.知晓Cloudflare 注册邮箱" 256 | LOGI "2.知晓Cloudflare Global API Key" 257 | LOGI "3.域名已通过Cloudflare进行解析到当前服务器" 258 | confirm "我已确认以上内容[y/n]" "y" 259 | if [ $? -eq 0 ]; then 260 | install_acme 261 | if [ $? -ne 0 ]; then 262 | LOGE "无法安装acme,请检查错误日志" 263 | exit 1 264 | fi 265 | #creat a directory for install cert 266 | install_path_set 267 | #Set DNS API 268 | CF_GlobalKey="" 269 | CF_AccountEmail="" 270 | 271 | #domain valid check 272 | domain_valid_check 273 | LOGD "请设置API密钥:" 274 | read -p "Input your key here:" CF_GlobalKey 275 | LOGD "你的API密钥为:${CF_GlobalKey}" 276 | LOGD "请设置注册邮箱:" 277 | read -p "Input your email here:" CF_AccountEmail 278 | LOGD "你的注册邮箱为:${CF_AccountEmail}" 279 | ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt 280 | if [ $? -ne 0 ]; then 281 | LOGE "修改默认CA为Lets'Encrypt失败,脚本退出" 282 | exit 1 283 | fi 284 | export CF_Key="${CF_GlobalKey}" 285 | export CF_Email=${CF_AccountEmail} 286 | ~/.acme.sh/acme.sh --issue --dns dns_cf -d ${CERT_DOMAIN} -d *.${CERT_DOMAIN} --log 287 | if [ $? -ne 0 ]; then 288 | LOGE "证书签发失败,脚本退出" 289 | exit 1 290 | else 291 | LOGI "证书签发成功,安装中..." 292 | fi 293 | ~/.acme.sh/acme.sh --installcert -d ${CERT_DOMAIN} -d *.${CERT_DOMAIN} --ca-file /root/cert/ca.cer \ 294 | --cert-file /root/cert/${CERT_DOMAIN}.cer --key-file /root/cert/${CERT_DOMAIN}.key \ 295 | --fullchain-file /root/cert/fullchain.cer 296 | if [ $? -ne 0 ]; then 297 | LOGE "证书安装失败,脚本退出" 298 | exit 1 299 | else 300 | LOGI "证书安装成功,开启自动更新..." 301 | fi 302 | ~/.acme.sh/acme.sh --upgrade --auto-upgrade 303 | if [ $? -ne 0 ]; then 304 | LOGE "自动更新设置失败,脚本退出" 305 | ls -lah cert 306 | chmod 755 ${CERT_DEFAULT_INSTALL_PATH} 307 | exit 1 308 | else 309 | LOGI "证书已安装且已开启自动更新,具体信息如下" 310 | ls -lah ${CERT_DEFAULT_INSTALL_PATH} 311 | chmod 755 ${CERT_DEFAULT_INSTALL_PATH} 312 | fi 313 | else 314 | LOGI "脚本退出..." 315 | exit 1 316 | fi 317 | } 318 | 319 | ssl_cert_issue 320 | -------------------------------------------------------------------------------- /SSLAutoInstall/media/bda84fbc2ede834deaba1c173a932223.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FranzKafkaYu/BashScripts/28adb22f2ea31ef558b11cd55a613ca493f8c191/SSLAutoInstall/media/bda84fbc2ede834deaba1c173a932223.png -------------------------------------------------------------------------------- /SSLAutoInstall/media/d13ffd6a73f938d1037d0708e31433bf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FranzKafkaYu/BashScripts/28adb22f2ea31ef558b11cd55a613ca493f8c191/SSLAutoInstall/media/d13ffd6a73f938d1037d0708e31433bf.png -------------------------------------------------------------------------------- /ShellConfig/ExampleConfig.conf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################################################## 3 | # 4 | #FILE : ExampleConfig.conf 5 | # 6 | #DESCRIPTION : One example for Linux shell config 7 | # 8 | #VERSION : 1.0.0 9 | #DATE : 2022-03-15 10 | #AUTHOR : FranzKafkaYu 11 | #HISTORY : 12 | # 13 | ######################################################## 14 | 15 | ######################################################## 16 | # A simple list 17 | ######################################################## 18 | # A simple list contain numbers and characters 19 | example_list=(0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N) 20 | 21 | #Here we need spilt numbers and characters 22 | sort_list=( 23 | 'TypeNumber 0 1 2 3 4 5 6 7 8 9' 24 | 'TypeCharacter A B C D E F G H' 25 | ) 26 | ######################################################## 27 | # number list 28 | ######################################################## 29 | number_list=(0 1 2 3 4 5 6 7 8 9) 30 | 31 | ######################################################## 32 | # character list 33 | ######################################################## 34 | character_list=(A B C D E F G H) 35 | -------------------------------------------------------------------------------- /ShellUtils/ShellUtils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################################################## 3 | # 4 | #FILE : ShellScriptUtils.sh 5 | # 6 | #DESCRIPTION : Some basic utils function 7 | # 8 | #VERSION : 1.0.0 9 | #DATE : 2022-03-15 10 | #AUTHOR : FranzKafkaYu 11 | #HISTORY : 12 | # 13 | ######################################################## 14 | # 获取脚本路径 15 | cd "$(dirname "$BASH_SOURCE")" 16 | script_file=$(pwd)/$(basename "$BASH_SOURCE") 17 | script_path=$(dirname "$script_file") 18 | cd - >/dev/null 19 | 20 | echo "ShellUtils.sh's path is ${script_path}" 21 | 22 | ######################################################## 23 | # 日志打印参数及函数 24 | ######################################################## 25 | # 脚本日志等级定义 26 | log_level_off=0 27 | log_level_error=1 28 | log_level_warn=2 29 | log_level_info=3 30 | log_level_verbose=4 31 | log_level_all=5 32 | 33 | # 默认日志等级 34 | log_level=$log_level_all 35 | 36 | # 函数功能:错误日志打印 37 | # 参数1:日志内容 38 | function LOGE() { 39 | if [ $log_level -ge $log_level_error ]; then 40 | echo -e "\033[1;31m$*\033[0m" 41 | fi 42 | } 43 | 44 | # 函数功能:警告日志打印 45 | # 参数1:日志内容 46 | function LOGW() { 47 | if [ $log_level -ge $log_level_warn ]; then 48 | echo -e "\033[1;33mWARN: $*\033[0m" 49 | fi 50 | } 51 | 52 | # 函数功能:通告日志打印 53 | # 参数1:日志内容 54 | function LOGI() { 55 | if [ $log_level -ge $log_level_info ]; then 56 | echo -e "\033[1;32mINFO: $*\033[0m" 57 | fi 58 | } 59 | 60 | # 函数功能:详细日志打印 61 | # 参数1:日志内容 62 | function LOGV() { 63 | if [ $log_level -ge $log_level_verbose ]; then 64 | echo -e "VERBOSE: $*" 65 | fi 66 | } 67 | 68 | # 函数功能:设置脚本日志等级 69 | # 参数1:脚本日志等级(取值参考脚本日志等级定义) 70 | # 返回值:设置成功返回0,设置失败返回1 71 | function SetEvsScriptLogLevel() { 72 | if [ $# -ne 1 ]; then 73 | LOGE "Input parameter error! parameter number:$#, need 1 parameter" 74 | return 1 75 | fi 76 | if [ $1 -lt $log_level_off -o $1 -gt $log_level_all ]; then 77 | LOGE "Error evs script log level:$1!" 78 | return 1 79 | fi 80 | log_level=$1 81 | return 0 82 | } 83 | 84 | # 函数功能:日志打印 85 | # 颜色:红色 86 | # 参数1:日志内容 87 | function LOG_RED() { 88 | echo -e "\033[1;31m$*\033[0m" 89 | } 90 | 91 | # 函数功能:日志打印 92 | # 颜色:黄色 93 | # 参数1:日志内容 94 | function LOG_YELLOW() { 95 | echo -e "\033[1;33m$*\033[0m" 96 | } 97 | 98 | # 函数功能:日志打印 99 | # 颜色:绿色 100 | # 参数1:日志内容 101 | function LOG_GREEN() { 102 | echo -e "\033[1;32m$*\033[0m" 103 | } 104 | 105 | # 函数功能:日志打印 106 | # 颜色:蓝色 107 | # 参数1:日志内容 108 | function LOG_BLUE() { 109 | echo -e "\033[1;34m$*\033[0m" 110 | } 111 | 112 | # 函数功能:日志打印 113 | # 颜色:紫色 114 | # 参数1:日志内容 115 | function LOG_PURPLE() { 116 | echo -e "\033[1;35m$*\033[0m" 117 | } 118 | 119 | # 函数功能:日志打印 120 | # 颜色:天蓝色 121 | # 参数1:日志内容 122 | function LOG_CERULEAN() { 123 | echo -e "\033[1;36m$*\033[0m" 124 | } 125 | 126 | # 函数功能:日志打印 127 | # 颜色:默认颜色色 128 | # 参数1:日志内容 129 | function LOG() { 130 | echo -e "$*" 131 | } 132 | 133 | ######################################################## 134 | # 公共函数 135 | ######################################################## 136 | # 函数功能:判断元素是否在列表中 137 | # 参数1:元素 138 | # 参数2:列表 139 | # 返回值:元素在列表中返回0,元素不在列表中返回1 140 | function contains() { 141 | if [ $# -ne 2 ]; then 142 | LOGE "Input parameter error! parameter number:$#, need 2 parameter" 143 | return 1 144 | fi 145 | local list=$2 146 | LOGV "list size:${#list[*]}" 147 | LOGV "list:${list[*]}" 148 | for element in ${list[@]}; do 149 | if [ "$element" = "$1" ]; then 150 | LOGV "The list:(${list[*]}) contains this element:$1" 151 | return 0 152 | fi 153 | done 154 | LOGE "The list:(${list[*]}) does not contain this element:$1" 155 | return 1 156 | } 157 | 158 | -------------------------------------------------------------------------------- /TelegramBot/SSHLoginAlert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #This script can send a alert when someone login into vps 3 | #date:2021-09-02 4 | #name:SSHLoginAlert.sh 5 | #author:FranzKafka 6 | 7 | echo "This is a script for ssh login alert" 8 | token=xxxxxxxxxxxxxxxxx 9 | echo "my token is $token" 10 | id=xxxxxx 11 | echo "my id is $id" 12 | message=$(hostname && TZ=UTC-8 date && who && w && last -1 | awk 'BEGIN{ORS="\t"}{print $1,$15}') 13 | echo "send message is $message,begin...." 14 | curl -v "https://api.telegram.org/bot${token}/sendMessage?chat_id=${id}" --data-binary "&text=${message}" 15 | echo "send alert end" 16 | -------------------------------------------------------------------------------- /crontabBot/CheckPeriodicStatus.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | #this script is used for excute periodic check fot Vpses 3 | #Author:FranzKafka 4 | #Date:2021-09-05 5 | 6 | echo "******This is a script for daily check for Vpses******" 7 | timeStamp=$(date) 8 | echo "Today is $timeStamp" 9 | #topCmd=$(top -o %CPU |head -n 17) 10 | echo "top cmd result is $topCmd" 11 | message=$(netstat -plunt && top -o %MEM|head -n 10) 12 | echo "This is information $message" 13 | token=******************************************** 14 | id=********** 15 | curl -s "https://api.telegram.org/bot${token}/sendMessage?chat_id=${id}" --data-binary "&text=${message}" 16 | -------------------------------------------------------------------------------- /x-ui/x-ui.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | red='\033[0;31m' 4 | green='\033[0;32m' 5 | yellow='\033[0;33m' 6 | plain='\033[0m' 7 | 8 | config_port="" 9 | config_account="" 10 | config_password="" 11 | 12 | # check root 13 | [[ $EUID -ne 0 ]] && echo -e "${red}错误: ${plain} 必须使用root用户运行此脚本!\n" && exit 1 14 | 15 | # check os 16 | if [[ -f /etc/redhat-release ]]; then 17 | release="centos" 18 | elif cat /etc/issue | grep -Eqi "debian"; then 19 | release="debian" 20 | elif cat /etc/issue | grep -Eqi "ubuntu"; then 21 | release="ubuntu" 22 | elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then 23 | release="centos" 24 | elif cat /proc/version | grep -Eqi "debian"; then 25 | release="debian" 26 | elif cat /proc/version | grep -Eqi "ubuntu"; then 27 | release="ubuntu" 28 | elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then 29 | release="centos" 30 | else 31 | echo -e "${red}未检测到系统版本,请联系脚本作者!${plain}\n" && exit 1 32 | fi 33 | 34 | os_version="" 35 | 36 | # os version 37 | if [[ -f /etc/os-release ]]; then 38 | os_version=$(awk -F'[= ."]' '/VERSION_ID/{print $3}' /etc/os-release) 39 | fi 40 | if [[ -z "$os_version" && -f /etc/lsb-release ]]; then 41 | os_version=$(awk -F'[= ."]+' '/DISTRIB_RELEASE/{print $2}' /etc/lsb-release) 42 | fi 43 | 44 | if [[ x"${release}" == x"centos" ]]; then 45 | if [[ ${os_version} -le 6 ]]; then 46 | echo -e "${red}请使用 CentOS 7 或更高版本的系统!${plain}\n" && exit 1 47 | fi 48 | elif [[ x"${release}" == x"ubuntu" ]]; then 49 | if [[ ${os_version} -lt 16 ]]; then 50 | echo -e "${red}请使用 Ubuntu 16 或更高版本的系统!${plain}\n" && exit 1 51 | fi 52 | elif [[ x"${release}" == x"debian" ]]; then 53 | if [[ ${os_version} -lt 8 ]]; then 54 | echo -e "${red}请使用 Debian 8 或更高版本的系统!${plain}\n" && exit 1 55 | fi 56 | fi 57 | 58 | confirm() { 59 | if [[ $# > 1 ]]; then 60 | echo && read -p "$1 [默认$2]: " temp 61 | if [[ x"${temp}" == x"" ]]; then 62 | temp=$2 63 | fi 64 | else 65 | read -p "$1 [y/n]: " temp 66 | fi 67 | if [[ x"${temp}" == x"y" || x"${temp}" == x"Y" ]]; then 68 | return 0 69 | else 70 | return 1 71 | fi 72 | } 73 | 74 | confirm_restart() { 75 | confirm "是否重启面板,重启面板也会重启 xray" "y" 76 | if [[ $? == 0 ]]; then 77 | restart 78 | else 79 | show_menu 80 | fi 81 | } 82 | 83 | before_show_menu() { 84 | echo && echo -n -e "${yellow}按回车返回主菜单: ${plain}" && read temp 85 | show_menu 86 | } 87 | 88 | install() { 89 | bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh) 90 | if [[ $? == 0 ]]; then 91 | if [[ $# == 0 ]]; then 92 | config_after_install 93 | start 94 | else 95 | start 0 96 | fi 97 | fi 98 | } 99 | 100 | #This function will be called when user installed x-ui out of sercurity 101 | config_after_install() { 102 | echo -e "${yellow}出于安全考虑,安装完成后需要强制修改端口与账户密码${plain}" 103 | read -p "请输入您的账户名:" config_account 104 | echo -e "${yellow}您的账户名将设定为:${config_account}${plain}" 105 | read -p "请输入您的账户密码:" config_password 106 | echo -e "${yellow}您的账户密码将设定为:${config_password}${plain}" 107 | read -p "请输入面板访问端口:" config_port 108 | echo -e "${yellow}您的面板访问端口将设定为:${config_password}${plain}" 109 | confirm "确认设定完成?" "y" 110 | if [ $? -eq 0 ]; then 111 | echo -e "${yellow}确认设定,设定中${plain}" 112 | /usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password} 113 | echo -e "${yellow}账户密码设定完成${plain}" 114 | /usr/local/x-ui/x-ui setting -port ${config_port} 115 | echo -e "${yellow}面板端口设定完成${plain}" 116 | else 117 | echo -e "${red}已取消,所有设置项均为默认设置,请及时修改${plain}" 118 | fi 119 | } 120 | 121 | update() { 122 | confirm "本功能会强制重装当前最新版,数据不会丢失,是否继续?" "n" 123 | if [[ $? != 0 ]]; then 124 | echo -e "${red}已取消${plain}" 125 | if [[ $# == 0 ]]; then 126 | before_show_menu 127 | fi 128 | return 0 129 | fi 130 | bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh) 131 | if [[ $? == 0 ]]; then 132 | echo -e "${green}更新完成,已自动重启面板${plain}" 133 | exit 0 134 | fi 135 | } 136 | 137 | uninstall() { 138 | confirm "确定要卸载面板吗,xray 也会卸载?" "n" 139 | if [[ $? != 0 ]]; then 140 | if [[ $# == 0 ]]; then 141 | show_menu 142 | fi 143 | return 0 144 | fi 145 | systemctl stop x-ui 146 | systemctl disable x-ui 147 | rm /etc/systemd/system/x-ui.service -f 148 | systemctl daemon-reload 149 | systemctl reset-failed 150 | rm /etc/x-ui/ -rf 151 | rm /usr/local/x-ui/ -rf 152 | 153 | echo "" 154 | echo -e "卸载成功,如果你想删除此脚本,则退出脚本后运行 ${green}rm /usr/bin/x-ui -f${plain} 进行删除" 155 | echo "" 156 | 157 | if [[ $# == 0 ]]; then 158 | before_show_menu 159 | fi 160 | } 161 | 162 | reset_user() { 163 | confirm "确定要将用户名和密码重置为 admin 吗" "n" 164 | if [[ $? != 0 ]]; then 165 | if [[ $# == 0 ]]; then 166 | show_menu 167 | fi 168 | return 0 169 | fi 170 | /usr/local/x-ui/x-ui setting -username admin -password admin 171 | echo -e "用户名和密码已重置为 ${green}admin${plain},现在请重启面板" 172 | confirm_restart 173 | } 174 | 175 | reset_config() { 176 | confirm "确定要重置所有面板设置吗,账号数据不会丢失,用户名和密码不会改变" "n" 177 | if [[ $? != 0 ]]; then 178 | if [[ $# == 0 ]]; then 179 | show_menu 180 | fi 181 | return 0 182 | fi 183 | /usr/local/x-ui/x-ui setting -reset 184 | echo -e "所有面板设置已重置为默认值,现在请重启面板,并使用默认的 ${green}54321${plain} 端口访问面板" 185 | confirm_restart 186 | } 187 | 188 | set_port() { 189 | echo && echo -n -e "输入端口号[1-65535]: " && read port 190 | if [[ -z "${port}" ]]; then 191 | echo -e "${yellow}已取消${plain}" 192 | before_show_menu 193 | else 194 | /usr/local/x-ui/x-ui setting -port ${port} 195 | echo -e "设置端口完毕,现在请重启面板,并使用新设置的端口 ${green}${port}${plain} 访问面板" 196 | confirm_restart 197 | fi 198 | } 199 | 200 | start() { 201 | check_status 202 | if [[ $? == 0 ]]; then 203 | echo "" 204 | echo -e "${green}面板已运行,无需再次启动,如需重启请选择重启${plain}" 205 | else 206 | systemctl start x-ui 207 | sleep 2 208 | check_status 209 | if [[ $? == 0 ]]; then 210 | echo -e "${green}x-ui 启动成功${plain}" 211 | else 212 | echo -e "${red}面板启动失败,可能是因为启动时间超过了两秒,请稍后查看日志信息${plain}" 213 | fi 214 | fi 215 | 216 | if [[ $# == 0 ]]; then 217 | before_show_menu 218 | fi 219 | } 220 | 221 | stop() { 222 | check_status 223 | if [[ $? == 1 ]]; then 224 | echo "" 225 | echo -e "${green}面板已停止,无需再次停止${plain}" 226 | else 227 | systemctl stop x-ui 228 | sleep 2 229 | check_status 230 | if [[ $? == 1 ]]; then 231 | echo -e "${green}x-ui 与 xray 停止成功${plain}" 232 | else 233 | echo -e "${red}面板停止失败,可能是因为停止时间超过了两秒,请稍后查看日志信息${plain}" 234 | fi 235 | fi 236 | 237 | if [[ $# == 0 ]]; then 238 | before_show_menu 239 | fi 240 | } 241 | 242 | restart() { 243 | systemctl restart x-ui 244 | sleep 2 245 | check_status 246 | if [[ $? == 0 ]]; then 247 | echo -e "${green}x-ui 与 xray 重启成功${plain}" 248 | else 249 | echo -e "${red}面板重启失败,可能是因为启动时间超过了两秒,请稍后查看日志信息${plain}" 250 | fi 251 | if [[ $# == 0 ]]; then 252 | before_show_menu 253 | fi 254 | } 255 | 256 | status() { 257 | systemctl status x-ui -l 258 | if [[ $# == 0 ]]; then 259 | before_show_menu 260 | fi 261 | } 262 | 263 | enable() { 264 | systemctl enable x-ui 265 | if [[ $? == 0 ]]; then 266 | echo -e "${green}x-ui 设置开机自启成功${plain}" 267 | else 268 | echo -e "${red}x-ui 设置开机自启失败${plain}" 269 | fi 270 | 271 | if [[ $# == 0 ]]; then 272 | before_show_menu 273 | fi 274 | } 275 | 276 | disable() { 277 | systemctl disable x-ui 278 | if [[ $? == 0 ]]; then 279 | echo -e "${green}x-ui 取消开机自启成功${plain}" 280 | else 281 | echo -e "${red}x-ui 取消开机自启失败${plain}" 282 | fi 283 | 284 | if [[ $# == 0 ]]; then 285 | before_show_menu 286 | fi 287 | } 288 | 289 | show_log() { 290 | journalctl -u x-ui.service -e --no-pager -f 291 | if [[ $# == 0 ]]; then 292 | before_show_menu 293 | fi 294 | } 295 | 296 | migrate_v2_ui() { 297 | /usr/local/x-ui/x-ui v2-ui 298 | 299 | before_show_menu 300 | } 301 | 302 | install_bbr() { 303 | # temporary workaround for installing bbr 304 | bash <(curl -L -s https://raw.githubusercontent.com/teddysun/across/master/bbr.sh) 305 | echo "" 306 | before_show_menu 307 | } 308 | 309 | update_shell() { 310 | wget -O /usr/bin/x-ui -N --no-check-certificate https://github.com/vaxilu/x-ui/raw/master/x-ui.sh 311 | if [[ $? != 0 ]]; then 312 | echo "" 313 | echo -e "${red}下载脚本失败,请检查本机能否连接 Github${plain}" 314 | before_show_menu 315 | else 316 | chmod +x /usr/bin/x-ui 317 | echo -e "${green}升级脚本成功,请重新运行脚本${plain}" && exit 0 318 | fi 319 | } 320 | 321 | # 0: running, 1: not running, 2: not installed 322 | check_status() { 323 | if [[ ! -f /etc/systemd/system/x-ui.service ]]; then 324 | return 2 325 | fi 326 | temp=$(systemctl status x-ui | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1) 327 | if [[ x"${temp}" == x"running" ]]; then 328 | return 0 329 | else 330 | return 1 331 | fi 332 | } 333 | 334 | check_enabled() { 335 | temp=$(systemctl is-enabled x-ui) 336 | if [[ x"${temp}" == x"enabled" ]]; then 337 | return 0 338 | else 339 | return 1 340 | fi 341 | } 342 | 343 | check_uninstall() { 344 | check_status 345 | if [[ $? != 2 ]]; then 346 | echo "" 347 | echo -e "${red}面板已安装,请不要重复安装${plain}" 348 | if [[ $# == 0 ]]; then 349 | before_show_menu 350 | fi 351 | return 1 352 | else 353 | return 0 354 | fi 355 | } 356 | 357 | check_install() { 358 | check_status 359 | if [[ $? == 2 ]]; then 360 | echo "" 361 | echo -e "${red}请先安装面板${plain}" 362 | if [[ $# == 0 ]]; then 363 | before_show_menu 364 | fi 365 | return 1 366 | else 367 | return 0 368 | fi 369 | } 370 | 371 | show_status() { 372 | check_status 373 | case $? in 374 | 0) 375 | echo -e "面板状态: ${green}已运行${plain}" 376 | show_enable_status 377 | ;; 378 | 1) 379 | echo -e "面板状态: ${yellow}未运行${plain}" 380 | show_enable_status 381 | ;; 382 | 2) 383 | echo -e "面板状态: ${red}未安装${plain}" 384 | ;; 385 | esac 386 | show_xray_status 387 | } 388 | 389 | show_enable_status() { 390 | check_enabled 391 | if [[ $? == 0 ]]; then 392 | echo -e "是否开机自启: ${green}是${plain}" 393 | else 394 | echo -e "是否开机自启: ${red}否${plain}" 395 | fi 396 | } 397 | 398 | check_xray_status() { 399 | count=$(ps -ef | grep "xray-linux" | grep -v "grep" | wc -l) 400 | if [[ count -ne 0 ]]; then 401 | return 0 402 | else 403 | return 1 404 | fi 405 | } 406 | 407 | show_xray_status() { 408 | check_xray_status 409 | if [[ $? == 0 ]]; then 410 | echo -e "xray 状态: ${green}运行${plain}" 411 | else 412 | echo -e "xray 状态: ${red}未运行${plain}" 413 | fi 414 | } 415 | 416 | show_usage() { 417 | echo "x-ui 管理脚本使用方法: " 418 | echo "------------------------------------------" 419 | echo "x-ui - 显示管理菜单 (功能更多)" 420 | echo "x-ui start - 启动 x-ui 面板" 421 | echo "x-ui stop - 停止 x-ui 面板" 422 | echo "x-ui restart - 重启 x-ui 面板" 423 | echo "x-ui status - 查看 x-ui 状态" 424 | echo "x-ui enable - 设置 x-ui 开机自启" 425 | echo "x-ui disable - 取消 x-ui 开机自启" 426 | echo "x-ui log - 查看 x-ui 日志" 427 | echo "x-ui v2-ui - 迁移本机器的 v2-ui 账号数据至 x-ui" 428 | echo "x-ui update - 更新 x-ui 面板" 429 | echo "x-ui install - 安装 x-ui 面板" 430 | echo "x-ui uninstall - 卸载 x-ui 面板" 431 | echo "------------------------------------------" 432 | } 433 | 434 | show_menu() { 435 | echo -e " 436 | ${green}x-ui 面板管理脚本${plain} 437 | ${green}0.${plain} 退出脚本 438 | ———————————————— 439 | ${green}1.${plain} 安装 x-ui 440 | ${green}2.${plain} 更新 x-ui 441 | ${green}3.${plain} 卸载 x-ui 442 | ———————————————— 443 | ${green}4.${plain} 重置用户名密码 444 | ${green}5.${plain} 重置面板设置 445 | ${green}6.${plain} 设置面板端口 446 | ———————————————— 447 | ${green}7.${plain} 启动 x-ui 448 | ${green}8.${plain} 停止 x-ui 449 | ${green}9.${plain} 重启 x-ui 450 | ${green}10.${plain} 查看 x-ui 状态 451 | ${green}11.${plain} 查看 x-ui 日志 452 | ———————————————— 453 | ${green}12.${plain} 设置 x-ui 开机自启 454 | ${green}13.${plain} 取消 x-ui 开机自启 455 | ———————————————— 456 | ${green}14.${plain} 一键安装 bbr (最新内核) 457 | " 458 | show_status 459 | echo && read -p "请输入选择 [0-14]: " num 460 | 461 | case "${num}" in 462 | 0) 463 | exit 0 464 | ;; 465 | 1) 466 | check_uninstall && install 467 | ;; 468 | 2) 469 | check_install && update 470 | ;; 471 | 3) 472 | check_install && uninstall 473 | ;; 474 | 4) 475 | check_install && reset_user 476 | ;; 477 | 5) 478 | check_install && reset_config 479 | ;; 480 | 6) 481 | check_install && set_port 482 | ;; 483 | 7) 484 | check_install && start 485 | ;; 486 | 8) 487 | check_install && stop 488 | ;; 489 | 9) 490 | check_install && restart 491 | ;; 492 | 10) 493 | check_install && status 494 | ;; 495 | 11) 496 | check_install && show_log 497 | ;; 498 | 12) 499 | check_install && enable 500 | ;; 501 | 13) 502 | check_install && disable 503 | ;; 504 | 14) 505 | install_bbr 506 | ;; 507 | *) 508 | echo -e "${red}请输入正确的数字 [0-14]${plain}" 509 | ;; 510 | esac 511 | } 512 | 513 | if [[ $# > 0 ]]; then 514 | case $1 in 515 | "start") 516 | check_install 0 && start 0 517 | ;; 518 | "stop") 519 | check_install 0 && stop 0 520 | ;; 521 | "restart") 522 | check_install 0 && restart 0 523 | ;; 524 | "status") 525 | check_install 0 && status 0 526 | ;; 527 | "enable") 528 | check_install 0 && enable 0 529 | ;; 530 | "disable") 531 | check_install 0 && disable 0 532 | ;; 533 | "log") 534 | check_install 0 && show_log 0 535 | ;; 536 | "v2-ui") 537 | check_install 0 && migrate_v2_ui 0 538 | ;; 539 | "update") 540 | check_install 0 && update 0 541 | ;; 542 | "install") 543 | check_uninstall 0 && install 0 544 | ;; 545 | "uninstall") 546 | check_install 0 && uninstall 0 547 | ;; 548 | *) show_usage ;; 549 | esac 550 | else 551 | show_menu 552 | fi 553 | -------------------------------------------------------------------------------- /xrayUtils/xrayTrafficCheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #This shell script will help you to check xray traffic by its given api 4 | #And this script takes example by v2ray 5 | #Author:FranzKafka 6 | #Date:2022-03-019 7 | #Version:0.0.1 8 | 9 | #Here we set some basic args here 10 | 11 | xrayApiServer=127.0.0.1:62789 12 | xrayBinary=/usr/local/x-ui/bin/xray-linux-amd64 13 | 14 | apidata() { 15 | local ARGS= 16 | if [[ $1 == "reset" ]]; then 17 | ARGS="reset: true" 18 | fi 19 | $xrayBinary api statsquery --server=$xrayApiServer "${ARGS}" | 20 | awk '{ 21 | if (match($1, /"name":/)) { 22 | f=1; gsub(/^"|link"|,$/, "", $2); 23 | split($2, p, ">>>"); 24 | printf "%s:%s->%s\t", p[1],p[2],p[4]; 25 | } 26 | else if (match($1, /"value":/) && f){ f = 0; printf "%.0f\n", $2; } 27 | else if (match($0, /}/) && f) { f = 0; print 0; } 28 | }' 29 | } 30 | 31 | print_sum() { 32 | local DATA="$1" 33 | local PREFIX="$2" 34 | local SORTED=$(echo "$DATA" | grep "^${PREFIX}" | sort -r) 35 | local SUM=$(echo "$SORTED" | awk ' 36 | /->up/{us+=$2} 37 | /->down/{ds+=$2} 38 | END{ 39 | printf "SUM->up:\t%.0f\nSUM->down:\t%.0f\nSUM->TOTAL:\t%.0f\n", us, ds, us+ds; 40 | }') 41 | echo -e "${SORTED}\n${SUM}" | 42 | numfmt --field=2 --suffix=B --to=iec | 43 | column -t 44 | } 45 | 46 | DATA=$(apidata $1) 47 | echo "------------Inbound----------" 48 | print_sum "$DATA" "inbound" 49 | echo "-----------------------------" 50 | echo "------------Outbound----------" 51 | print_sum "$DATA" "outbound" 52 | echo "-----------------------------" 53 | echo 54 | echo "-------------User------------" 55 | print_sum "$DATA" "user" 56 | echo "-----------------------------" 57 | --------------------------------------------------------------------------------