当我登录时,我收到以下消息:
-bash: $'\r' : command not found
-bash: $'\r' : command not found
-bash: $'\r' : command not found
很明显,它是由某些启动脚本中的 Windows 风格的行结尾引起的,所以我的问题是:我可以跟踪导致该问题的脚本以及如何跟踪吗?
答案1
Bash 在启动时读取许多不同的文件,甚至取决于它的启动方式(参见手册的描述)。还有一些类似的内容/etc/profile.d/
不会被 shell 直接读取,但可以从许多发行版中的其他启动文件中引用。
您必须完成所有这些操作,但幸运的是,您只需执行grep
回车即可。尝试例如:
grep $'\r' ~/.bashrc ~/.profile ~/.bash_login ~/.bash_profile /etc/bash.bashrc /etc/profile /etc/profile.d/*
也可以看看是否可以找出哪些文件正在设置/添加到环境变量及其优先顺序?对于类似的问题。
答案2
file(1) 在这里也很有帮助。
$file *
signin: Python script, ASCII text
signup: Python script, ASCII text, with CRLF line terminators
site_off.htm: XML 1.0 document, ASCII text
sitemaps: directory
我可以看到signup
需要删除那些讨厌的 Windows CRLF 行结尾。
对于直接递归,/home/username
您可能可以与find
and结合使用xargs
(也可能是 grep):
$ find . | xargs file | grep CR
./foo_data/V: ASCII text, with CR, LF line terminators
./foo_data/Y: ASCII text, with CR, LF line terminators
答案3
另一种方法是采用所有提到的启动脚本,并在每个脚本的开头回显标识每个脚本的字符串。
$ head .bashrc
echo "Running bashrc"
然后,登录时,您将看到类似以下内容:
running bashrc
running bash_aliases
-bash: $'\r' : command not found
-bash: $'\r' : command not found
-bash: $'\r' : command not found
running something_else
此时您可以得出结论,(在上面的示例中).bash_aliases
包含有问题的行结尾。
一旦您识别了该文件,但问题行并没有跳出来,您可以使用相同的方法来追踪该行。在文件中回显一条消息,然后在 3/4 或 1/4 秒内回显,具体取决于输出。这样,您就可以根据线路是在回声之前还是之后回声来追踪该线路。
答案4
我认为这个问题的难点不是“如何在文件中找到回车符?”但是“我怎样才能找到我的 bashrc 使用了哪些文件?”
对于第二个问题,你可以尝试这样的操作:
bash -x .bashrc
这将向您展示一切你的 bashrc 确实如此,包括它引用的所有文件。它很吵,但应该可以帮助您跟踪正在使用哪些文件。
但事实上,.bashrc
如果不以交互方式运行,我的(和许多其他)文件会提前退出,因此您必须欺骗它通过该检查:
bash -ix .bashrc
这里是-i
部队交互模式。
为了只找出源文件的情况,类似这样的东西对我有用,但我不能保证正则表达式捕获所有内容:
bash -ix .bashrc 2> >(grep -E '^\+* (\.|source)')
我想您可能还想要错误消息,例如:
bash -ix .bashrc 2> >(grep -E -e '^\+* (\.|source)' -e 'command not found')
如果由于某种原因这些都不起作用,我会求助于strace -e open bash
类似的方法来查找 bash 会话每次打开任何文件的时间。但这是一个更重量级/噪音更大的解决方案。