Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当命令在本地(/bin/sh-c CMD)和远程(ssh node1/bin/sh-c CMD)运行时,shell(sh或csh)在处理参数方面的行为是否有所不同?_Shell_Ssh_Csh - Fatal编程技术网

当命令在本地(/bin/sh-c CMD)和远程(ssh node1/bin/sh-c CMD)运行时,shell(sh或csh)在处理参数方面的行为是否有所不同?

当命令在本地(/bin/sh-c CMD)和远程(ssh node1/bin/sh-c CMD)运行时,shell(sh或csh)在处理参数方面的行为是否有所不同?,shell,ssh,csh,Shell,Ssh,Csh,在本地运行与通过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本身正在这样做?TLDR:您的示例由于本地shell处理而失败 在Unix上,当进程x(如shell)运行不同的程序y(通常作为子进程,但不一定)时

在本地运行与通过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本身正在这样做?

TLDR:您的示例由于本地shell处理而失败

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

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

因为C数组从下标0开始,参数数组通常被命名为<代码> ARGV (从BCPL导出的参数向量-C,其中数组被称为向量)C(和C++等)程序员经常称程序名为“AGV零”。请注意,您可以让同一个程序在文件系统中以多个名称出现,因此它的名称在编译时不为人所知,只有在它运行时才为人所知;这种技巧过去在诸如

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
之后的一个参数作为整个命令行(或脚本)进行解析并执行结果(可能),但
'/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
参数,然后使用

/bin/csh
-c
/bin/echo a b c d
因此,它将-c之后的一个参数作为命令行,可以成功解析并运行该命令行


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

TLDR:您的示例由于本地shell处理而失败

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

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

因为C数组从下标0开始,参数数组通常被命名为<代码> ARGV (从BCPL导出的参数向量-C,其中数组被称为向量)C(和C++等)程序员经常称程序名为“AGV零”。请注意,您可以让同一个程序在文件系统中以多个名称出现,因此它的名称在编译时不为人所知,只有在它运行时才为人所知;这种技巧过去在诸如

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
之后的一个参数作为整个命令行(或脚本)进行解析并执行结果(可能),但
'/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
参数,然后使用

/bin/csh
-c
/bin/echo a b c d
因此,它将-c之后的一个参数作为命令行,可以成功解析并运行该命令行

这就是为什么我们在多个堆栈上有几十个Q,用于“如何让ssh使用特殊字符和/或插值正确地远程运行此命令”的许多变体