AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / computer / 问题 / 1722446
Accepted
Lunartist
Lunartist
Asked: 2022-05-23 18:38:38 +0800 CST2022-05-23 18:38:38 +0800 CST 2022-05-23 18:38:38 +0800 CST

如何使用名称中的'$1' scp java 内部类

  • 772

文件

sample$1.class
sample.class
scp_test.sh

scp_test.sh

#!/bin/bash

TARGET=('sample.class' 'sample$1.class')

for dd in "${TARGET[@]}"
do
  FILENAME=`basename ${dd}`
  scp ${FILENAME} remote:/tmp/${dd}
done

当 shell 运行时,在远程服务器上sample$1.class被覆盖, 只留下 .sample.class
sample.class

$ ./scp_test.sh
sample.class               100%    0     0.0KB/s   00:00
sample$1.class             100%    0     0.0KB/s   00:00
$ ssh remote 'ls -l /tmp/'
total 01 
sample.class

只有当它被复制时才会发生scp。使用本地副本的cp行为不是这样的。


*编辑由于我使用 4.3(4.2.46) 下的 Bash 版本,我不能使用${dd@Q}. 我通过使用引号组合'"${dd}"'而不是 plain解决了这个问题${dd}。

scp
  • 1 1 个回答
  • 53 Views

