How to create bash alias to backup of a file before editing in a text editor

centos
shell
bash
centos7

#1

Hi,

Say I want to edit the file /var/www/html/router.php to fix something. I want to backup /var/www/html/router.php to /backup/ directory as router-mm-dd-yyyy-hh-mm.php. I do this manually:

cd /var/www/html/
cp router.php /backup/router-$(date +"%m-%d-%Y-%H-%M").php
vi router.php

Now if something goes bad I copy /backup/router-$(date +"%m-%d-%Y-%H-%M").php back to /var/www/html/. Can I create bash shell alias like editfile run above commands. How will it accept filename? BTW this is on centos 7 server.


#2

I did some research and it says function is best. Bash function better than aliases? Is it true?


#3

Yup. Something as follows:

#!/bin/bash
function fileedit(){
	local d="/backup"	# backup dir 	
	local e="vi" 		# editor name such as vi/joe/emacs
	local n="$(date +'%m-%d-%Y-%H-%M')"	# date format
	local lf=""		# local file name
	local df=""		# dest file name
	local f="$1"		# get input

	# fail safe stuff

	# Is input given?
	[ "$f" == "" ] && { echo "Usage: $0 filename"; exit 2; }

	# Does file exits?
	[  ! -f "$f" ] && { echo "$f not found."; exit 1; }

	# make dest backu dir
	if [ ! -d "$d" ] 
	then
		mkdir -p "$d" 
		[ $? -ne 0 ] && { echo "Failed to create $d directory"; exit 3; }
	fi
	
	lf="${f##*/}"		# get just a filename from path
	df="${lf/./-$n.}"	# add date 
	[ "$lf" == "$df" ] && df="$lf-$n"	# failsafe 
	echo "Copying file..."
	cp -v "$f" "${d}/$df"
	echo "Editing file..."
	$e "$f"
	
}	

fileedit "$1"

As you can see code is complex and it has many disadvantages. I suggest you learn about git (or any other version control). Use git to manage file versions. It will be a good thingy in a long run too.

  1. GIT - Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
  2. Gitlab - Free public or private (paid option also available) git repos for your project
  3. Github - Free or paid private repos for your project
  4. Version control

#4

A bit ‘excessive’ but you can run a local git server that will give you a lot more than ‘a backup copy’.

My local small NAS (Synology) has one built in.


#5

Let me second and third the people recommending revision control. For many years, I used RCS, with an alias “rvi” that did something like ‘co -l $; vi $; ci -u $*’. Obviously I didn’t want to check in every file I edited, so it was something easy to remember, and which I drilled into coworker’s heads to use whenever they made any system-level changes.

Later, I used svn to centralize them on one server, and in recent years I’ve liked mercurial a lot (probably because it feels a lot like RCS). It doesn’t really matter which you choose, but it gives you very easy ways to diff changes without seeking out particular files, as well as rollback changes. Add a commit message that reminds you of why you made the change, too. I made it a policy that editing any system file without proper version control was a “track down who did it and shame them in front of the team” offense.

If you do just go with a timestamped backup file, at least put the date in correct order so ‘ls’ will sort by time. I use %F, which gives you YYYY-mm-dd, available in date, strftime(3), stat, and other places.


#6

