一种用mv替代rm的方法
专栏:ExASIC Jan. 14, 2026, 6:17 p.m. 17 阅读
本文介绍了一种用mv替代rm的方法。

本文介绍了一种用mv替代rm的方法。在用户HOME目录下建一个回收站~/.Trash,下面的脚本会判断是重要文件还是不重要文件,采用不同的策略来挪动或直接删除文件。

实现方法见脚本中的注释。特别提醒:本脚本可能存在bug,使用之前请详细测试。

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"regexp"
	"strings"
	"time"
)

const (
	Ver     = "2.0"
	LastUpd = "Jan. 14, 2026"
	Author  = "Chenf"
)

var (
	MyFileList   []string
	MyIgnoreList []string
	NotGotoTrash = 0
	HelpFlag     = 0
)

func main() {
	// get hostname
	trashroot := "/home"

	// get current login user name
	currentUser, err := user.Current()
	if err != nil {
		fmt.Println("Error getting current user:", err)
		os.Exit(1)
	}
	username := currentUser.Username

	// mkdir trash dir if not exists
	trashpath := fmt.Sprintf("%s/%s/.Trash", trashroot, username)
	if !pathExists(trashpath) {
		os.MkdirAll(trashpath, 0755)
	}

	dateTimeDir := time.Now().Format("20060102150405")

	// handle options
	args := os.Args[1:]
	for _, arg := range args {
		switch {
		case arg == "-h" || arg == "-help" || arg == "--help":
			printHelp()
			os.Exit(0)

		case arg == "--version":
			fmt.Println("rm2mv v" + Ver)
			os.Exit(0)

		case arg == "--force":
			runCommand("/bin/rm", "-rf", arg)

		case strings.Contains(arg, "/.Trash/"):
			runCommand("chmod", "777", "-R", arg)
			runCommand("/bin/rm", "-rf", arg)

		case arg == "--status":
			if !pathExists(trashpath) {
				os.Exit(0)
			}
			runCommand("du", "-sh", trashpath)
			os.Exit(0)

		case arg == "--clean":
			cleanTrash(trashpath, dateTimeDir)
			os.Exit(0)

		case !strings.HasPrefix(arg, "-"):
			// protect /xxx and /home/xxx
			if isDangerousPath(arg) {
				fmt.Println("[Warning] deleting dangerous files: " + arg)
				os.Exit(0)
			} else {
				if pathExists(arg) {
					MyFileList = append(MyFileList, arg)
				} else if isSymlink(arg) { // invalid symlink
					MyFileList = append(MyFileList, arg)
				} else { // ignore non-exists file
					MyIgnoreList = append(MyIgnoreList, arg)
				}
			}

		default:
			MyIgnoreList = append(MyIgnoreList, arg)
		}
	}

	// check and clean trash
	trashtimestamp := trashpath + "/clean.timestamp"
	if !pathExists(trashtimestamp) {
		runCommand("rm", "--clean")
	} else {
		content, err := ioutil.ReadFile(trashtimestamp)
		if err == nil && len(content) >= 8 {
			lastDatetime := string(content)
			if len(lastDatetime) >= 8 {
				y := lastDatetime[0:4]
				m := lastDatetime[4:6]
				d := lastDatetime[6:8]
				lastTime, err := time.Parse("20060102", y+m+d)
				if err == nil {
					if time.Since(lastTime).Hours() > 7*24 {
						runCommand("rm", "--clean")
					}
				}
			}
		}
	}

	// remove files
	if len(MyFileList) != 0 {
		target := fmt.Sprintf("%s/%s", trashpath, dateTimeDir)
		if !pathExists(target) {
			os.MkdirAll(target, 0755)
		}

		for _, f := range MyFileList {
			targetFile := target + "/" + filepath.Base(f)

			// avoid deleting one file twice
			if pathExists(targetFile) {
				runCommand("/bin/rm", "-rf", targetFile)
				moveFile(f, target)
			} else if isPipeFile(f) {
				// handle special file type (named pipe)
				os.Remove(f)
			} else if isSymlink(f) && !pathExists(f) {
				// delete invalid symlink
				runCommand("/bin/rm", "-rf", f)
			} else if shouldDeleteDirectly(f) {
				// delete file directly by blacklist
				runCommand("/bin/rm", "-rf", f)
			} else {
				// move to ~/.Trash
				if pathExists(targetFile) {
					runCommand("/bin/rm", "-rf", targetFile)
				}
				moveFile(f, target)
			}
		}
	}
}

//...脚本太长,见附件

附件:rm2mv.zip

感谢阅读,更多文章点击这里:【专栏:ExASIC】
最新20篇 开设专栏