On 23/03/10 06:15, Jim Meyering wrote:
> Pádraig Brady wrote:
>>
>> However `replace` is used by mysql-server as previously mentioned.
>> And `repl` is used by nmh. How about keeping with the terse unix
>> tradition while alluding to the relationship with cp/mv/rm by using...
>>
>> rp
> 
> I wouldn't object.
> 
> A possible bastardized compromise: re-place
> It's sort of analogous to in-place.

None of rp, inplace, re-place are great TBH.
Anyway attached is the latest version.
It's getting a bit complicated, but I don't
think much more needs to go in (maybe translations?)

cheers,
Pádraig.
#!/bin/sh

me=$(basename $0)

usage() {
  err=$1; out=2
  [ $err -eq 0 ] && out=1
  printf "\
$me [OPTION] 'FILTER' FILE...
Replace the contents of each FILE after processing with FILTER

      --backup[=CONTROL]  make a backup of each existing destination file
  -b                      like --backup but does not accept an argument
  -C, --compare           compare each pair of source and destination files, and
                            in some cases, do not modify the destination at all.
  -p, --preserve-timestamps  apply access/modification times of SOURCE files
                             to corresponding destination files.

  -S, --suffix=SUFFIX     override the usual backup suffix

The backup suffix is \`~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX.
The version control method may be selected via the --backup option or through
the VERSION_CONTROL environment variable.  Here are the values:

  none            never make backups (even if --backup is given)
  numbered        make numbered backups
  existing        numbered if numbered backups exist, simple otherwise
  simple          always make simple backups

Report "$me" bugs to [email protected]
GNU coreutils home page: <http://www.gnu.org/software/coreutils/>
General help using GNU software: <http://www.gnu.org/gethelp/>
Report "$me" translation bugs to <http://translationproject.org/team/>
" >&$out
  exit $err
}

version() {
  Cmd=$1; Date=2010; Version=8.5 #TODO: auto update
  #TODO: translation
  printf "\
$Cmd (GNU coreutils) $Version
Copyright (C) $Date Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Pádraig Brady.
"
  exit 0
}

if getopt -T >/dev/null 2>&1; test $? -ne 4; then
  # Enhanced getopt(1) not available and POSIX getopts
  # only supports short options, so revert to simple manual parsing
  if test $# -lt 2; then
    test "$1" = "--help" && usage 0
    test "$1" = "--version" && version "$me"
    usage 1
  fi
else
  OPT=$(
    getopt -o bCpS: \
           --long backup::,compare,help,preserve-timestamps,suffix:,version \
           -n"$me" -- "$@" ||
    usage 1
  )
  eval set -- "$OPT"

  while true; do
    case "$1" in
      -b)
        test "$VERSION_CONTROL" || VERSION_CONTROL="existing"
        backup="$VERSION_CONTROL"; shift;;
      --backup)
        case "$2" in
          "") backup=existing; shift 2;;
          *) backup="$2"; shift 2;;
        esac;;
      -C|--compare) compare=1; shift;;
      -p|--preserve-timestamps) preserve_times=1; shift;;
      -S|--suffix) suffix="$2"; shift 2;;
      --help) usage 0; shift;;
      --version) version "$me"; shift;;
      --) shift; break ;;
      *) echo "Option processing error"; exit 1;;
    esac
  done

  if test "$backup"; then
    backup="--backup=$backup"
    test "$suffix" && backup="$backup --suffix=$suffix"
  fi

  if test $# -lt 1; then
    printf "\
$me: missing file operand
Try \`$me --help' for more information.
"
  fi
fi

filter="$1"; shift

cleanup() { rm -f "$tf"; }
trap "cleanup" EXIT

filter_file() {
  ret=0

  if $filter < "$file" > "$tf"; then
    if test "$preserve_times"; then
      touch "$tf" --reference="$file" || { ret=1; fail=1; }
    fi
  else
    ret=1; fail=1
  fi

  if test $ret = 0; then
    if test "$compare"; then
      cmp -s -- "$tf" "$file"
      status=$?
      test $status -eq 0 && { ret=1; } # Don't process further
      test $status -gt 1 && { ret=1; fail=1; }
    fi
  fi

  return $ret
}

fail=0
for file in "$@"; do
  dir=$(dirname -- "$file")
  tf=$(mktemp -q --tmpdir="$dir")
  if test -e "$tf" && cp --attr -- "$file" "$tf" 2>/dev/null; then
    # Modify file atomically.
    # We could `chmod u+rw` here to allow updating non rw files?
    filter_file &&
    { mv $backup -- "$tf" "$file" || fail=1; } # rename
  else
    # cp doesn't support --attributes-only or
    # $dir is not writeable.  In this case we
    # use $TMPDIR, but don't use mv to unlink/copy
    # as $TMPDIR might not support all attrs of $dir.
    # Also we can't unlink in unwriteable dir.
    # Note we won't be able to update non rw files like this.
    cleanup # dir/file.tmp
    tf=$(mktemp)
    filter_file &&
    { cp $backup -- "$tf" "$file" || fail=1; } # truncate and copy
    test "$preserve_times" && touch "$file" --reference="$tf"
    cleanup # tmp/file.tmp
  fi
done

exit $fail

Reply via email to