用C++自己写一个rm命令替换系统rm,执行mv * /Users/xxx/.Transh(废纸篓)

rm xxx

mv xxx ~/.Trash

rm命令简单但伤害性极大,现在用C++自己写一个rm命令执行mv * /Users/xxx/.Transh(废纸篓),给自己一碗回头药。

1、源码:

#include <iostream>
#include <regex>
#include <string>
#include <ctime>
using namespace std;
#define BUF_SIZE 1024  
#define flag regex_constants::ECMAScript
bool exec(const char* cmd,bool blog){
	int retcode(system(cmd));
	if(retcode==0) return true;
	else{
		// cout<<cmd<<" return errcode: "<<retcode<<endl;
		return false;
	}
	if(false){
		/*
		FILE * p_file = NULL;  
		p_file = popen(cmd, "r");
		if (!p_file) {  
			fprintf(stderr, "sh error, check rm source code! ! !");  
			return false;
		}
		regex reg("No such file or directory",flag);
		char buf[BUF_SIZE];
		bool bReturn(false);
		char* res=fgets(buf, BUF_SIZE, p_file);
		// mac上不论popen()执行成功与否,此处调用fgets()会引发“[1]    21015 segmentation fault”错误
		cout<<res<<endl;
		while (res != NULL) {
			// https://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html
			bReturn=true;
			if(blog) 
				cout<<buf<<endl;
			if(regex_search(buf,reg)){
				return false;
			}
			res=fgets(buf, BUF_SIZE, p_file);
		}
		if(! bReturn) return false;
		pclose(p_file);
		return true;
		*/
	}
	
};
int main(int argc,char* argv[]){
    if(argc<=1){
        cout<<"please input a valid file!"<<endl;
		return 1;
    }
	int iCountSuc(-1),iCountFail(-1);
	string cmdsls[argc-1],cmdsmv[argc-1],errs[argc-1];
	char mv[BUF_SIZE],desti[BUF_SIZE],fail[BUF_SIZE];
	strcpy(mv,"mv ");
	strcpy(desti," /Users/haypin/.Trash");
	strcpy(fail," FAILED! ! !");
	char chard[3],charf[3],chari[3],charP[3];
	char charR[3],charr[3],charv[3],charW[3];
	strcpy(chard,"-d");
	strcpy(charf,"-f");
	strcpy(chari,"-i");
	strcpy(charP,"-P");
	strcpy(charR,"-R");
	strcpy(charr,"-r");
	strcpy(charv,"-v");
	strcpy(charW,"-W");
	regex regd(chard,flag);	// 去除,mv直接移动目录
	regex regf(charf,flag);	// 保留,与mv -f作用相同
	regex regi(chari,flag);	// 保留,与mv -i作用相似
	regex regP(charP,flag);	// 去除
	regex regR(charR,flag);	// 去除,mv直接移动目录
	regex regr(charr,flag);	// 去除,等价于-R
	regex regv(charv,flag);	// 保留,与mv -v作用相同
	regex regW(charW,flag);	// break,Attempt to undelete the named files
	regex reghyphen("--",flag);
	bool bhyphen(false);
	string mv_joint;
	mv_joint.append("mv ");
	for(int i(1);i<argc;i++){
		bhyphen=regex_search(argv[i],reghyphen);
		if(!bhyphen){	// --前的都是选项,--后的不是选项
			bool bd(regex_search(argv[i],regd));
			bool bP(regex_search(argv[i],regP));
			bool bR(regex_search(argv[i],regR));
			bool br(regex_search(argv[i],regr));
			bool bW(regex_search(argv[i],regW));
			if(bd || bP || bR || br) {
				cout<<"continue "<<argv[i]<<endl;
				continue;
			}
			if(bW) {
				cout<<"-W mean Attempt to undelete the named files, will break"<<endl;
				break;
			}
			bool bf(regex_search(argv[i],regf));
			bool bi(regex_search(argv[i],regi));
			bool bv(regex_search(argv[i],regv));
			if(bf) {
				mv_joint.append(charf);
				mv_joint.append(" ");
				continue;
			}
			if(bi) {
				mv_joint.append(chari);
				mv_joint.append(" ");
				continue;
			}
			if(bv) {
				mv_joint.append(charv);
				mv_joint.append(" ");
				continue;
			}
		}
		cmdsls[i-1].append("ls ");		// ls /Users/haypin/.Trash/argv[i],如果存在就mv argv[i] desti/argv[i]+08-10-14:23:11
		cmdsls[i-1].append(desti);
		cmdsls[i-1].append("/");
		cmdsls[i-1].append(argv[i]);

		cmdsmv[i-1].append(mv_joint);
		cmdsmv[i-1].append(argv[i]);
		cmdsmv[i-1].append(desti);
		if(exec(cmdsls[i-1].c_str(),false)){
			time_t now(time(0));
			tm *now_tm(localtime(&now));
			char buf[100];
			strcpy(buf,"/");
			cmdsmv[i-1].append(buf);
			cmdsmv[i-1].append(argv[i]);
			strcpy(buf,"\\ \\ ");
			cmdsmv[i-1].append(buf);
			sprintf(buf,"%d",now_tm->tm_mon);
			cmdsmv[i-1].append(buf);
			cmdsmv[i-1].append("-");
			sprintf(buf,"%d",now_tm->tm_mday);
			cmdsmv[i-1].append(buf);
			cmdsmv[i-1].append("-");
			sprintf(buf,"%d",now_tm->tm_hour);
			cmdsmv[i-1].append(buf);
			cmdsmv[i-1].append(":");
			sprintf(buf,"%d",now_tm->tm_min);
			cmdsmv[i-1].append(buf);
			cmdsmv[i-1].append(":");
			sprintf(buf,"%d",now_tm->tm_sec);
			cmdsmv[i-1].append(buf);
			cmdsmv[i-1].append(".");
			sprintf(buf,"%d",int(now));
			cmdsmv[i-1].append(buf);
		}
		cout<<cmdsmv[i-1]<<endl;
		if(exec(cmdsmv[i-1].c_str(),true)){
			iCountSuc +=1;
			continue;
		}
		iCountFail+=1;
		string err;
		err.append(mv);
		err.append(argv[i]);
		err.append(fail);
		errs[iCountFail]=err;
	}  
	if(iCountSuc>=0){
		for(string& imv:cmdsmv) cout<<imv<<" success1"<<endl;
	}
	if(iCountFail>=0){
		// for(string& irr:errs)cout<<irr<<endl;	// 发生错误时system(cmd)会打印标准错误的
	}
	string res;
	res.append("total ");
	char str[BUF_SIZE];
	sprintf(str, "%d", iCountSuc+1);
	res.append(str);
	res.append(" success2");
	if(iCountFail>=0 || iCountSuc<0){
		res.append(", ");
		sprintf(str, "%d", iCountFail+1);
		res.append(str);
		res.append(fail);
	}
	cout<<res<<endl;
	return 0;
}

 

