mkredir

a unix shell command-line program

Make a redirect page. See also mvredir.

A redirect page allows a browser to get to a page at a new location even though the browser was told to get the page at the obsolete location. It is always a good idea to leave behind a redirect page at the old location when you move a page, so that links to the old location still work. This approach is preferable to a unix symbolic link (symlink) or “hard link” because those approaches proliferate different locations for the same page. Also, if the page moves to a different position in the hierarchy, relative links will not work when the page is accessed from a different path.

Examples:

1 Z% mkredir newname.html oldname.html
2 Z% mkredir newdir/name.html .
3 Z% mkredir $(ls newdir/*.html | sed 's,^,../,') olddir 

1. oldname.html will redirect to newname.html

2. name.html will redirect to newdir/name.html

3. olddir/name1.html will redirect to ../newdir/name1.html, etc.

The usage summary is this:

Usage:
  mkredir [ -f ] [ -b ] path1 path2
  mkredir [ -f ] [ -b ] path ... directory

The -f option forces replacement of the target if it already exists.
The -b option causes the redirect file(s) to have a <body> that says:
     One moment while we redirect you to the page.
The source path arguments must all be relative to the destination directory, and mkredir does not check if those paths exist.

This works only for redirecting html files. If you want to redirect a directory, you have to use the Apache RedirectPermanent directive (see the Apache Alias module (mod_alias) documentation). For example, I redirect from http://Yost.com/yostupload to its real location in a .htaccess file, like this:

RedirectPermanent /yostupload http://Yost.com/computers/yostupload

The presence of a <body> in the redirect page makes the redirect take longer and is necessary only for extremely old browsers.

Here’s the mkredir program:

#!/bin/zsh

# See notice of copyright and license at end.

commandName=${0##*/}

usage() {
if [[ $1 != '' ]] ; then echo 1>&2 "\n$1" ; fi
echo 1>&2 "
Usage: $commandName [ -f ] [ -b ] file1 file2
or     $commandName [ -f ] [ -b ] file ... directory

The -f option forces replacement of the target if it already exists.
The -b option causes the redirect file(s) to have a <body> that says:
     One moment while we redirect you to the page
The source path arguments must all be relative to the destination directory, 
and mkredir does not check if those paths exist.

"
    exit 2
}

argForce=()
argBody=()
zparseopts -D -K - -help=argHelp f=argForce b=argBody

case "$1" in
-*)
  usage "Unknown option: $1"
  ;;
esac

case $# in
0|1|)
  usage
  ;;
2)
  ;;
*)
  if [[ ! -d "$*[-1]" ]] ; then
    usage "$*[-1]: not a directory"
  fi
  ;;
esac

if [[ $#argHelp != 0 ]] ; then
  usage
fi

#-------------------------------------------------------------------------------

entitize() {
  echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
        <html><head><title></title></head><body><a href="'"$1"'">x</a></body></html>' \
  | tidy -q 2> /dev/null \
  | sed -n '
      s,">x.*,,
      s,.*href=",,p
  '
  return 0
}

filter() {
  target=$(entitize "$1")
  sedArgs='s,^    ,,'
  if [[ $#argBody != 0 ]] ; then
    sedArgs="$sedArgs
      /<!-- /d
      / -->/d
    "
  fi
  targetEscaped=$(echo "$target" | sed 's,|,\\|,')
  sedArgs="$sedArgs
    s|__PLACEHOLDER__|$targetEscaped|
  "
  sed "$sedArgs"
  return 0
}

makeRedirectPage() {
  redirect="$1"
  destination="$2"
  if [[ -e "$destination" ]] ; then
    if [[ $#argForce == 0 ]] ; then
      echo 1>&2 "$commandName: ${destination}: File exists"
      return 2
    else
      rm -f "$destination"
    fi
  fi
  echo '<?xml version="1.0" encoding="iso-8859-1"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
            "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
      <meta http-equiv="Refresh" content="0; URL=__PLACEHOLDER__" />
      <meta http-equiv="Expires" content="Tue, 1 Jan 1997 0:0:0 GMT" />
      <title>Redirect</title>
    </head>
    
    <!-- 
    <body bgcolor="#ffffff">
    
    <h3 align="center">
      <br />One moment while we redirect you to 
      <a href="__PLACEHOLDER__">the page</a>.</h3>
    
    </body>
     -->
    
    </html>
  ' \
  | filter "$redirect" \
  > "$destination"
  return $?
}


TRAPINT() {
  echo 1>&2 "$commandName aborting: interrupted at file $file"
  exit 2
}

if [[ $# == 2 && ! -d "$2" ]] ; then
  if ! makeRedirectPage "$1" "$2" ; then
    exit 2
  fi
else
  args=("$@")
  dir="$args[$#]"
  args[-1]=()
  for file in "${args[@]}"
  do
    if ! makeRedirectPage "$file" "$dir/${file##*/}" ; then
      exit 2
    fi
  done
fi

# Copyright 2005 Dave Yost <Dave@Yost.com>
# All rights reserved.
# This version is
#   mkredir 1.0 2005-08-03
# which at time of this publication can be found at:
#   http://Yost.com/computers/mkredir
# Redistribution and use in the form of source code or derivative data built 
# from the source code, with or without modification, are permitted provided 
# that the following conditions are met:
# 1. THE USER AGREES THAT THERE IS NO WARRANTY.
# 2. If and only if appropriate, the above phrase "This version is" must be 
#    followed by the phrase "a modified form of" or "extracted from" or 
#    "extracted and modified from".
# 3. Redistributions of source code must retain this notice intact.
# 4. Redistributions in the form of derivative data built from the source 
#    code must reproduce this notice intact in the documentation and/or other 
#    materials provided with the distribution, and each file in the derivative 
#    data must reproduce any Yost.com URI included in the original distribution.
# 5. Neither the name of Dave Yost nor the names of its contributors may be 
#    used to endorse or promote products derived from this software without 
#    specific prior written permission.
# 6. Written permission by the author is required for redistribution as part 
#    of a commercial product.
# This notice comprises all text from "Copyright" above through the end of 
# this sentence.

http://Yost.com/computers/mkredir/index.html - this page
2005-08-03 Created