【问题标题】:Does shell (sh or csh) behave differently for handling arguments when commands get run locally(/bin/sh -c CMD) vs remotely (ssh node1 /bin/sh -c CMD)?当命令在本地(/bin/sh -c CMD)与远程(ssh node1 /bin/sh -c CMD)运行时,shell(sh 或 csh)在处理参数方面的行为是否不同?
【发布时间】:2021-05-05 18:18:02
【问题描述】:

在本地运行与通过 ssh 远程运行时,我得到以下不同的命令行为。

$ /bin/csh -c \'/bin/echo a b c d\'
Unmatched '''.
$ ssh node1 /bin/csh -c \'/bin/echo a b c d\'
a b c d

这里的 ssh 是否以不同的方式处理命令参数并以某种方式删除转义字符? (或者本地 shell 本身正在这样做?)

【问题讨论】:

    标签: shell ssh csh


    【解决方案1】:

    TLDR:您的示例因本地 shell 处理而失败。

    在 Unix 上,当进程 x(例如 shell)运行不同的程序 y(通常作为子进程,但不一定)时,它会将 y 自己的名称 加上任何参数作为 可变长度数组 字符串,例如在旧系统上echo a b c d 运行带有参数数组的echo 程序(为清楚起见,每行显示一个)

    echo
    a
    b
    c
    d
    

    (在最新系统echo 上的大多数shell 上是shell 内置而不是单独的程序,但其他 程序仍然以传统方式工作。)

    因为 C 数组从下标 0 开始,并且参数数组通常命名为 argv(参数向量 - C 派生自 BCPL,其中数组称为向量)C(和 C++ 等)程序员通常将程序名称称为“argv -零”。请注意,您可以让同一个程序以多个名称出现在文件系统中,因此它的名称在编译时是未知的,只有在运行时才知道;这个技巧曾经在 gzip/gunzip 之类的东西上很流行,但近几十年来似乎已经过时了。

    在 shell 输入中,反斜杠单引号意味着将该单引号视为普通数据,而不是用它来引用其他字符,例如分隔单词和参数的空格,所以

    /bin/csh -c \'/bin/echo a b c d\'
    

    使用以下 argv 运行 /bin/csh:

    /bin/csh
    -c
    '/bin/echo
    a
    b
    c
    d'
    

    csh(或 Bourne 类型的 shell)将 -c 之后的 one 参数作为要解析的整个命令 line(或脚本)和结果(可能) 已执行,但 '/bin/echo 不是有效的命令行。任何剩余的参数都不会被视为命令,而是可能的参数到正在运行的命令(如果需要它们)。

    另一方面,ssh 客户端程序将任何和所有“数据”参数(不是选项,也不是必需的 [user@]remotehost 参数)视为构成要远程运行的命令,并通过 SSH 发送它们协议全部连接成一行,所以你的ssh 命令得到

    ssh
    node1
    /bin/csh
    -c
    '/bin/echo
    a
    b
    c
    d'
    

    但发送

    /bin/csh -c '/bin/echo a b c d'
    

    并且远程系统上的sshd 将整行作为一个参数传递给您的登录shell,然后将其作为一个单独的-c 参数,然后运行csh

    /bin/csh
    -c
    /bin/echo a b c d
    

    所以它将-c后面的一个参数作为命令行,它可以成功解析并运行。

    而这种组合就是为什么我们在多个堆栈上有几十个 Q 用于“如何让 ssh 使用特殊字符和/或插值正确地远程运行此命令”的许多变体。虽然通常有一个可能的答案,但通常最简单的方法是通过运行不带远程命令参数的 ssh,因此它远程运行交互式 shell,并将所需的命令作为 输入 em> 到那个外壳;或者,几乎相同,将命令放入文件中,将该文件传输到远程系统(或通过 NFS 或类似方式访问),然后告诉远程系统运行 文件作为脚本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-22
      • 2021-10-16
      • 1970-01-01
      • 2011-01-30
      • 2013-01-29
      • 1970-01-01
      • 2011-04-28
      • 2019-12-27
      相关资源
      最近更新 更多