Is it possible to make scp fail when you do a local copy? I find it annoying to accidently create files with names like 192.168.11.5 when I meant to type 192.168.11.5: and hence copying the file to the remote computer.

link|improve this question
feedback

migrated from serverfault.com Jan 12 at 20:31

This question came from our site for system administrators and desktop support professionals.

2 Answers

up vote 5 down vote accepted

Not by default but if you want something quick you could just create a wrapper around it something like move the original binary to scp.orig and have a new shell script which takes the input, checks that there is a : in the input and passes it, if not prompts to continue ?

Edit: This post answers my question so I'm accepting but I wanted to add the shell function I wrote that solves the problem for me:

# Simple wrapper around scp to avoid forgotten colon's
scp() {
    if [[ $@ == *:* ]]; then
        # Looks like a valid command so run it
        command scp "$@"
    else
        echo -n "Would you like to add a colon to the end of the function? [y/n] "
        read response
        if [ "$response" = "y" ]; then
            command scp "$@":
        else
            command scp "$@"
        fi
    fi
}
link|improve this answer
@JasonAxelson Beware that your wrapper will break in some cases, for example if an option's argument contains : or if there are multiple sources. Also, you need quotes in "$@", otherwise your script will break with some file names (especially if you pass remote wildcards). I would recommend more checks on the last argument, as well, to only add a : to something that looks like a host name. – Gilles Jan 13 at 21:57
feedback

There's no such option in scp. You can write a wrapper script that checks the arguments. Here's one (untested, typed directly in the browser). It verifies that the last argument (the target) contains a :, or that all previous non-option arguments (the sources) contain a :.

#!/bin/sh
eval "target=\${$#}"
case $target in
  *:*) :;; # remote target
  *) # local target
    while getopts F:P:S:c:i:l:o:1246BCpqrv OPTLET; do :; done
    i=$OPTIND
    while [ $i -lt $# ]; do
      i=$((i+1))
      eval "source=\${$i}"
      case $source in
        *:*) :;; # remote source
        *)
          echo 1>&2 "Refusing to copy a local file to a local file with scp"
          exit 99;;
      esac
    done
esac
exec scp "$@"
link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.