通过 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}"
如果我在本地命令行中使用 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}"