diff options
author | An-Cheng Huang <ancheng@vyatta.com> | 2007-11-12 13:06:02 -0800 |
---|---|---|
committer | An-Cheng Huang <ancheng@vyatta.com> | 2007-11-12 13:06:02 -0800 |
commit | b7fc9e0f6d6105ba2203f219743d4b269415e84b (patch) | |
tree | ef6586dfc62798c2b17487b443864699aca55f31 /examples/scripts.v2/ncp | |
download | vyatta-bash-b7fc9e0f6d6105ba2203f219743d4b269415e84b.tar.gz vyatta-bash-b7fc9e0f6d6105ba2203f219743d4b269415e84b.zip |
initial import from bash_3.1dfsg.orig.tar.gz
Diffstat (limited to 'examples/scripts.v2/ncp')
-rw-r--r-- | examples/scripts.v2/ncp | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/examples/scripts.v2/ncp b/examples/scripts.v2/ncp new file mode 100644 index 0000000..c91ba64 --- /dev/null +++ b/examples/scripts.v2/ncp @@ -0,0 +1,187 @@ +#! /bin/bash +# +# original from: +# @(#) ncp.ksh,nmv.ksh 1.1 94/07/23 +# 92/01/18 john h. dubois iii (john@armory.com) +# 92/01/31 added check for no args left after shifts +# 92/02/17 added help +# 92/02/25 remove path component from filename before tacking it onto dest. +# 92/03/15 exec mv or cp +# 93/07/13 Added -i +# 93/09/29 Made abort if file exists optional. +# 93/11/19 Exit before invoking mv if no files to move +# 94/01/03 Added o option +# 94/04/13 Added x option. +# Fixed appending of source filename, broken by earlier change. +# 94/07/23 Append only the filename part of the source path. +# +# conversion to bash v2 syntax done by Chet Ramey + +false() +{ + return 1 +} + +true() +{ + return 0 +} + +phelp() +{ +echo "$name: do a $cmd with extra checking and options. +$Usage +$name is used as a front end for $cmd to get the [icfo] options, and so +that a trailing / will force the last component of the path to be +interpreted as a directory, so that $name foo bar/ will fail if bar is +not an existing directory, instead of changing the name of foo to bar. +Effectively, $name foo bar/ is short for $name foo bar/foo +Options: +-h prints this help. +-c checks first for the existence of each file, and fails if it exists. +-i is like -c except that if the file exists and stdin and stdout are a + tty, a query is printed and a reply is read; a file is overwritten only + if the reply begins with 'y'. +-f unsets -c and -i (in case $cmd is aliased to $name). +-o (overwrite only) checks that the named file(s) exist and fails for any + that do not. It is the complement of the -c option. +Whichever of [cifo] comes later on the command line determines the behaviour. +Any of these options must come before any standard $cmd options." +} + +# interactive: Attempt to overwrite file should result in interactive +# query rather than automatic failure. +# noover: Do not overwrite files (if interactive is true, query, else fail) +# overwrite: Only overwriting is allowed, not creation of new files. +# debug: Print debugging info. +typeset interactive=false noover=false overwrite=false debug=false +name=${0##*/} + +case "$name" in +ncp|nmv) cmd=/bin/${name#?} ;; +*) echo "$name: Must be invoked as ncp or nmv." 1>&2 ; exit 2;; +esac + +Usage="Usage: $name [-cfhio] $cmd-cmd-line" + +while getopts :cfhiox opt; do + case $opt in + h) phelp; exit 0;; + x) debug=true ;; + c) noover=true ;; + i) noover=true ; interactive=true ;; + f) noover=false ; interactive=false ;; + o) overwrite=true ; noover=false ; interactive=false;; + +?) echo "$name: options should not be preceded by a '+'." 1>&2; exit 2;; + ?) echo "$name: $OPTARG: bad option. Use -h for help." 1>&2 ; exit 2;; + esac +done + +# remove args that were options +shift $((OPTIND - 1)) + +if [ $# -lt 2 ]; then + echo -e "$Usage\nUse -h for help." + exit +fi + +Check() +{ + if [ ! -f "$1" ] && $overwrite; then + echo "$name: $1: File does not exist." 1>&2 + return 1 + elif [ -f "$1" ] && $noover; then + if [ $interactive = false ] || [ ! -t 0 ] || [ ! -t 1 ]; then + echo "$name: $1: File exists." 1>&2 + return 1 + else + while :; do + echo -n \ +"$name: $1: File exists. Overwrite? (y)es/(n)o/(a)bort/(Y)es for all: " 1>&2 + read reply + case "$reply" in + y*) + echo "$name: Overwriting $1." + return 0 + ;; + Y*) + echo "$name: Overwriting $1." + interactive=false + noover=false + return 0 + ;; + [nN]*) + echo "$name: Skipping $2." + return 1 + ;; + [aA]*) + echo "$name: Aborting." + exit 1 + ;; + *) + echo "$name: Invalid response." 1>&2 + ;; + esac + done + fi + else + return 0 + fi +} + +# i is the index of the filename being examined +# lastarg is the index of the last filename before the dest directory name +typeset -i i=0 lastarg=$(($#-1)) + +# Sets argv[0..$#-1] +argv=("$@") +$debug && echo argv = "${argv[@]}" 1>&2 +dest=${argv[lastarg]} + +if $debug; then + echo \ +"interactive=$interactive noover=$noover overwrite=$overwrite debug=$debug +lastarg=$lastarg dest=$dest name=$name cmd=$cmd +files=$*" 1>&2 +fi + +if $noover || $overwrite; then + $debug && echo "checking for existance of directories..." 1>&2 + # If the destination is not intended to be a directory... + if [ $# -eq 2 ] && [ ! -d "$dest" ]; then + Check "$dest" "$1" || exit 0 # No files to copy + else + while [ $i -lt $lastarg ]; do + Check "$dest/${argv[i]##*/}" "${argv[i]}" || unset argv[i] + let i+=1 + done + fi +fi + +[ ${#argv[@]} -lt 2 ] && exit 0 + +# If only 2 args are given, mv/cp will not insist that the destination +# be a directory, which we want if the destination ends in "/" or if +# the original number of args was >2. +# $# is still the original number of args. +# Tack the file name onto the destination to force this behaviour. + +lastisslash() +{ + case "$1" in + */) return 0;; + *) return 1;; + esac +} + +if [ ${#argv[@]} = 2 ] && { lastisslash "$2" || [ $# -gt 2 ]; }; then + $debug && echo "Appending filename." 1>&2 + # Don't know which element of argv[] holds the source filename, + # since may have started with more than 1 source file & had some unset. + # So, compact args to make it easy to find the set one. + argv=("${argv[@]}") + argv[1]="${argv[1]}/${argv[0]##*/}" +fi + +$debug && echo "Executing command: $cmd ${argv[@]}" 1>&2 +exec $cmd "${argv[@]}" |