虽然我们习惯了任何一次新的尝试都会遇到这样那样的问题,但不得不说,与 Windows 系列相比,Linux 平台更容易引发挫败感:因为它更分散,当一个任务需要依赖的部件越多,那么出现问题的机率也就成倍地增加了。

初次在 Ubuntu Server 上运行 ASP.NET 5 的过程也是这样一个并不算顺利的过程。主要遇到了下面的一些问题,记录在此,希望能有一些帮助。

 

command not found

有时候,你输入一个命令,它会提示 xxx command not found,英文字面含义就是计算机中没有这个命令或程序。如果输入的恰好的是一个 apt 包,它会提示可以输入 apt-get 的安装命令。

这基本是最简单的问题了,照着屏幕中的提示,输入对应的 apt-get install 指令即可轻松解决。

image

 

System.NotImplementedException: The requested feature is not implemented.

在安装了 Mono 和 dnvm 之后,运行 dnu restore 时被提示此错误。此错误指的是运行恢复包工作时,要调用的 .NET 功能在 Mono 中没有对应的实现,多是 Mono 版本过低所致,升级 Mono 版本即可。如果看到此错误,说明至少有一个 Mono 运行时在您的服务器上,但它的版本过低。

升级过程其实并不麻烦,分情况可以直接升级或者卸载了重新安装,都可以。如果之前是从源码安装的,那么使用卸载再装的方式:继续去该源码文件夹,使用 make uninstall 就可以卸载了。如果源码文件夹已经删除了?那么使用 which mono 来确定 mono 的安装位置,使用下面的命令来删除所有该目录中的 mono 相关文件。警告:这些命令将会永久删除不确定的文件,请慎用!与传统的网上 Linux Shell 脚本一样,我将各行添加了 # 作为注释符,如果你确定需要使用,请自行取消注释之后再用。

# cd /usr/bin

for i in ls -al | grep mono | awk '{print $9}'; do

rm ${i}

done

如果之前是使用 apt-get install 的方式安装的,那么先使用 apt-get update 更新源,然后再次来尝试 apt-get install 来尝试更新;之后再使用 mono –v 来查看是否已经更新到 4.x 版本。不行的话,可以先执行 apt-get remove 包,然后再安装。

最后仍安装到一个低版本?我是遇到过的。这种情况下,请使用 apt-get remove 来移除刚刚安装过的包,虽然 apt-get remove 并不稳定,经常出错。然后按照我上一篇文章中介绍的从源码安装的方法来安装最新版本。

仍请参考张善友关于升级 Mono 的文章

 

xxx depends yyy will not be installed

使用 apt-get install 的时候经常可能遇到这样的错误提示。意思也很直白,也就是说正要安装的软件包依赖了另一个软件包,但因为某个原因,不能自动地安装那个包。一些情况下,直接手动安装它说的无法安装的 yyy 包,是可以的,随后再重试安装 xxx。如果被提示说找不到这个软件包,那么做一次 apt-get update 操作之后再试。

值得一提的是,我在 Azure 的虚拟机 Ubuntu 14.04 中执行 apt-get install mono-complete 的时候提示“mono-complete depends mono-devel will not be installed”,我就手动执行 apt-get install mono-devel 来安装它,完成之后,这台服务器上的 Mono 运行时居然被自动地安装为了最新的版本。这样看来,理论上,我们直接仅安装 mono-devel,而不是 mono-complete,也就够了。由于 mono-complete 实际上是一个很大的礼包,所以如果能够少装就可以少装一些了。

 

System.IO.FileNotFoundException: Could not load file or assembly

在运行 dnx . kestrel 命令尝试启动应用程序的时候,可能出现这样的错误。其实屏幕里也会输出提示信息,原因就是有些被依赖的包还没能解析出来。一般是因为没有提前执行 dnu restore 操作所致的。

当然,也有可能是其他依赖问题,具体请参考此文章(英文)

 

dnu restore: The authentication or decryption has failed

这个错误令我有点意外,不过也似乎在情理之中:毕竟我以前并没有真正意义上的基于 Mono 做开发工作。这个问题原因是 Linux 中各个软件的证书存储比较分散,所以新安装的 mono 中还无法验证指定的 SSL 证书的合法性。mono 中提供了一个工具可以很快解决此问题:

mozroots –import –ask-remove

此解决方法来自 Stackoverflow,也可以参照 mono 官方对此的介绍

 

dnu restore: a task is canceled

如果你发现 dnu restore 命令开始很久之后,屏幕中开始出现黄颜色的这个错误,则说明可能发生了 HTTP 超时。最新版本中的 dnu 针对这种情况的提示会更友好,而且还会自动重试。不过,遗憾的是,这个 restore 的过程其实真的并不容易成功。还是 dudu,提到了 NuGet v3 api 会提高速度的情况,我也进行了尝试,效果还是有的。

然而并没有什么用,因为最后我感觉到是伟大的墙发挥了效用:在中国来执行这种 restore 就会一直超时并失败,目前这个问题还没有什么好的解决方法。

 

dnu restore: Cannot handle address family 61712

在执行 dnu restore 可能会遇到这个错误提示。据说这是新版 mono 的一个 BUG。博客园的 dudu 也遇到这个状况,他给出的解决方法是重置机器上的 DNS 缓存。不过,在试过之后,我遇到的问题却并没有能够解决。还好这个错误并不会真正阻碍 restore 的过程,它只会在 restore 操作的某一个不确定的时机发生。几经重试,最终还是能够完成 restore 的过程,自己比较辛苦就是了。

 

An exception was thrown by the type initlializer for HttpApi

这个问题比较简单,是因为试图运行为 Windows 编写的开发服务器程序所致。在 Ubuntu Server 上,我们应该换成调用 Kestrel 服务器程序的命令。例如上一篇文章中提到的 dnx . kestrel

 

Kestrel: System.Exception: Error -4092 EACCES permission denied

sudo dnx  command not found

如果直接运行 dnx . kestrel 可能会遇到这两个连续的错误,因为绑定到一个端口需要管理员权限。但接下来,试图使用 sudo 提权的时候,会被提示找不到 dnx 命令,令人费解。

看起来似乎是 sudo 后面的命令就不能是别名引用了。那么很快,我就可以知道怎么做了:使用 which dnx 找到 dnx 所在,并手动指业它的完全路径,然后传入 kestrel 参数。

 

 

暂时只记录了这么多,回想起来,再补充。

又到了回顾结论的时候。我经常有意无意地自我暗示,说自己是一个悲观主义者。因为我很清楚,无论是学习一门新语言还是使用一个不熟悉的框架,每做一次尝试都会遇到若干这样那样的问题,有些问题很容易解决,而有一些则可能成为障碍。当然,一般情况下我会去做一个动手尝试是因为理论上是可行的。在坚信目标能够完成的前提下,我想尽一切方法尽可能地去解决这些问题,趟过这趟水,也就知道它的深浅了。