2、CMakeLists.txt:

cmake_minimum_required(VERSION 3.21)
project(rrm)
set(CMAKE_CXX_STANDARD 11)
add_executable(rrm rrm.cpp)

2.5、再给个VScode的编译任务设置tasks.json:

{
	"version": "2.0.0",
	"tasks": [
		{
			"label":"cd",
			"type":"shell",
			"command":"cd",
			"args":[
				"${fileDirname}/build"
			],
			"problemMatcher":"$gcc",
		},
		{
			"label":"cmake ..",
			"type":"shell",
			"command":"cmake",
			"args":[
				// ".."
				"${fileDirname}",
			],
			
			"problemMatcher":"$gcc",
		},
		{
			"label":"cmake --build .",
			"type":"shell",
			"command":"cmake",
			"args":[
				"--build",
				// "."
				"${fileDirname}/build",
			],
			"dependsOrder":"sequence",
			"dependsOn":[
				"cd",		// VScode dependsOn依赖任务的cd <cwd>对后序任务无影响,每次任务的cwd都位于${workspaceFolder}
				"cmake .."
			],
			"problemMatcher":"$gcc",
		},
	]
}

注意到tasks.json每个任务的执行都是相互独立、不影响的,既便通过"dependsOn"设置依赖的任务列表并开启"dependsOrder"指定执行顺序。比如上面先执行"cd"任务将cwd切换到${fileDirname}/build,后执行"cmake .."命令,则"cmake .."命令的cwd并不相应地保持在${fileDirname}/build,每个任务执行的cwd都初始位于${workspaceFolder}。幸好cmake和cmake --build命令提供<cwd>选项可以直接指定工作目录,所以直接写绝对路径就可以。

这个CMakeLists.txt等价于:

mkdir build

cd build

cmake ..

camke --build .

编译出rrm可执行文件

3、查看$PATH

 haypin@MBP  ~  echo $PATH
/Users/haypin/.local/bin
:/Applications/CMake.app/Contents/bin
:/Users/haypin/Go1201/bin
:/Users/haypin/Go/bin
:/Users/haypin/miniconda3/condabin
:/Library/Frameworks/Python.framework/Versions/2.7/bin
:/usr/local/bin
:/usr/bin
:/bin
:/usr/sbin
:/sbin
:/Applications/VMware Fusion.app/Contents/Public
:/usr/local/go/bin
:/usr/local/share/dotnet
:/Library/Apple/usr/bin
:/Library/Frameworks/Mono.framework/Versions/Current/Commands
:/usr/local/mysql-8.0.21-macos10.15-x86_64/bin
 haypin@MBP  ~  which rm
/bin/rm

系统rm命令在/bin目录,那将自己写的rrm链接到$PATH比/bin更靠前的路径就可以被优先找到,我选择在/Users/haypin/.local/bin目录下链接自己写的rrm:

 haypin@MBP  ~  cd ~/.local/bin
 haypin@MBP  ~/.local/bin  ln /Users/haypin/cpp_cmake_js_java_python/rrm/build/rrm rm
 haypin@MBP  ~/.local/bin  ll rm
-rwxr-xr-x  1 haypin  staff    56K  8 10 10:29 rm

关闭当前终端后再打开一个:

 haypin@MBP  ~  which rm
/Users/haypin/.local/bin/rm

此时的rm命令就是最先找到的自己写的rrm了。

4、测试

 haypin@MBP  ~/cpp_cmake_js_java_python/rrm  touch robot
 haypin@MBP  ~/cpp_cmake_js_java_python/rrm  rm robot
mv robot /Users/haypin/.Trash success
total 1 success
 haypin@MBP  ~/cpp_cmake_js_java_python/rrm  cd ~/.Trash
 haypin@MBP  ~/.Trash  ll
total 0
-rw-r--r--  1 haypin  staff     0B  8 10 11:21 robot
 haypin@MBP  ~/.Trash 

5、尽情地rm吧,妈妈再也不怕我翻车了 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值