我在Windows机器上使用Cygwin从远程Linux机器获取一些信息并将结果写入文件。这是我的命令:
ssh user@remotemachine ps -aef | grep vnc | grep -v grep | awk '{print "<size>"$11"<\/size>""\n""<colorDepth>"$13"<\/colorDepth>"}' > myfile.txt
但是,当我运行
时ls -l
在写入myfile.txt的目录上,它显示文件的名称实际上是 myfile.txt?(带有添加的问号)。该额外字符来自何处以及如何将打印代码正确命名为myfile.txt
我会运行另一个命令,例如
mv myfile.txt? myfile.txt
或
mv myfile.txt^M myfile.txt
但是在我的bash脚本中似乎都没有找到要重命名的文件(尽管有趣的是我可以从终端(不在脚本中)开始输入
mv myf
然后使用Tab键完成文件的查找,然后使用新文件名完成该行,并成功重命名该文件。
答案 0 :(得分:5)
您的脚本很可能使用Windows样式的行结尾。 行的结尾看起来像一样
... myfile.txt
但确实如此:
... myfile.txt\r\n
其中\r\n
是Windows CR-LF行结尾。这是Windows文本文件中的行应该如何结束,但shell不能识别Windows样式的行结尾。它看到一个有效的文本行,但它将CR字符视为该行的一部分。因此,它将"myfile.txt\r"
视为文件名。
您是如何创建bash脚本文件的?如果您使用的是Windows本机编辑器,则说明行结尾。
许多编辑器(包括vim)将自动适应文件的行结尾,因此您可能无法从编辑器中删除额外的\r
。
并且ls
会将CR等不可打印的字符显示为?
。
在脚本上运行file
可能会告诉您行结尾。
通过dos2unix
命令过滤脚本。 (首先阅读手册页;与大多数文本过滤器不同,dos2unix
更新其输入文件而不是写入stdout
。)
这也应该有效:
mv foo.sh foo.sh.bad
tr -d '\r' < foo.sh.bad > foo.sh
chmod +x foo.sh
(我先创建了一个备份副本,以防出现问题,所以你不要破坏你的脚本。)
答案 1 :(得分:0)
此:
ssh user@remotemachine ps -aef | grep vnc | grep -v grep | awk '{print "<size>"$11"<\/size>""\n""<colorDepth>"$13"<\/colorDepth>"}' > myfile.txt
可以改写为:
ssh user@remotemachine ps -aef | awk '/[v]nc/ {print "<size>"$11"<\/size>""\n""<colorDepth>"$13"<\/colorDepth>"}' > myfile.txt
要阻止grep
在ps
使用[first letter]
grep vnc | grep -v grep
grep [v]nc
,因为awk
可以做到这一点
awk '/[v]nc/ {some code}'