防止 scp 复制本地文件?

防止 scp 复制本地文件?

我刚刚读了Linux scp 命令问题问题,它提醒我,我经常忘记在 scp 命令的主机部分指定冒号,因此在本地复制文件而不是复制到远程主机,例如我

scp foo host

代替

scp foo host:

但我从未使用 scp 在本地复制文件。因此,我想知道如果两个(源和目标)参数都引用本地文件,是否有办法让 scp 失败。

答案1

您可以在 Bash 中编写一个包装函数并将其命名为scp,用于getopts将选项处理为新数组,将源和目标保留在位置参数中,然后检查这些参数是否存在“@”和“:”,如果不存在,则发出错误消息。如果存在,则使用scp类似 的命令调用实际函数command scp "${args[@]}" "$source" "$dest"。该command命令使 Bash 调用在 中找到的程序,PATH而不是同名的函数。

因为至少在我的系统上scp只支持短选项类型getopts(也只支持短选项)就可以了。

该函数看起来像这样(未经测试):

scp () {
    # wrapper function to prevent scp of local-only files
    options=":346BCpqrTvc:F:i:J:l:o:P:S:"
    while getopts $options option
    do
        case $option in
            3 | 4 | 6 | B | C | p | q | r | T | v)
                args+=($option)
                ;;
            c | F | i | J | l | o | P | S)
                args+=($option "$OPTARG")
                ;;
            \? ) echo "Unknown option: -$OPTARG" >&2; return 1;;
            :  ) echo "Missing option argument for -$OPTARG" >&2; return 1;;
            *  ) echo "Unimplemented option: -$option" >&2; return 1;;
        esac
    done

    shift $((OPTIND - 1))

    if [[ $1 != *@*:* && $2 != *@*:* ]]
    then
        echo "Local-only copy not permitted"
        echo "to override, use 'command scp ARGS'"
        return 1
    fi
    command scp "${args[@]}" "$1" "$2"
}

此脚本中的选项反映了scp撰写本文时所接受的选项,但它们可能会随时间而变化。这是此类包装器脚本所带来的风险之一。

答案2

scp使用常规cp来复制本地文件。

创建一个名为的脚本cp并确保scp使用修改后的运行PATH,以便找到该脚本而不是真正的脚本cp

脚本可能是这样的:

#!/bin/sh
echo 'Local copying unsupported!' >&2
exit 1

将其另存为~/.weird-stuff/cp并使其可执行。然后创建一个名为的包装器scp,修改PATH真实的scp。示例包装器函数:

scp () {
PATH="$HOME/.weird-stuff:$PATH" command scp "$@";
}

您可能更喜欢等效的包装脚本。

坏处:

  • 无法保证 的未来版本scp将依赖cp。如果scp停止依赖cp(或停止依赖PATH来查找cp),则解决方案将停止工作。

优势:

  • 解决方案(不同于这个) 不需要理解 支持的选项scp。无论scp命令行 如何解释,或者将来此事是否发生任何变化,只要scp继续使用cp进行本地复制(并PATH查找cp),该解决方案就会起作用。

答案3

低成本解决方案:如果如果您总是/经常从同一目录复制,并且总是/经常复制到同一主机,只需创建一个具有主机名称的假文件并删除其上的所有写权限:touch host && chmod ugo-w host。然后您的错误 scp 命令将失败。

相关内容