Script Writing background
Whether it is a production environment, a test environment, or a development environment, it is often necessary to use the RM command to delete & batch files in some "important" directories. According to the philosophy of Linux "Small is Beauty" (a program only do one thing) + "users know what they do" (the user knows what they want, also understand what they are doing, and will be responsible for their actions), then the user in the implementation of RM, it must be aware of the consequences of their operations, so " It's really important to think twice. But for some, it could really be catastrophic, shaking hands, cheap hands and any wrong actions (more spaces before the path delimiter "/", incorrect use of *, wrong path (current path, relative path, wrong action path), error script (someone dares to debug a script that has not been tested in the production environment), Bad bulk operations, bad security policies) can cause data loss, which is very deadly in production environments, especially in production environments where backup is missing from a hot standby.
so it is necessary to make the user regret it once by scripting or other means. This article uses the Bash Shell script approach to this issue, and other solutions can be found at the end of the "reference".
Script Writing Ideas
Similar to the idea of the Recycle Bin, the Recycle Bin has this feature: 1. not really deleted; 2. The same name can be, 3. Remember the source path of the file, as a script should do so
Scripts should be used basically like RM.
Script uses
650) this.width=650; "title=" image "style=" border-top:0px;border-right:0px;border-bottom:0px;border-left:0px; " Border= "0" alt= "image" Src= "Http://s3.51cto.com/wyfs02/M01/9A/5B/wKioL1lUrtKTPP6FAACRg5B7V5A266.png" height= "600" />
About the parameters of RM
The use of ignored policies within the script, regardless of which parameter of RM is used, will be performed in MV operation, where improvements are desirable .
650) this.width=650; "title=" image "style=" border-top:0px;border-right:0px;border-bottom:0px;border-left:0px; " Border= "0" alt= "image" Src= "Http://s3.51cto.com/wyfs02/M02/9A/5B/wKioL1lUrtvAN7HQAABd-5vLjQ4306.png" height= "366" />
Script Content
The script contents can be found in GitHub .
#!/usr/bin/env bash# a command or alias to replace ' RM ' with a safe and easy to use, safe remove files or Directories# see also:# safe-rm - wrapper around the rm command to prevent accidental deletions - https://github.com/kaelzhang/shell-safe-rm# trash-cli - command line interface to freedesktop.org trash - https://pypi.python.org/pypi/trash-cli/# debug optiondebug=false # debug= trueif ${debug} ; then old_ps4= $PS 4# export ps4= ' +${bash_source}:${lineno}:${funcname[0]}: ' export ps4= ' +${LINENO}: ${FUNCNAME[0]}: ' # if there is only one bash script, Do not display ${bash_source} _xtrace_functions=$ (Set +o | grep xtrace) set -o xtracefi# set an empty function using for location this line quickly in pycharm editor on purpose.function _empty () { return; }# public header# =================================================== ==========================================================================# resolve links - $0 may be a symbolic link# learn from apache-tomcat-6.x.xx/bin/ Catalina.shprg= "$" while [ -h "$PRG" ]; do ls= ' ls -ld "$PRG" ' link= ' expr ' $ls : '. *-> \ (. *\) $ ' if expr ' $link ' : '/.* ' > /dev/null; then prg= "$link" else prg= ' Dirname "$PRG" '/"$link" fidone# get standard environment variablesprgdir= " dirname "$PRG" ' # echo color function, smarter, learn from lnmp.org lnmp install.shfunction echo_r () { # color red: Error, failed [ $# -ne 1 ] && return 1 echo -e "\033[31m$1\033[0m"}function echo_g () { # Color green: Success [ $# -ne 1 ] & & return 1 echo -e "\033[32m$1\033[0m"}function echo_y () { # color yellow: warning [ $# -ne 1 ] && return 1 echo -e "\033[33m$1\033[ 0m "}function echo_b&nbSP; () { # color blue: debug level 1 [ $# -ne 1 ] && return 1 echo -e "\ 033[34m$1\033[0m "}function echo_p () { # color purple,magenta: Debug level 2 [ $# -ne 1 ] && return 1 echo -e "\033[35m$1\033[0m"}function echo_c () { # color cyan: friendly prompt, level 1 [ $# -ne 1 ] && return 1 echo -e "\ 033[36m$1\033[0m "}# end echo color function, smarter#workdir=" ' realpath ${ Workdir} ' "Workdir=" ' Readlink -f ${prgdir} ' "# end public header# ================ =============================================================================================================real_rm= '/bin/rm ' trash_dir= " $HOME/.trash " # if do not use " $HOME " or " ~ " to resolve permission problem, should use "chmod o+t $trash _dir" .chmod --help: Each MODE is of the form ' [ugoa]* ([-+=] ([rwxxst]*|[ Ugo]) + '. log_dir= "$trash _dir" log_file= "$log _dir/operation.log" trash_save_days=3function real_rm () { if [[ ! -f ${real_rm} ]]; then echo ' safe-rm cannot find the real ' rm ' binary ' exit 1 fi save_days=${trash_save_days:-10} test $ (Find -l /tmp/.delete/ -type d ! -name "^." -a ! -wholename "/tmp/.delete/" -mtime +${save_days} -exec echo ' {} ' \; | wc -l ) -gt 0 found_old_files=$? if [[ ${found_old_files} -eq 0 ]]; then echo_b "Old files found, cleaning" #find -l ${trash_dir}/ -maxdepth 1 -type d ! -name "^." -mtime +${save_days} -exec rm -rf ' {} ' \; find -l ${trash_dir}/ -maxdepth 1 -type d ! - wholename "$trash _dir/" ! -name "^." -mtime +${save_days} -exec rm -rf ' {} ' \; echo_g "Old files cleaned succeSsfully " else echo_g " old Files in standby state, passed " fi}function safe_rm () { if [[ "$1x" = ' x ' ]]; then ${real_rm} --help exit 1 fi if [[ ! -d ${trash_dir} ]]; then mkdir -p ${trash_dir} fi # date +%Y%m%d%H%M%S.%N | shasum | awk ' {print $1} ' | cat - -a uniq_trash_dir= ' $trash _dir/$ (date +%Y%m% d%h%m%s.%n | shasum | awk ' {print $1} ') " mkdir -p ${uniq_trash_dir} &nbSp; if [[ $# -eq 1 ]];then if [[ -f $1 ]] | | [[ -d $1 ]]; then # ignore rm -f|-r|-rf|-fr, etc mv $1 ${uniq_trash_dir} retval=$? fi else # alternative impl of ' Rm file ... ' parameter_ Array= "[email protected]" # ifs= ' ' $ ' \ t ' $ ' \ n ', ifs=$ ' \t\n ', if ifs is unset, or its value is exactly <space><tab><newline> old_ifs=$Ifs ifs= ' ' $ ' \ t ' $ ' \ n ' for parameter in ${parameter_array}; do if [[ -f ${parameter} ]] | | &NBSP;[[&NBSP;-D&NBSP;${PARAMETER}&NBSP;]];&NBSP;THEN&NBSP;&NBSP;#&NBSP;IGNORE&NBSP;RM&NBSP;-F|-R|-RF|-FR, etc mv ${parameter} ${uniq_trash_dir} fi done retval=$? ifs= "$old _ifs" fi log_operation [email protected] exit ${retval}}function log_operation () { tee -a ${log_file}<<-eof # debug purpose or notify mode{ "Date_human": "$ (date + '%y-%m-%d %h:%m:%s.%n ')", "date ": " $ (date) ", " user ": " $USER ", " Ssh_client ": " $ Ssh_client ", " ssh_connection ": " $SSH _connection ", " Ssh_tty " : "$SSH _tty", "Trash_dir": "${uniq_trash_dir}" "Log_ File ":" ${log_file} ", " pwd ": " $PWD ", " Operation ": " [email protected] ", " parameter ": " [email protected] "}eof}function usage () { cat - << eof${workdir}/' basename $0 ' help show help message${workdir}/' basename $0 ' clean &nbsP; clean old deleted fileseof}function main () { lock_ Filename= "Lock_$$_${random}" # lock_filename_full_path= "/var/lock/subsys/$lock _filename" lock_filename_full_path= "/var/lock/$lock _filename" if ( set -o noclobber; echo "$$" > "$lock _filename_full_path") 2> /dev/null;then trap ' rm -f ' $lock _filename _full_path "; exit $?" int term exit [ ! -x ${workdir}/ ' basename $0 ' ] && chmod +x ${workdir}/' basename $0 ' if [[ $# -lt 1 ]]; then ${workdir}/' basename $0 ' help exit 0 fi if [ -f $1 ]; then safe_rm [email protected] else parameter_array= "[email protected]" # ifs= ' ' $ ' \ t ' $ ' \ n ', ifs=$ ' \t\n ', if ifs is unset, or its value is exactly <space><tab><newline> old_ifs= $IFS ifs= ' ' $ ' \ t ' $ ' \ n ' for parameter in ${parameter_array}; do if [[ -f ${parameter} ]] | | &NBSP;[[&NBSP;-D&NBSP;${PARAMETER}&NBSP;]];&NBSP;THEN&NBSP;&NBSP;#&NBSP;IGNORE&NBSP;RM&NBSP;-F|-R|-RF|-FR, etc safe_rm [email protected] fi done ifs= "$old _ifs" fi case $1 In clean) real_rm ;; help|*) usage exit 1 ;; esac rm -f "$lock _filename_full_path" trap - int term EXIT else echo "failed to acquire lock: $lock _filename_full_path " echo "held by $ (cat ${lock_filename_fUll_path}) "fi}main [email protected]# debug optionif ${debug} ; then export ps4=${old_ps4} ${_xtrace_functions}fi
Can continue to do things
1. List the deleted files conveniently according to the operation Log
2. recover files more conveniently according to the operation Log
3. Handle the situation where the file does not exist
4. Increase in the situation of direct deletion
5. Issues with reserved permissions
6. Remove parameters such as-RF from operation and parameter in Log_file
Reference:
This kind of thing others have already done well, although the process of learning need to accumulate and experience, but life is short, sometimes need to stand on the shoulders of giants.
- the ways to prevent RM misoperation "
- the Change RM command to move to recycle bin "
- the trash-cli 0.17.1.14 "converts RM into a Python implementation that moves to the Recycle Bin
Tag:safe-rm,trash-cli,rm
--end--
This article is from "Communication, My Favorites" blog, please make sure to keep this source http://dgd2010.blog.51cto.com/1539422/1943170
Securely delete files in a Linux shell script production environment