Linux上自动执行程序脚本
自动执行程序的脚本:
启动程序的shell脚本
#!/bin/bashrun_program() {#表示第一个参数program=$1program_path="./$program"# 去掉扩展名,拼接成 XXX_log 的形式log_file="${program%%.*}_log"chmod 777 "$program_path"# 检查该程序后台是否正在运行pid=$(pgrep -f "$program_path")# 如果后台正在运行就kill掉该程序if [ -n "$pid" ]; thensudo kill "$pid" > /dev/null 2>&1sleep 1 # kill掉之后休息1秒钟,等待清理资源fi# 启动该程序,并将结果重定向到log文件,"2>&1" 表示将标准错误重定向到标准输出所指向的位置,即log文件# 最后一个 "&" 表示把前面的整个命令放到后台执行,不会阻塞脚本的继续执行,否则会阻塞脚本,直到程序运行结束sudo "$program_path" >> "$log_file" 2>&1 &
}----# 根据需要添加要启动的程序
run_program "s1.out"
run_program "s2.out"
在程序中自动生成该脚本
在一些场景下需要自动生成这样的脚本,并下载对应的Linux设备上,让用户实现一键式部署,无需再手动的修改启动脚本,对应的生成脚本代码如下:
生成脚本代码
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>using std::string;
using std::vector;void WriteShell(const vector<string>& vec, const string& fileName);int main()
{string fileName = "D:/Tmp/start.sh";vector<string> vec = { "s1.out","s2.out","s3.out" };WriteShell(vec, fileName);
}void WriteShell(const vector<string>& vec, const string& fileName)
{std::stringstream sstr;// 1-1. 写入固定部分的内容,原始字符串: R"delimiter(content)delimiter"sstr << R"----(#!/bin/bash# This script was generated dynamically by a C++ program.run_program() {program=$1program_path="./$program"# 将日志文件名后缀改为 .loglog_file="${program%%.*}.log"echo "Handling program: $program"# 赋予执行权限chmod +x "$program_path"# 使用 pgrep 查找进程pid=$(pgrep -f "$program_path")# 检查进程是否存在if [ -n "$pid" ]; thenecho "Process for $program found with PID: $pid. Attempting to kill."sudo kill "$pid" > /dev/null 2>&1sleep 1fiecho "Starting $program in background. Log will be at $log_file"sudo "$program_path" >> "$log_file" 2>&1 &
})----";// 1-2. 将动态的变量写入脚本for (const auto& str : vec){sstr << "run_program \"" << str << "\"\n";}// 1-3. 写入结束提示信息sstr << "\necho \"Shell excute finished.\"\n";//2. 将文件写入到本地文件中// 2-1. 从stringstream中获取获取完整的字符串string resContentStr = sstr.str();// 2-2. 以二进制模式打开文本文件,保证Linux格式的换行符(LF),// 避免在Windows上写入换行符 "\n"时,C++将其转换成 "\r\n",然后在Linux上运行该脚本时,由于多了"\r"导致报错:"command not found: ^M"// std::ios::binary,我们告诉文件流:“不要做任何换行符转换,字符串里是什么字节,就原封不动地写入文件std::ofstream out(fileName, std::ios::binary);if (!out){std::cerr << "Error: unable to open file" << std::endl;return;}out << resContentStr;out.close();
}
【注意】
- 写入代码中,要插入的固定代码部分建议使用原始C++11的字符串,能够直观的显示原始的格式和字符。
- 写入时以
std::ios::binary
格式打开文件,避免在Windows上的自动\r\n
换行符无法被Linux识别的问题