• Cygwin/WSL专用Shell函数,restartps:带命令行参数重启某进程


    restart-ps() {
    	# 借助WMIC命令(封装后的参数为wmicps),带命令行参数重启指定进程
    	if [ $# -eq 0 ] || [[ "${*,,}" == "-h" || "${*,,}" == "--help" ]];then
    		echo "restart-ps:带命令行参数重启某进程,例如重启frpc等进程极为有用!"
    		echo -e "\nUsage  :restart-ps process-name"
    		echo -e "\nExample:restart-ps frpc.exe"
    		echo -e "\t restart-ps frpc"
    		return
    	fi
    	psInfo=$(wmicps "$1") #依赖于本文件另一函数wmicps
    	cmdInfo=$(echo "$psInfo"|awk '/CommandLine=/{print $0};/ExecutablePath=/{print $0}'|dos2unix -q|iconv -f GBK -t UTF-8) #注意适配命令行参数带中文的情况:iconv	
    	[ -z "$cmdInfo" ] && {
    		echo "没有找到相关进程..."
    		return
    	}
    	
    	if [ $(echo "$cmdInfo"|wc -l) -gt 2 ];then
    		#echo "当前进程存在多个同名实例,程序无法自动判断,请手动进行重启!"
    		#echo "程序退出..."
    		echo "进程名存在多个同名实例,将进入多实例判断程序,请根据情况选择你需要操作哪一个进程!"
    		restart-multi-ps "$1"
    		return
    	else
    		echo "$cmdInfo"
    		OLD_IFS=$IFS
    		IFS=$(echo -e "\n")
    		exePath=$(echo "$cmdInfo"|awk -F '=' '/ExecutablePath=/{print $2;exit}')
    		commandLine=$(echo "$cmdInfo"|awk -F '=' '/CommandLine=/{sub($1"=","");print $0;exit}')
    		batPrefix=""
    		
    		echo "$commandLine"|grep -iE '\.exe"? ' &>/dev/null
    		if [ $? -eq 0 ];then
    			runCommandLine="$commandLine"
    		else
    			echo "命令行参数需要特殊处理..."
    			batPrefix="@pushd \""$(cygpath -aw `dirname "$exePath"`)"\""
    			_commandLine=$(echo "$commandLine"|awk -F ' ' '{gsub($1" ","");print $0}')
    			runCommandLine="\"$exePath\" ${_commandLine}"
    		fi
    		echo "Origin run Command is:$runCommandLine"
    		winkill "$1"
    		echo "重启进程ing..."	
    		local runbat=$(mktemp --suffix=.bat)
    		cat>$runbat<<<"${batPrefix}"$'\r\n'"@start \"\" $runCommandLine"
    		cat $runbat
    		chmod a+x "$runbat"
    		cmd /Q /c `cygpath -aw $runbat`
    		[ -f "$runbat" ] && rm -vf $runbat
    		IFS=$OLD_IFS
    	fi
    }
    
    



    增强版重启进程函数:restart-multi-ps

    适配系统存在多个同名进程的情况,可以手动输入序号选择操作哪一个进程;

    restart-multi-ps() {
    	# 重启某进程,本函数匹配多个同名进程实例存在的情况
    	if [ $# -eq 0 ] || [[ "${*,,}" == "-h" || "${*,,}" == "--help" ]];then
    		echo "restart-multi-ps:带命令行参数重启某进程,例如重启frpc等进程极为有用!"
    		echo "restart-multi-ps:本函数适配存在多个同名进程的情况,提供手动输入序号选择的选项!"
    		echo -e "\n参数说明:"
    		echo -e "  \$1 —— 必选,进程名称,eg:msedge|msedge.exe"
    		echo -e "  \$2 —— 可选,指定运行窗口显示方式,显示或隐藏;有效的参数有两个:show/hide,可省略,默认为show"
    		echo -e "  \$3 —— 可选,start命令运行窗口的Caption标题栏,可省略,默认为空"
    		echo -e "\nUsage  :restart-multi-ps process-name [windows state(show/hide)] [cmd Caption]"
    		echo -e "\nExample:restart-multi-ps frpc.exe"
    		echo -e "\t restart-multi-ps frpc"
    		echo -e "\t restart-multi-ps frpc.exe Caption:Frpc内网穿透"
    		echo -e "\t restart-multi-ps frpc.exe hide 第一个Frpc进程..."
    		echo -e "\t restart-multi-ps frpc.exe show 第二个Frpc进程..."
    		return
    	fi
    	local psName="$1"
    	local windowState="$2"
    	psInfo=$(wmicps "$psName" --nopath|dos2unix -q|iconv -f GBK -t UTF-8|grep -iE '(ProcessId=|ExecutablePath=|CommandLine=)') #注意iconv兼容命令行参数带中文的情况
    	if [ -z "$psInfo" ];then
    		echo "没有找到相关进程..."
    		return
    	fi
    	
    	psCount=0
    	parsePsInfo() {
    		if [[ "$2" =~ CommandLine\= ]];then 
    			let psCount+=1
    			echo -e "\n==============="
    			echo -e "\033[32m${psCount}:\033[0m"
    		fi
    		echo "$2"
    		if [[ "$2" =~ ProcessId\= ]];then 
    			echo "---------------------"
    		fi
    	}
    
    	mapfile -t -C "parsePsInfo" -c 1 <<<"$psInfo"
    	echo "提示:按Pid终止单个进程请直接输入序号数字即可,如 12,如果需终止所有同名进程,并按所选的命令行参数重新运行进程,请输入任意字母+数字序号,比如 \`a12\`"
    	read -p "共有 $psCount 个同名实例,你要操作哪一个进程,请选择:" psChoose
    	psItem=$(echo "$psChoose"|sed -r 's/[^0-9]//g')
    	if [ -z "$psItem" ];then
    		echo "退出选择..."
    		return
    	fi
    	#echo "$psInfo"|awk -v selectedLine="$psChoose" '/(selectedLine-1)*3,(selectedLine-1)*3+3/{print}'
    	psItemInfo=$(echo "$psInfo"|awk -v startLine=$((($psItem-1)*3)) '(NR>startLine&&NR<=(startLine+3)){print}')
    	expr $psChoose + 0 &>/dev/null
    	if [ $? -eq 0 ];then	
    		echo "终止单个进程,序号: $psChoose"
    		local pid=$(echo "$psItemInfo"|awk -F '=' '/ProcessId=/{sub("ProcessId=","");print;exit}')
    		echo "终止进程 pid:$pid"
    		winkill $pid
    	else
    		echo "终止所有进程 $psName"
    		winkill "$psName"
    	fi
    	
    	OLD_IFS=$IFS
    	IFS=$(echo -e "\n")
    	exePath=$(echo "$psItemInfo"|awk -F '=' '/ExecutablePath=/{print $2;exit}')
    	commandLine=$(echo "$psItemInfo"|awk -F '=' '/CommandLine=/{sub($1"=","");print $0;exit}')
    	batPrefix=""
    	##判断窗口隐藏状态,部分Console类窗口视具体情况可能需要隐藏运行,如(mysqld、httpd等),也可以在$2中使用`show`或`hide`显式指定
    	if [[ "${windowState,,}" == "show" ]];then
    		local runState=" "
    		shift
    	elif [[ "${windowState,,}" == "hide" ]];then
    		local runState=" /B "
    		shift
    	##针对一些常用的后台进程常驻服务(MySQL、MongoDB等)。不指定窗口显示方式时,默认方式即设为隐藏窗口
    	elif [ -z "${windowState}" ] && [[ "${psName,,}" =~ ^mysqld || "${psName,,}" =~ ^httpd || "${psName,,}" =~ ^frpc ]];then
    		local runState=" /B "
    	else
    		local runState=" "
    	fi
    	
    	echo "$commandLine"|grep -iE '\\.*\.exe"? ' &>/dev/null
    	if [ $? -eq 0 ];then
    		runCommandLine="$commandLine"
    		batPrefix="@pushd \""$(cygpath -aw `dirname "$exePath"`)"\"" #保险起见:无论如何都pushd到可执行文件所在路径
    	else
    		echo "命令行参数需要特殊处理..."
    		batPrefix="@pushd \""$(cygpath -aw `dirname "$exePath"`)"\""
    		_commandLine=$(echo "$commandLine"|awk -F ' ' '{gsub($1" ","");print $0}')
    		runCommandLine="\"$exePath\" ${_commandLine}"
    	fi
    	echo "Origin run Command is:$runCommandLine"
    	echo "重启进程ing..."	
    	local runbat=$(mktemp --suffix=.bat)
    	local caption=""
    	[ ! -z "$2" ] && caption="$2"
    	cat>$runbat<<<"${batPrefix}"$'\r\n'"@start \"${caption}\"${runState}$runCommandLine"
    	cat $runbat
    	chmod a+x "$runbat"
    	cmd /Q /c `cygpath -aw $runbat`
    	[ -f "$runbat" ] && rm -vf $runbat
    	IFS=$OLD_IFS
    }
    

    使用帮助:


    运行效果:


    附:根据进程id(pid)重启某进程函数 restart-ps-by-pid:

    restart-ps-by-pid() {
    	# 根据进程ID(pid),带命令行参数重启指定进程
    	#支持一次传递多个pid,eg:restart-ps-by-pid 12 32 11 ...
    	if [ $# -eq 0 ] || [[ "${*,,}" == "-h" || "${*,,}" == "--help" ]];then
    		echo "restart-ps-by-pid:根据进程ID(pid),带命令行参数重启某进程!"
    		echo -e "\t 注:可一次传递多个参数(\$*),对多个进程进行操作!"
    		echo -e "\nUsage  :restart-ps-by-pid pid1 pid2 pid3 ..."
    		echo -e "\nExample:restart-ps-by-pid 2003"
    		echo -e "\t restart-ps-by-pid 1005 2003"
    		return
    	fi
    	while [ $# -gt 0 ];
    	do
    		local pid="$1"
    		shift
    		print_color 33 "重启 pid 为 $pid 的进程 ..."
    		local psInfo=$(gsudo cmd /c wmic process Where ProcessId=\"${pid}\" get Name,ExecutionState,ExecutablePath,CommandLine,Status,ProcessId,UserModeTime,WindowsVersion /FORMAT:List|dos2unix -q|iconv -f GBK -t UTF-8|sed -r '/^[\s\t]*\r*\n*$/d')
    		local cmdInfo=$(echo "$psInfo"|awk '/CommandLine=/{print $0};/ExecutablePath=/{print $0}'|dos2unix -q|iconv -f GBK -t UTF-8) #注意适配命令行参数带中文的情况:iconv	
    		[ -z "$cmdInfo" ] && {
    			print_color 9 "pid ==> $pid,没有找到相关进程..."
    			continue
    		}
    		echo "$cmdInfo"
    		OLD_IFS=$IFS
    		IFS=$(echo -e "\n")
    		local exePath=$(echo "$cmdInfo"|awk -F '=' '/ExecutablePath=/{print $2;exit}')
    		local commandLine=$(echo "$cmdInfo"|awk -F '=' '/CommandLine=/{sub($1"=","");print $0;exit}')
    		local psName=$(echo "$psInfo"|awk -F '=' '/Name=/{print $2;exit}')
    		local batPrefix=""
    		local startPrefix="@start" #默认start方式,使用显示窗口的情况
    		
    		if [[ "${psName,,}" =~ ^mysqld || "${psName,,}" =~ ^httpd || "${psName,,}" =~ ^frpc ]];then
    			local runState=" /B "
    			#local runState=" "
    			#local startPrefix="@start cmd /c start" #修改start方式,隐式运行窗口的情况;
    		else
    			local runState=" "
    		fi
    		
    		echo "$commandLine"|grep -iE '\.exe"? ' &>/dev/null
    		if [ $? -eq 0 ];then
    			runCommandLine="$commandLine"
    			batPrefix="@pushd \""$(cygpath -aw `dirname "$exePath"`)"\"" #保险起见:无论如何都pushd到可执行文件所在路径
    		else
    			echo "命令行参数需要特殊处理..."
    			batPrefix="@pushd \""$(cygpath -aw `dirname "$exePath"`)"\""
    			_commandLine=$(echo "$commandLine"|awk -F ' ' '{gsub($1" ","");print $0}')
    			runCommandLine="\"$exePath\" ${_commandLine}"
    		fi
    		echo "Origin run Command is:$runCommandLine"
    		winkill $pid
    		echo "重启进程ing..."	
    		local runbat=$(mktemp --suffix=.bat)
    		local caption=""
    		#local caption="$runCommandLine" #标题栏暂定命令行运行参数
    		cat>$runbat<<<"${batPrefix}"$'\r\n'"${startPrefix} \"${caption}\"${runState}$runCommandLine"
    		cat $runbat
    		chmod a+x "$runbat"
    		if [[ "$runState" == " /B " ]];then #借助VBS运行隐藏的控制台窗口,否则直接使用CMD /B参数开关操作多进程老是有问题,第二个进程老是莫名其妙挂掉!
    			cscript.exe //nologo `cygpath -aw /v/scripts/WscriptRun.vbs` "`cygpath -aw $runbat`"
    		else
    			cmd /Q /c `cygpath -aw $runbat`
    		fi
    		[ -f "$runbat" ] && rm -vf $runbat
    		IFS=$OLD_IFS
    		print_color 33 "pid ==> $pid 进程重启 Done ..."
    		echo -e "\n"
    	done
    }
    
  • 相关阅读:
    课时15.DTD文档声明下(了解)
    Python-01 学习第一节
    常用数据库备份还原命令
    Oracle排除记录集
    存储过程分页语句
    TFS统计编码行数语句
    数据库所有表替换所有列的特定字符串
    MSSQL查询所有数据库表,指定数据库的字段、索引
    统计整个库所有表的记录数
    执​行​o​r​a​c​l​e​函​数​的​四​种​方​法
  • 原文地址:https://www.cnblogs.com/cnhack/p/15970116.html
Copyright © 2020-2023  润新知