通过 ssh 在返回的文本中保留 '\n' 换行符

Preserve '\n' newline in returned text over ssh

如果我在本地命令行中使用 grep 和 sort 等执行查找命令,我得到的返回行如下:

# find ~/logs/ -iname 'status' | xargs grep 'last seen' | sort --field-separator=: -k 4 -g
0:0:line:1
0:0:line:2
0:0:line:3

如果我通过 ssh 执行相同的命令,返回的文本打印时没有换行符,如下所示:

# VARcmdChk="$(ssh ${VARuser}@${VARserver} "find ~/logs/ -iname 'status' | xargs grep 'last seen' | sort --field-separator=: -k 4 -g")"
# echo ${VARcmdChk}
0:0:line:1 0:0:line:2 0:0:line:3

我想了解为什么 ssh 会清理返回的文本,以便将换行符转换为空格。我还没有尝试输出到文件,然后使用 scp 将其拉回。似乎很浪费,因为我只想在本地查看远程结果。

回显变量VARcmdChk时,应该用"括起来。

$ VARcmdChk=$(ssh ${VARuser}@${VARserver} "find tmp/ -iname status -exec grep 'last seen' {} \; | sort --field-separator=: -k 4 -g")
$ echo "${VARcmdChk}"
last seen:11:22:33:44:55:66:77:88:99:00
last seen:00:99:88:77:66:55:44:33:22:11

请注意,我已将您的 xargs 替换为 -exec

好的,这个问题与这个问题重复,Why does shell Command Substitution gobble up a trailing newline char?,所以只回答了一部分。

但是,我只是说一部分,因为答案会告诉您发生这种情况的原因,但解决方案的唯一线索是最后的小答案。

解决方案是引用echo参数,如解决方案所示:

# VARcmdChk="$(ssh ${VARuser}@${VARserver} "find ~/logs/ -iname 'status' | xargs grep 'last seen' | sort --field-separator=: -k 4 -g")"
# echo "${VARcmdChk}"
0:0:line:1
0:0:line:2
0:0:line:3

但是没有解释为什么会这样工作,因为假设变量是一个字符串,所以应该按预期打印。然而,阅读 Expansion of variable inside single quotes in a command in Bash 提供了有关在字符串中保留换行符等的线索。将要通过 echo 打印的变量放在引号中,可以绝对保留内容,并获得预期的输出。

变量的echo就是为什么要把它全部放在一行中的原因。 运行 以下命令将按预期输出结果:

ssh ${VARuser}@${VARserver} "find ~/logs/ -iname 'status' | xargs grep 'last seen' | sort --field-separator=: -k 4 -g"

要使命令输出在新行上显示每个结果,就像您在本地 运行 命令时所做的那样,您可以使用 awk 将结果拆分到新行中。

awk '{print "\n"}'

可以像这样将此方法附加到您的命令中:

echo ${VARcmdChk} | awk '{print "\n""\n""\n"}'

或者,您可以根据您的回答在变量周围加上引号:

echo "${VARcmdChk}"