我在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键完成文件的查找,然后用一个新的文件名完成这一行,这就成功地重命名了文件。
您的脚本很可能使用Windows风格的行尾。行尾看起来像
... myfile.txt
但实际上:
... myfile.txtrn
其中CCD_ 1是结束的Windows CR-LF行。这就是Windows文本文件中的行应该如何结束,但外壳无法识别Windows样式的行结束。它看到一行有效的文本,但它看到CR字符作为该行的一部分。因此它将"myfile.txtr"
作为文件名。
你是如何创建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
(我先创建了一个备份副本,以防出现问题,这样你就不会破坏你的脚本。)
这:
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
为了防止rn
0在ps
中找不到自己,请使用[first letter]
grep vnc | grep -v grep
grep [v]nc
并且由于awk
可以进行
awk '/[v]nc/ {some code}'