为什么在 ssh 会话中使用管道读取失败?

为什么在 ssh 会话中使用管道读取失败?

为什么这显示空行而不是 find 找到的文件夹?

ssh -o stricthostkeychecking=no -o userknownhostsfile=/dev/null \
  -o batchmode=yes -o passwordauthentication=no [email protected] \
  "sudo find /folder/CFGKCP/KCS\ Pro/Job\ Setup -name JOBCFG.info \
    | while read linea; do echo $linea; done";

答案1

正如罗密欧指出的,您在命令周围使用双引号。这意味着您的变量在执行命令之前已被扩展ssh。所以 while 循环的主体是

echo $linea

并且在ssh linea可能不存在之前,因此传递的命令将被echo替换linea为空字符串。

如果您在命令参数周围使用单引号,则不会发生参数扩展,并且该字符串将完好无损地传递,所以也可以

ssh -o stricthostkeychecking=no -o userknownhostsfile=/dev/null -o batchmode=yes -o passwordauthentication=no [email protected] 'sudo find /folder/CFGKCP/KCS\ Pro/Job\ Setup -name JOBCFG.info | while read linea; do echo $linea; done'

或转义$告诉你的 shell 不要扩展它

答案2

因为你使用的是双引号。这意味着在运行$linea之前已扩展。ssh您可以使用以下方法进行测试set -x

$ set -x
$ ssh user@host "find /var  | while read line; do echo $line; done"
+ ssh user@host 'find /var  | while read line; do echo ; done'

正如你所看到的,实际执行的命令是echo没有变量的。为了避免这种情况,您可以使用单引号而不是双引号:

ssh user@host 'find /var  | while read line; do echo "$line"; done'

或者,在本地运行 while 循环:

ssh user@host find /var  | while read line; do echo "$line"; done

在上面的示例中,find在远程主机上运行,while​​在本地运行,根据命令的输出ssh

答案3

避免while read循环。

ssh [email protected] '
  sudo find "/folder/CFGKCP/KCS Pro/Job Setup" -name JOBCFG.info -exec sed -i "
    /^\[General]/,/^\[/ {
      s/^JobRoot = .*/JobRoot = C:\\\\LOTES\\\\TMP\\\\\r/
    }" {} +'

或者用单引号:

ssh [email protected] '
  sudo find "/folder/CFGKCP/KCS Pro/Job Setup" -name JOBCFG.info -exec sed -i '\''
    /^\[General]/,/^\[/ {
      s/^JobRoot = .*/JobRoot = C:\\LOTES\\TMP\\\r/
    }'\'' {} +'

(这\r已经是 GNU 特定的,所以你也可以使用-i)。

答案4

感谢您对将变量扩展为引号的解释,现在我明白了我的问题从哪里开始。我仍然必须承受嵌套单引号,因为顺序而不是 echo 使用它们。这是一个更详细的示例:

ssh [email protected] '
    sudo find /folder/CFGKCP/KCS\ Pro/Job\ Setup -name JOBCFG.info|
        while read line; do
            sudo sed '/^\[General\]/,/^\[/ {s/^JobRoot = .*/JobRoot = C:\\LOTES\\TMP\\\r/}' "$line" |sudo tee "$line".modificado; sudo mv -f "$line".modificado "$line";
        done
';

相关内容