1 个回答

  • Voted
  1. Best Answer
    Kamil Maciorowski
    2022-05-24T08:49:04+08:002022-05-24T08:49:04+08:00

    初步说明

    这个答案主要是关于传统的scp,即scp使用 SCP 协议的传统。OpenSSH 的Modernscp默认使用 SFTP,当我写这篇文章时,过渡还不到两个月;所以很新鲜。我可以告诉你scp使用 SCP,因为如果它使用 SFTP,你就不会遇到有问题的问题。解决此类问题是 SCP 被 SFTP 取代的原因之一。

    从变更日志:

    OpenSSH 9.0 于 2022-04-08 发布。[…]

    […]

    此版本scp(1)从使用旧的 scp/rcp 协议切换到默认使用 SFTP 协议。

    scp host:* .旧版 scp/rcp通过远程 shell执行远程文件名(例如 )的通配符扩展 。这具有需要在命令行中包含的文件名中对 shell 元字符进行双引号的副作用scp(1),否则它们可能会被解释为远程端的 shell 命令。


    潜在问题独立于scp

    首先:引用正确。即使未引用,您的示例名称也可能是安全的,仍然编写健壮的代码是一种美德。IMO 如果您可以不引用而逃脱,那么总是引用比每次都努力思考更容易。您的带有正确引用变量的代码将如下所示(注意我还没有尝试解决这个问题scp,这将在稍后完成):

    #!/bin/bash
    
    target=('sample.class' 'sample$1.class')
    
    for dd in "${target[@]}"
    do
      filename="$(basename "${dd}")"
      scp -- "${filename}" "remote:/tmp/${dd}"
    done
    

    (我还将名称全部固定为大写,引入双破折号以防您添加以破折号开头的文件名target。我认为basename在这种特殊情况下是无操作的,但我认为您有理由这样做。)

    如果您scp使用 SFTP,那么上面的代码就可以工作(坦率地说,我认为您的原始代码也可以使用这样scp的 ,但只是因为您使用的名称在未引用时是“安全的”)。


    问题与scp

    不幸的是,遗留scp系统将远程路径名嵌入到 shell 代码中,该代码旨在由远程 shell 解释(比较我的这个答案)。远程 shell 将解释引号等字符$,[除非它们在到达远程 shell 时被转义或引用。这意味着您需要在本地额外引用远程 shell。您需要为本地 shell和远程 shell 引用。这就是引用的意思,即“要求文件名中的 shell 元字符双引号”。


    解决方案

    巴什可以提供帮助。"${dd@Q}"将扩展dd并转义或引用结果,因此在额外的解释级别(在您的情况下由远程外壳执行)之后,结果将是您期望的单个单词(如"$dd"在本地扩展)。以下行是对 legacy 的修复scp:

    scp -- "${filename}" "remote:/tmp/${dd@Q}"
    

    整个脚本将是:

    #!/bin/bash
    
    target=('sample.class' 'sample$1.class')
    
    for dd in "${target[@]}"
    do
      filename="$(basename "${dd}")"
      scp -- "${filename}" "remote:/tmp/${dd@Q}"
    done
    

    该解决方案不可移植,它不能在 pure 中工作sh。你的脚本中的 shebang 是#!/bin/bash从一开始的,所以我猜你不介意只在 Bash 中工作的代码。


    最后的笔记

    • 第一个片段(不带${dd@Q})适用于scp使用 SFTP(即新的)。第二个片段(带有${dd@Q})适用于scp使用 SCP(即 legacy scp)。没有简单的通用代码。使其表现得像 legacy的新scp支持,但是如果您使用 legacy ,那么它将失败,因为它会发现该选项无效。无论哪种方式,您都需要知道您是新的还是旧的,并相应地调整您的 shell 代码。现在你的旧的(因此首先是问题),但如果你更新它,它可能会被一个新的取代。已经链接的变更日志注意到不兼容:-Oscpscp-Oscpscp

      这产生了一个潜在的不兼容区域:scp(1)当使用 SFTP 协议时不再需要这种挑剔和脆弱的引用,并且尝试使用它可能会导致传输失败。我们认为删除文件名中双引号 shell 字符的需要是一个好处,并且不打算在scp(1)使用 SFTP 协议时引入旧 scp/rcp 的错误兼容性。

    • 一边“问题”,一个友好的建议。像这样命名你的脚本scp_test.sh不是一个好习惯。对于您scp_test.sh的翻译已经是bash,不是sh。您的原始代码需要bash并且不能纯工作sh(因为数组)。你要改名scp_test.bash吗?如果将脚本移植到 Python 会怎样?好的,我认为您不会对有问题的脚本执行此操作,但通常您可能会这样做。然后每个调用的工具scp_test.sh都需要修复并调用scp_test.py。

      命名脚本scp_test。scp_test您可以通过检查其权限来判断是否可执行。如果您想知道它是什么,请调用file scp_test. 现在你可以用你想要的任何语言重写脚本,甚至编译一个二进制文件,你(或任何人/任何东西)仍然可以将它作为scp_test.

    • 1

相关问题

  • 使用带有 WinSCP 的 SCP 协议下载时,排除的文件需要很长时间才能处理

  • 在 scp 传输期间产生、预期、发送中止

  • 如何设置 WinSCP 将文件传输到远程 ABCI 服务器

  • 有没有办法将 scp 到“这台”机器?(“父”机器?)

  • Atom 搞乱了 Emacs 文件中的格式

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何减少“vmmem”进程的消耗?

    • 11 个回答
  • Marko Smith

    从 Microsoft Stream 下载视频

    • 4 个回答
  • Marko Smith

    Google Chrome DevTools 无法解析 SourceMap:chrome-extension

    • 6 个回答
  • Marko Smith

    Windows 照片查看器因为内存不足而无法运行?

    • 5 个回答
  • Marko Smith

    支持结束后如何激活 WindowsXP?

    • 6 个回答
  • Marko Smith

    远程桌面间歇性冻结

    • 7 个回答
  • Marko Smith

    子网掩码 /32 是什么意思?

    • 6 个回答
  • Marko Smith

    鼠标指针在 Windows 中按下的箭头键上移动?

    • 1 个回答
  • Marko Smith

    VirtualBox 无法以 VERR_NEM_VM_CREATE_FAILED 启动

    • 8 个回答
  • Marko Smith

    应用程序不会出现在 MacBook 的摄像头和麦克风隐私设置中

    • 5 个回答
  • Martin Hope
    Saaru Lindestøkke 为什么使用 Python 的 tar 库时 tar.xz 文件比 macOS tar 小 15 倍? 2021-03-14 09:37:48 +0800 CST
  • Martin Hope
    CiaranWelsh 如何减少“vmmem”进程的消耗? 2020-06-10 02:06:58 +0800 CST
  • Martin Hope
    Jim Windows 10 搜索未加载,显示空白窗口 2020-02-06 03:28:26 +0800 CST
  • Martin Hope
    v15 为什么通过电缆(同轴电缆)的千兆位/秒 Internet 连接不能像光纤一样提供对称速度? 2020-01-25 08:53:31 +0800 CST
  • Martin Hope
    andre_ss6 远程桌面间歇性冻结 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney 为什么在 URL 后面加一个点会删除登录信息? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension 鼠标指针在 Windows 中按下的箭头键上移动? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    jonsca 我所有的 Firefox 附加组件突然被禁用了,我该如何重新启用它们? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK 是否可以使用文本创建二维码? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 更改 git init 默认分支名称 2019-04-01 06:16:56 +0800 CST

热门标签

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve