Disclaimer:
These pages about different languages / apis / best practices were mostly jotted down quckily and rarely corrected afterwards.
The languages / apis / best practices may have changed over time (e.g. the facebook api being a prime example), so what was documented as a good way to do something at the time might be outdated when you read it (some pages here are over 15 years old).
Just as a reminder.

Installation of scripts and binaries, the scripts

A way to release code in an organized fashion

As always, your own your own if the script mess your files up, I just provide the info you are responsible for what you do with it

Read this description to see how the scripts are used.
Described in this document are the mapping file, installation script and example makefile.

You have two files, the script and a file that maps the script to their destination.
The format of the mapping file is:

 destinationserver TAB path to file from ~/ TAB destinationpath TAB flag if the file is a binary or not TAB additional text
 

The mapping file

A TAB separated text file.
 stats   theFiles/project1/calculateRevenue   /opt/calc/   binary   ERROR: This is a binary file, you need to install it with 'make'
 stats   theFiles/project1/stat_scripts/gen_stats.sh      /opt/statscripts/
 calc    theFiles/project23/something.sh                  /some/dir/
 

The source code

 #!/usr/bin/ksh
 ###################################################################
 #
 # More scripts and tips can be found at
 # http://www.edlin.org/
 #
 # This script is used to ftp a file from the local directory to
 # the proper directory on the production machine
 # It will also write date,userid,hostname,targetfile,sourcefile
 # into a logfile, as well as sent with email
 #
 # At the moment it works like this:
 #
 # 1. Go to the directory with the file you have changed
 # 2. Run this script with the the full path as command argument
 # 3. Done, unless you get error messages
 #
 # Sample session:
 # $ whoami
 # user12
 # $ cd ~/theFiles/project1/stat_scripts
 # $ install.ksh -m "fixed bugs" $PWD/gen_stats.sh
 # Installing:
 # calvin:/home/user12/theFiles/project1/stat_scripts/gen_stats.sh
 # at:
 # hobbes:/opt/statscripts/
 #
 # $Id: install.ksh,v 1.31 2000/05/12 11:29:43 someuser Exp $
 #
 ###################################################################
 
 _helpme()
 {
   echo "-------------------------------------------------------------------"
   echo "-h: this help"
   echo "-m: a comment why the file is installed, e.g. 
    \"fixed bugs \" or something similar"
   echo "Example:"
   echo "> install.ksh -m \"fixed the bugs\" $PWD/gen_stats.sh"
   exit 53
 }
 
 _ftp_file()
 {
   stty -echo
   read -r PASSWORD?"Enter password for user $2 : "
   stty echo
   print
 
   #$1 = server
   #$2 = userid
   #$3 = source
   #$4 = targetdirectory on server
 
   #extract filename
   filename="`expr "//$3" : '.*/\([^/]*\)'`"
 
   ftp -in $1 <<EOF
     user $2 $PASSWORD
     bin
     put $3 $4${filename}
     quit
 EOF
 }
 
 _print_info(){
   echo "****************** NOTE: *****************"
   echo $1
   echo "******************************************"
 }
 
 _die(){
   echo "ERROR: $*"
   exit 99
 }
 
 SEND_MAIL=1
 
 USAGE="usage: $0 [-v] [-m comment] file
$0 -h for help"
 
 ## Parse out arguments
 while getopts hbvm: arguments
 do
    case $arguments in
         v) VERBOSE=1;;
 	b) BINARYINSTALLATION=1;;
 	h) echo $USAGE; _helpme;;
 	m) MESSAGE=$OPTARG;;
    esac
 done
 
 shift $(($OPTIND - 1))
 USERID=`whoami`
 LOCAL_SOURCE=$*
 
 if [[ -z "$MESSAGE" ]]
 then
   echo ${USAGE};
   exit 33;
 fi
 
 # The script does not run properly on AIX (for binaries that is)
 if [[ ($HOSTNAME = "aixmachine") ]]
 then
   echo "Sorry, you cannot install from AIX
Logon to a HP-UX machine to do install"
   echo "please make sure that you have compiled on AIX though,
"
   echo "e.g. do a \"make\" right now and then logon to a HP-UX machine and do \"make install\""
   exit 34
 fi
 
 ## Cut away the users home directory from the source part
 SOURCE=`echo ${LOCAL_SOURCE} | awk ' { search="/home/[A-Za-z0-9]*/"; sub(search,"",$0); print $0}'`
 
 #$USER is set by the shell, hence presently it will be vpmadm
 LOOKUPTABLE=/home/${USER}/theFiles/tools/installation/install_lookuptable.txt
 LOGFILE=/home/${USER}/log/installed.txt
 
 #Make sure we have got the latest lookuptable and logfile
 #cvs up $LOOKUPTABLE
 #cvs up $LOGFILE
 
 #Find out target
 cat $LOOKUPTABLE | while read -r lookup_server lookup_source lookup_target binary information
 do
   
   if [[ ( $SOURCE = $lookup_source ) ]]  then
     TARGET=$lookup_target
     break
   else
     # For example the binaries always have the date when they were compiled
     #, e.g. calculateRevenue.030109
     if [[ $SOURCE = ${lookup_source}.[0-9][0-9][0-9][0-9][0-9][0-9] ]]  then
       TARGET=$lookup_target
       break
     fi
   fi
 done
 
 if [[ -z "$TARGET" ]]
 then
   _die " Could not find a target for
$SOURCE" \
        "
       It might be that the file has to be manually installed," \
        "
       please check install_manually.txt"
   exit 54;
 else
   if [[ (-z "$BINARYINSTALLATION") ]]
   then
     if [[ ( $binary = "binary" ) ]]  then
       _print_info "$information"
       exit
     fi
   fi
 fi
 
 ######################################################
 #map type of file to servername
 #shared is mapped to caxhhp01, the files have to be installed
 #manually on the other ones
 case $lookup_server in
 	"stats") lookup_server="hobbes"; lookup_user="prod87";;
 	"calc")	  lookup_server="fraggle"; lookup_user="prod99";;
 	"backup") lookup_server="muppet"; lookup_user="prod11";;
 	"shared") lookup_server="calvin"; lookup_user="prod87";;
 	*) lookup_user="$USERID";;
 esac
 ######################################################
 
 HOSTNAME=`hostname`
 
 echo "----------------------------------------------------------------------" \
      "
Logging user as ${USERID}" \
      "
Comment: $MESSAGE" \
      "
FTPing" \
      "
  $HOSTNAME:$LOCAL_SOURCE" \
      "
to" \
      "
  $lookup_server:$TARGET" \
      "
---------------------------------------------------------------------"
 
 _ftp_file $lookup_server $lookup_user $LOCAL_SOURCE $TARGET
 
 DATUM=`date +"%Y_%m_%d %H:%M"`
 
 # save info to logfile
 LOGDATA="$DATUM	${USERID}	$HOSTNAME	$LOCAL_SOURCE	$TARGET	$MESSAGE"
 echo $LOGDATA >> $LOGFILE
 
 #send a mail
 if [[ ( -n $SEND_MAIL ) ]]
 then
    SUBJECT="install.ksh: $SOURCE"
    echo "$DATUM
Installed by: ${USERID} @ $HOSTNAME

Source -> Target:
$HOSTNAME:$LOCAL_SOURCE -> 
$lookup_server:$TARGET

 \
    Comment: $MESSAGE
------------------------------------------------------------------------" \
    | mailx -s "${SUBJECT}" gareth@somedomainname.com dilbert@somedomainname.com
 fi
 
 echo "If the ftp-session did not generate any errors;"
 echo "please login to $lookup_server and make sure that the file has been"
 echo "transfered properly, and that the execute-bit is set on the file."
 
 # Print any optional information that are relevant when installing this file
 
 if [[ (-z "$BINARYINSTALLATION") ]]
 then
   if [[ (-n $information) ]]
   then
     _print_info "$information"
   fi
 else
   echo "Installation completed."
 fi
 

The Makefile

Here is the snippet from the binaries Makefile that is relevant for the installation procedure.
 
 # ....
 
 EXT   = `date +%y%m%d`
 
 #Executable for production
 BINARY_LIVE = "$(BINARY_FILE).$(EXT)"
 PROD_USER=prod87
 PROD_MACHINE=hobbes
 DOSYMLINK = rexec $(PROD_MACHINE) -l $(PROD_USER) \
             "cd /opt/calc/;rm $(BINARY_FILE);ln -s $(BINARY_LIVE) $(BINARY_FILE);chmod 755 $(BINARY_LIVE)"
 
 INSTALLBIN = install.ksh -b -m '$(MSG)' $(PWD)/$(BINARY_LIVE)
 
 install:	
 	@if [ -z "$(MSG)" ]; then echo "usage: \"make install MSG=\"\"
To get more information: \"make help\"
"; false; fi; 
 	@$(CHMOD) 0755 $(BINARY_FILE)
 	@$(CP) $(BINARY_FILE) $(BINARY_LIVE)
 	$(INSTALLBIN)
 	@echo "Logging in to create symlink from $(BINARY_FILE) to $(BINARY_LIVE)
($(PROD_USER)@$(PROD_MACHINE))"
 	@$(DOSYMLINK)
 	@echo "Please login to $(PROD_MACHINE) and test the binary by calling $(BINARY_FILE) without any arguments"
 
 
 # ....
 

More programming related pages

Workflow: Release process
Workflow: Bug tracking
Teambox (Redbooth) - Mantis connector
Design Patterns
Git & Github
Go / Golang
CVS
CVS backup script
Distribution process
Installation script
Java Server Faces
Facelets
jibx
jBoss
jBpm
Perl tips
Perl links
PostgreSQL
Python / py2app
Shell scripts
Xslt
Node.js
Facebook / Opengraph
PHP developer notes
Redbooth API through php
Website optimization
jqTableKit demo
Javascript / html / css links