登录后如何跟踪给我“找不到命令”的脚本?


8

登录时,我收到以下消息:

-bash: $'\r' : command not found
-bash: $'\r' : command not found
-bash: $'\r' : command not found 

很明显,它是由某些启动脚本中的Windows样式的行尾引起的,所以我的问题是:我可以跟踪导致该行尾的脚本吗?


2
试着在你的home目录看的.bashrc,.bash_profile文件和配置文件,以及/ etc / profile文件
拉曼Sailopal

Answers:


14

Bash在启动时会读取许多不同的文件,甚至取决于启动方式(有关说明,请参见手册)。然后/etc/profile.d/,shell不会直接读取类似的东西,但是可以从许多发行版的其他启动文件中引用这些东西。

您将必须完成所有这些操作,但是幸运的是,您可以只grep为回车。尝试例如:

grep $'\r' ~/.bashrc ~/.profile ~/.bash_login ~/.bash_profile /etc/bash.bashrc /etc/profile /etc/profile.d/*

另请参见是否可以找出正在设置/添加到环境变量的文件及其优先顺序?对于类似的问题。


6
寻找另一个地方:~/.bash_aliases
Weiwei Zhou,

1
另一种选择是使用strace -e open your-shell来自斯特凡的答案
杰夫·谢勒

5

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您可以将findand与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 / 4s,具体取决于输出。这样,您可以根据回声之前还是之后的回声来跟踪行。


是的,如果可以快速将其自动化,则此方法很好,否则与浏览所有这些文件几乎相同。
Denis Sablukov

1
请注意,您可能还希望在每个文件的末尾说“完成运行<文件>”。在这种情况下,除非只有一些行具有CR行尾,否则这并不重要,但是,如果您正在寻找另一个错误,那么在获取.bash_aliases之后可能就在您的.bashrc中。
本·米尔伍德

1
对于只是学习调试外壳问题的人,或者当它不像搜索“ \ r”那样容易时,在您的知识工具箱中值得此答案。我继承了一个复杂的构建系统,该系统是相互缠绕的脚本的巢,可以通过SSH进行远程构建。这是解散并将其移至Docker容器的唯一方法。
Scott Prive

1
另一个一般性提示-处理相互关联的Bash脚本时,请注意在何处添加echo语句并(无论您在做什么)经常进行测试。如果使用bash脚本将字符串输出到STDOUT并将调试语句添加到STDOUT,则可能会破坏正在调试的内容。有时答案是使用“ logger”命令将信息/调试添加到脚本中。在其他情况下,如果有警告,请使用STDERR。
Scott Prive

@DenisSablukov如果文件很长,并且需要花一些时间查看,则此方法将帮助您更快地缩小源范围。排到6个文件的顶部和底部不需要很长时间。
user394

3

我认为这个问题的难点不是“我如何在文件中找到回车符?” 但是“如何找出我的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 bashbash会话每次打开任何文件的方法或类似方法。但这是一个更重的/嘈杂的解决方案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.