Here a script I use to save local copy of files before editing. It allows to go “sudo” and edit configuration files without risking to loose track of modifications.
Hope it will solve your issue

    #!/bin/bash
    #  bkedit - Backup first then edit file. Go sudo if needed.
    #  works with  any editor (vi, nano, leafpad, openoffice, etc.)
    #  leave trace in .modified_files.lst of every filename edited
    #  for developer sake
    #  --
    #  Copyright 2015 Vittorio Beggi  <visnotjl[at]prontosoccorsopc.biz>
    #  
    #  This program is free software; you can redistribute it and/or modify
    #  it under the terms of the GNU General Public License as published by
    #  the Free Software Foundation; either version 2 of the License, or
    #  (at your option) any later version.
    #  
    #  This program is distributed in the hope that it will be useful,
    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    #  GNU General Public License for more details.
    #  
    #  You should have received a copy of the GNU General Public License
    #  along with this program; if not, write to the Free Software
    #  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
    #  MA 02110-1301, USA.
    #  --
    #  
    expected_args=2
    e_badargs=65
    e_wrongitem=42

    #-- Error messages and warnings
    msg1="File not found"
    msg2="The file owner is "
    msg3="Confirm you want to Edit anyway "

    if [ $# -ne $expected_args ]
    then
      echo "Usage: bkedit {editor (ex.: nano)} {filename}"
      exit $e_badargs
    fi

    #-- Consolidate input Arguments
    Infile="$2"
    Edit="$1"

    #- Check if  working interactively or through a socket
    fd=0   # stdin
    if [[ -t "$fd" || -p /dev/stdin ]] 
    then
      Xterm="T"
    else
      Xterm="F"
    fi

    #-- Check if file exists otherwise exit
    if ! [ -f "${Infile}" ]
     then
      if [ "T" == "${Xterm}" ]
      then
      	echo "${msg1}:[" ${Infile} "]"
      else
    	zenity --error --text="${msg1}:[ ${Infile} ]"
      fi
      exit $e_wrongitem
    fi
    #-- Make time stamp 
    Tstamp=$(date +%Y%m%d_%k%M%S | sed 's/ /0/g')

    Ourdir=$(dirname "$Infile")

    #-- See if first time modify
    Extension=`ls "${Infile}"* |wc -l`
    echo x$Extension
    if [ "x${Extension}" == "x1" ]
    then
    	Extension="original"
    else
    	Extension="${Tstamp}"
    fi

    #-- Look for credentials
    F_owner=$(ls -ld "${Infile}" | awk '{print $3}')
    Cur_user=$(whoami)


    #-- say DONT need sudo by default
    Weneedsudo="F"

    #-- see if need sudo turned on
    if [ "x${F_owner}" != "x${Cur_user}" ]
    then
    Weneedsudo="T"
    if [ "x${F_owner}" != "xroot" ]
    then
    	if [ "T" == "${Xterm}" ]
    	then
    		echo "${msg2} ${F_owner} ...  "
    		echo -n "${msg3}[y/N] "
    		read answer
    		if ! $(echo "$answer" | grep -iq "^y")
    		then
      		   exit $e_wrongitem
    		fi
    	else
    		if ! $(zenity --question --text "${msg2} ${F_owner} ...\n${msg3}" ) 
    		then
    		   exit $e_wrongitem
    		fi	
    	fi
    fi
    fi

    if ! [ -w "$Ourdir" ]	
    then
       Weneedsudo="T"
    fi

    if ! [ -w "$Infile" ]
    then
       Weneedsudo="T"
    fi

    #-- prepare a temporary area for all that stuff
    #-
    Workdir=$(echo "/tmp/${Cur_user}" | sed 's/ /_/g')
    mkdir -p "${Workdir}"

    if [ "${Weneedsudo}" == "T" ]
    then
    {
    #-- build a temporary script in /tmp, with copy and Edit embedded 

    echo "#!/bin/bash" > ${Workdir}/${Tstamp}.sh
    echo "cp \"${Infile}\"  \"${Infile}_${Extension}\" && ${Edit} \"${Infile}\" " >> ${Workdir}/${Tstamp}.sh
    echo 'echo $(readlink -f '"${Infile})"' | tee -a '"${Workdir}/${Tstamp}.lst"' > /dev/null' >> ${Workdir}/${Tstamp}.sh
    echo 'chmod 766 '"${Workdir}/${Tstamp}.lst" ' ' >> ${Workdir}/${Tstamp}.sh
    echo "exit 0" >> ${Workdir}/${Tstamp}.sh

    #-- Then go sudo  and launch temporary script
    	if [ "T" == "${Xterm}" ]
    	then
    		sudo sh ${Workdir}/${Tstamp}.sh
    	else
    		gksu sh ${Workdir}/${Tstamp}.sh
    	fi

     #--  avoid leaving waste in temp
     rm ${Workdir}/${Tstamp}.sh
     }
    else
     #-- "we don't need sudo"
     cp "${Infile}" "${Infile}_${Extension}" &&  ${Edit} "${Infile}"
     echo $(readlink -f ${Infile}) | tee -a ${Workdir}/${Tstamp}.lst > /dev/null
    fi
    #
    #-- record the name of the modified file in ".modified.lst" to help keep track
    #-- of each variation made to the system
    #
    if ! [ -f ".modified_files.lst" ]
      then
    touch .modified_files.lst
    fi
    #
    cat ${Workdir}/${Tstamp}.lst | tee -a ~/.modified_files.lst > /dev/null
    sort -u -o ~/.modified_files.lst ~/.modified_files.lst

    #-- avoid leaving waste in temp
    rm ${Workdir}/${Tstamp}.lst
      
    exit 0



#7

A post was split to a new topic: How to get alert when users access on particular file on Linux