一直以来我都有一个痛点,我希望写一些比较小的程序的时候可以不用打开IDE,刚入门的时候看Java动力节点的视频,当时是跟着配EditPlus,后面不知道为什么我就用了npp了,然后java、c、c++、python、php,什么语言我都设置一个运行的快捷键给它,我就发现我需要记下来的快捷键好多,再后来npp有一次更新我看到了更新log,就觉得挺失望的,挺长一段时间没有用,但是最近开始刷题,就确实IDE启动速度太慢了,所以不管了我自己方便就行。
进入正题
需要根据运行程序的类型来分类型编译
-
若后缀为asm,则使用nasm进行编译,不需要打开编译后的二进制文件
-
若后缀为c,则使用gcc进行编译
-
若后缀为cpp或者cc,则使用g++进行编译
编译结果得到的EXE文件直接在命令行打开
-
若后缀为java,则使用Javac进行编译,编译完成之后在命令行使用java启动对应Main的class文件
-
若后缀为py,则使用Python直接运行
在编译前需要:
-
判断对应后缀是否能够处理,不能处理应直接退出并给出提示
-
判断对应的编译工具是否存在,若存在才进行编译,否则直接退出并给出提示,也就是说,需要配置各种环境的home路径,而不是依赖系统配置的PATH
为了实现跨平台,所以选择使用shell脚本来实现,在Windows下要跑shell脚本的话,可以使用msys,msys即将不再支持win7,所以使用Windows的git附带的bash也是可以的。
shell脚本:
#!/bin/bash
#echo $0 $1 $2 $3
export OS_TYPE=$(uname -s) #Linux为Linux,MacOS为Darwin
#export OS_TYPE=Linux
function del_file(){
export filename=$1
if [ -f $filename ]; then #在进入编译前,首先得先删除可能的第一次编译结果
rm -f $filename > /dev/null 2>&1 #输出重定向,使得文件占用时的错误输出不要显示
if [ -f $filename ]; then
echo -e "\e[31m目标文件占用中,无法编译\e[0m"
exit
fi
fi
}
function check_home_path(){
#根据传进来的环境名称检查对应的path是否存在
export HOME_NAME=$1
export HOME_PATH=$(eval echo '$'${HOME_NAME}_HOME)
#echo $HOME_PATH
if [ "$HOME_PATH" == "" ]; then
if [ "$2" != "hide" ]; then
echo -e "$HOME_NAME环境不存在,请检查\e[31m$HOME_NAME\e[0m\e[31m_HOME\e[0m是否有配置"
fi
exit
fi
export HOME_PATH="/"$HOME_PATH
#进行多次字符串替换以使得Windows的环境变量可以在shell中使用
export HOME_PATH=${HOME_PATH/:/} #把Windows盘符的冒号去掉
export HOME_PATH=${HOME_PATH//\\//} #把Windows路径的反斜杠全部替换成斜杠
export HOME_PATH=${HOME_PATH/\/\///} #把 // 替换成 /,这个主要是我们在盘符前加上了斜杠,如果是Linux环境的话,就会多一个斜杠
#本函数正常跑完只能有一个echo,否则会导致下面接受返回值时出问题
echo $HOME_PATH
}
function run(){
pn=$# #最后一个参数表示一些提示是否隐藏
hide=$(eval echo '$'${pn}) #最后一个参数表示一些提示是否隐藏
if [ "$hide" != "hide" ]; then
echo -e "开始运行...\n\e[36m==========================================================\e[0m\n"
else
pn=$(expr $pn - 1)
#echo $pn
fi
cmd=$1
params=$2
i=3
while (( $i<=$pn ))
do
p=$(eval echo '$'${i})
params=$params" "$p
i=$(expr $i + 1)
done
"$cmd" $params
echo ""
if [ "$hide" != "hide" ]; then
echo -e "\n\e[36m==========================================================\e[0m\n运行结束"
fi
}
function compile(){ #传入编译程序类型、编译会生成的文件名以及编译参数
del_file "$1"
pn=$# #最后一个参数表示一些提示是否隐藏
hide=$(eval echo '$'${pn}) #最后一个参数表示一些提示是否隐藏
if [ "$hide" != "hide" ]; then
echo "正在编译$2源文件..."
else
pn=$(expr $pn - 1)
fi
cmd=$3
params=$4
i=5
while (( $i<=$pn ))
do
p=$(eval echo '$'${i})
params=$params" "$p
i=$(expr $i + 1)
done
#echo $cmd
#echo $params
"$cmd" $params
if [ -f "$1" ]; then
if [ "$hide" != "hide" ]; then
echo "编译完成"
fi
else
if [ "$hide" != "hide" ]; then
echo -e "\e[31m编译失败,请自行查找原因\e[0m"
fi
return 1;
fi
return 0;
}
function proc_exec_name(){
if [ $OS_TYPE == "Linux" -o $OS_TYPE == "Darwin" ]; then
echo ${1/.exe/}
else
echo $1
fi
}
if [ $# -eq 0 ]; then
echo -e "\e[31m错误!请输入参数\e[0m"
exit
fi
if [ "$2" == ".asm" ]; then
export des_file="./$1.bin"
export NASM=$(check_home_path "NASM" $3)
export NASM=$NASM"/nasm.exe"
export NASM=$(proc_exec_name "$NASM")
compile $des_file "ASM" "$NASM" $1$2 -l $1.lst -o $1.bin $3 #nasm src.asm -l src.lst -o src.bin
ret=$?
#echo $ret
elif [ "$2" == ".c" ]; then
export des_file="./$1.exe"
export des_file=$(proc_exec_name "$des_file")
export MINGW=$(check_home_path "MINGW" $3)
export C=$MINGW"/bin/gcc.exe"
export C=$(proc_exec_name "$C")
compile $des_file "C" "$C" -o $1 $1$2 $3 #gcc -o src src.c
ret=$?
if [ $ret -eq 0 ]; then
run "./$1" $3
fi
elif [ "$2" = ".cpp" -o "$2" == ".cc" ]; then
export des_file="./$1.exe"
export des_file=$(proc_exec_name "$des_file")
export MINGW=$(check_home_path "MINGW" $3)
export CC=$MINGW"/bin/g++.exe"
export CC=$(proc_exec_name "$CC")
compile $des_file "C++" "$CC" -o $1 $1$2 $3 #g++ -o src src.cpp
ret=$?
if [ $ret -eq 0 ]; then
run "./$1" $3
fi
elif [ "$2" == ".java" ]; then
export des_file="./$1.class"
export JAVA_HOME=$(check_home_path "JAVA" $3)
export JAVAC=$JAVA_HOME"/bin/javac.exe"
export JAVAC=$(proc_exec_name "$JAVAC")
export JAVA=$JAVA_HOME"/bin/java.exe"
export JAVA=$(proc_exec_name "$JAVA")
compile $des_file "JAVA" "$JAVAC" $1$2 $3 #javac Main.java
ret=$?
if [ $ret -eq 0 ]; then
run "$JAVA" $1 $3 #java Main
fi
elif [ "$2" == ".py" ]; then
export PYTHON=$(check_home_path "PYTHON" $3)
export PY=$PYTHON_HOME"/python.exe"
export PY=$(proc_exec_name "$PY")
run "$PY" $1$2 $3
else
echo -e "\e[33m暂不支持此类源文件($2),可自行添加\e[0m"
fi
npp中配置的cmd命令:
cmd /k pushd "$(CURRENT_DIRECTORY)" && bash.exe run.sh "$(NAME_PART)" "$(EXT_PART)" & PAUSE & EXIT
cmd /k pushd "$(CURRENT_DIRECTORY)" && bash.exe run.sh "$(NAME_PART)" "$(EXT_PART)" hide & PAUSE & EXIT #指定hide参数就可以隐藏脚本执行过程中的一些提示性语句
两条命令设置两个快捷键,一个是直接跑,另一个是前一个跑出问题可以看看是什么问题。
核心其实就是能够进入到当前打开文件的路径下,然后使用shell终端去启动脚本,传入文件名和扩展名,这里我用了npp的宏简单地打开了当前路径,然后获取到了文件名和扩展名参数,如果有什么编辑器也可以传入这样的参数的话应该也是通用的。
本脚本中涉及到的系统环境变量包括:
MINGW_HOME
JAVA_HOME
NASM_HOME
PYTHON_HOME
本意是想做一个可以跨平台使用的shell脚本,但在不同的系统下,这些环境变量不一定对得上,特别是Linux下用包管理器直接安装的nasm、gcc等应该是直接在/usr/bin目录下的,倒是不需要像脚本里面这么配置,所以脚本还有待修改。
标签:脚本,格式,echo,源文件,编译,export,HOME,PATH From: https://www.cnblogs.com/thankvincisdaily/p/17042718.html