Dan Nanni 发布的文章

Q: 我经常在 Linux 桌面查看天气预报。然而,是否有一种在终端环境下,不通过桌面小插件或者浏览器查询天气预报的方法?

对于 Linux 桌面用户来说,有很多办法获取天气预报,比如使用专门的天气应用、桌面小插件,或者面板小程序。但是如果你的工作环境是基于终端的,这里也有一些在命令行下获取天气的手段。

其中有一个就是 wego一个终端下的小巧程序。使用基于 ncurses 的接口,这个命令行程序允许你查看当前的天气情况和之后的预报。它也会通过一个天气预报的 API 收集接下来 5 天的天气预报。

在 Linux 下安装 wego

安装 wego 相当简单。wego 是用 Go 编写的,引起第一个步骤就是安装 Go 语言。然后再安装 wego。

$ go get github.com/schachmat/wego

wego 会被安装到 $GOPATH/bin,所以要将 $GOPATH/bin 添加到 $PATH 环境变量。

$ echo 'export PATH="$PATH:$GOPATH/bin"' >> ~/.bashrc
$ source ~/.bashrc

现在就可与直接从命令行启动 wego 了。

$ wego

第一次运行 weg 会生成一个配置文件(~/.wegorc),你需要指定一个天气 API key。 你可以从 worldweatheronline.com 获取一个免费的 API key。免费注册和使用。你只需要提供一个有效的邮箱地址。

你的 .wegorc 配置文件看起来会这样:

除了 API key,你还可以把你想要查询天气的地方、使用的城市/国家名称、语言配置在 ~/.wegorc 中。 注意,这个天气 API 的使用有限制:每秒最多 5 次查询,每天最多 250 次查询。 当你重新执行 wego 命令,你将会看到最新的天气预报(当然是你的指定地方),如题图显示。

显示出来的天气信息包括:(1)温度,(2)风速和风向,(3)可视距离,(4)降水量和降水概率 默认情况下会显示3 天的天气预报。如果要进行修改,可以通过参数改变天气范围(最多5天),比如要查看 5 天的天气预报:

$ wego 5

如果你想检查另一个地方的天气,只需要提供城市名即可:

$ wego Seattle

问题解决

  1. 可能会遇到下面的错误:
user: Current not implemented on linux/amd64

当你在一个不支持原生 Go 编译器的环境下运行 wego 时就会出现这个错误。在这种情况下你只需要使用 gccgo ——一个 Go 的编译器前端来编译程序即可。这一步可以通过下面的命令完成。

$ sudo yum install gcc-go
$ go get -compiler=gccgo github.com/schachmat/wego

via: http://ask.xmodulo.com/weather-forecasts-command-line-linux.html

作者:Dan Nanni 译者:oska874 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

问题:我有个 Linux 进程运行在多核处理器系统上。怎样才能找出哪个 CPU 内核正在运行该进程?

当你在 多核 NUMA 处理器上运行需要较高性能的 HPC(高性能计算)程序或非常消耗网络资源的程序时,CPU/memory 的亲和力是限度其发挥最大性能的重要因素之一。在同一 NUMA 节点上调度最相关的进程可以减少缓慢的远程内存访问。像英特尔 Sandy Bridge 处理器,该处理器有一个集成的 PCIe 控制器,你可以在同一 NUMA 节点上调度网络 I/O 负载(如网卡)来突破 PCI 到 CPU 亲和力限制。

作为性能优化和故障排除的一部分,你可能想知道特定的进程被调度到哪个 CPU 内核(或 NUMA 节点)上运行。

这里有几种方法可以 找出哪个 CPU 内核被调度来运行给定的 Linux 进程或线程

方法一

如果一个进程使用 taskset 命令明确的被固定(pinned)到 CPU 的特定内核上,你可以使用 taskset 命令找出被固定的 CPU 内核:

$ taskset -c -p <pid>

例如, 如果你对 PID 5357 这个进程有兴趣:

$ taskset -c -p 5357  
pid 5357's current affinity list: 5

输出显示这个过程被固定在 CPU 内核 5上。

但是,如果你没有明确固定进程到任何 CPU 内核,你会得到类似下面的亲和力列表。

pid 5357's current affinity list: 0-11

输出表明该进程可能会被安排在从0到11中的任何一个 CPU 内核。在这种情况下,taskset 不能识别该进程当前被分配给哪个 CPU 内核,你应该使用如下所述的方法。

方法二

ps 命令可以告诉你每个进程/线程目前分配到的 (在“PSR”列)CPU ID。

$ ps -o pid,psr,comm -p <pid>  
  PID PSR COMMAND  
 5357  10 prog

输出表示进程的 PID 为 5357(名为"prog")目前在CPU 内核 10 上运行着。如果该过程没有被固定,PSR 列会根据内核可能调度该进程到不同内核而改变显示。

方法三

top 命令也可以显示 CPU 被分配给哪个进程。首先,在top 命令中使用“P”选项。然后按“f”键,显示中会出现 "Last used CPU" 列。目前使用的 CPU 内核将出现在 “P”(或“PSR”)列下。

$ top -p 5357

相比于 ps 命令,使用 top 命令的好处是,你可以连续监视随着时间的改变, CPU 是如何分配的。

方法四

另一种来检查一个进程/线程当前使用的是哪个 CPU 内核的方法是使用 htop 命令

从命令行启动 htop。按 键,进入"Columns",在"Available Columns"下会添加 PROCESSOR。

每个进程当前使用的 CPU ID 将出现在“CPU”列中。

请注意,所有以前使用的命令 taskset,ps 和 top 分配CPU 内核的 IDs 为 0,1,2,...,N-1。然而,htop 分配 CPU 内核 IDs 从 1开始(直到 N)。


via: http://ask.xmodulo.com/cpu-core-process-is-running.html

作者:Dan Nanni 译者:strugglingyouth 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

提问:过去我已经在我的Ubuntu上升级了几次内核。现在我想要删除这些旧的内核镜像来节省我的磁盘空间。如何用最简单的方法删除Ubuntu上先前版本的内核?

在Ubuntu上,有几个方法来升级内核。在Ubuntu桌面中,软件更新允许你每天检查并更新到最新的内核上。在Ubuntu服务器上,最为重要的安全更新项目之一就是 unattended-upgrades 软件包会自动更新内核。然而,你也可以手动用apt-get或者aptitude命令来更新。

随着时间的流逝,持续的内核更新会在系统中积聚大量的不再使用的内核,浪费你的磁盘空间。每个内核镜像和其相关联的模块/头文件会占用200-400MB的磁盘空间,因此由不再使用的内核而浪费的磁盘空间会快速地增加。

GRUB管理器为每个旧内核都维护了一个GRUB入口,以备你想要使用它们。

作为磁盘清理的一部分,如果你不再使用这些,你可以考虑清理掉这些镜像。

如何清理旧内核镜像

在删除旧内核之前,记住最好留有2个最近的内核(最新的和上一个版本),以防主要的版本出错。现在就让我们看看如何在Ubuntu上清理旧内核。

在Ubuntu内核镜像包含了以下的包。

  • linux-image-: 内核镜像
  • linux-image-extra-: 额外的内核模块
  • linux-headers-: 内核头文件

首先检查系统中安装的内核镜像。

$ dpkg --list | grep linux-image
$ dpkg --list | grep linux-headers

在列出的内核镜像中,你可以移除一个特定的版本(比如3.19.0-15)。

$ sudo apt-get purge linux-image-3.19.0-15
$ sudo apt-get purge linux-headers-3.19.0-15

上面的命令会删除内核镜像和它相关联的内核模块和头文件。

注意如果你还没有升级内核那么删除旧内核会自动触发安装新内核。这样在删除旧内核之后,GRUB配置会自动升级来移除GRUB菜单中相关GRUB入口。

如果你有很多没用的内核,你可以用shell表达式来一次性地删除多个内核。注意这个括号表达式只在bash或者兼容的shell中才有效。

$ sudo apt-get purge linux-image-3.19.0-{18,20,21,25}
$ sudo apt-get purge linux-headers-3.19.0-{18,20,21,25}

上面的命令会删除4个内核镜像:3.19.0-18、3.19.0-20、3.19.0-21 和 3.19.0-25。

如果GRUB配置由于任何原因在删除旧内核后没有正确升级,你可以尝试手动用update-grub2命令来更新配置。

$ sudo update-grub2

现在就重启来验证GRUB菜单是否已经正确清理了。


via: http://ask.xmodulo.com/remove-kernel-images-ubuntu.html

作者:Dan Nanni 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

问题: 我正在运行一个程序,它在运行时会派生出多个线程。我想知道程序在运行时会有多少线程。在 Linux 中检查进程的线程数最简单的方法是什么?

如果你想看到 Linux 中每个进程的线程数,有以下几种方法可以做到这一点。

方法一: /proc

proc 伪文件系统,它驻留在 /proc 目录,这是最简单的方法来查看任何活动进程的线程数。 /proc 目录以可读文本文件形式输出,提供现有进程和系统硬件相关的信息如 CPU、中断、内存、磁盘等等.

$ cat /proc/<pid>/status

上面的命令将显示进程 的详细信息,包括过程状态(例如, sleeping, running),父进程 PID,UID,GID,使用的文件描述符的数量,以及上下文切换的数量。输出也包括进程创建的总线程数如下所示。

Threads: <N>

例如,检查 PID 20571进程的线程数:

$ cat /proc/20571/status

输出表明该进程有28个线程。

或者,你可以在 /proc//task 中简单的统计子目录的数量,如下所示。

$ ls /proc/<pid>/task | wc

这是因为,对于一个进程中创建的每个线程,在 /proc/<pid>/task 中会创建一个相应的目录,命名为其线程 ID。由此在 /proc/<pid>/task 中目录的总数表示在进程中线程的数目。

方法二: ps

如果你是功能强大的 ps 命令的忠实用户,这个命令也可以告诉你一个进程(用“H”选项)的线程数。下面的命令将输出进程的线程数。“h”选项需要放在前面。

$ ps hH p <pid> | wc -l

如果你想监视一个进程的不同线程消耗的硬件资源(CPU & memory),请参阅此教程


via: http://ask.xmodulo.com/number-of-threads-process-linux.html

作者:Dan Nanni 译者:strugglingyouth 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

问题: 当我试图在 Ubuntu 上的 Wireshark 中打开一个 pre-recorded 数据包转储时,它的界面突然死机,在我运行 Wireshark 的终端出现了下面的错误和警告。我该如何解决这个问题?
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GObject'
(wireshark:3480): GLib-GObject-CRITICAL **: g_object_set_qdata_full: assertion 'G_IS_OBJECT (object)' failed
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkRange'
(wireshark:3480): Gtk-CRITICAL **: gtk_range_get_adjustment: assertion 'GTK_IS_RANGE (range)' failed
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkOrientable'
(wireshark:3480): Gtk-CRITICAL **: gtk_orientable_get_orientation: assertion 'GTK_IS_ORIENTABLE (orientable)' failed
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkScrollbar'
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GtkWidget'
(wireshark:3480): GLib-GObject-WARNING **: invalid unclassed pointer in cast to 'GObject'
(wireshark:3480): GLib-GObject-CRITICAL **: g_object_get_qdata: assertion 'G_IS_OBJECT (object)' failed
(wireshark:3480): Gtk-CRITICAL **: gtk_widget_set_name: assertion 'GTK_IS_WIDGET (widget)' failed

Wireshark 是一个基于 GUI 的数据包捕获和嗅探工具。该工具被网络管理员普遍使用,网络安全工程师或开发人员对于各种任务的数据包级的网络分析是必需的,例如在网络故障,漏洞测试,应用程序调试,或逆向协议工程是必需的。 Wireshark 允许实时记录数据包,并通过便捷的图形用户界面浏览他们的协议首部和有效负荷。

这是 Wireshark 的 UI,尤其是在 Ubuntu 桌面下运行时,当你向上或向下滚动分组列表视图时,或开始加载一个 pre-recorded 包转储文件时,有时会挂起或冻结,并出现以下错误。

显然,这个错误是由 Wireshark 和叠加滚动条之间的一些不兼容造成的,在最新的 Ubuntu 桌面还没有被解决(例如,Ubuntu 15.04 的桌面)。

一种避免 Wireshark 的 UI 卡死的办法就是 暂时禁用叠加滚动条。在 Wireshark 上有两种方法来禁用叠加滚动条,这取决于你在桌面上如何启动 Wireshark 的。

命令行解决方法

叠加滚动条可以通过设置"LIBOVERLAY\_SCROLLBAR"环境变量为“0”来被禁止。

所以,如果你是在终端使用命令行启动 Wireshark 的,你可以在 Wireshark 中禁用叠加滚动条,如下所示。

打开你的 .bashrc 文件,并定义以下 alias。

alias wireshark="LIBOVERLAY_SCROLLBAR=0 /usr/bin/wireshark"

桌面启动解决方法

如果你是使用桌面启动器启动的 Wireshark,你可以编辑它的桌面启动器文件。

$ sudo vi /usr/share/applications/wireshark.desktop

查找以"Exec"开头的行,并如下更改。

Exec=env LIBOVERLAY_SCROLLBAR=0 wireshark %f

虽然这种解决方法可以在系统级帮助到所有桌面用户,但升级 Wireshark 后被覆盖就没用了。如果你想保留修改的 .desktop 文件,如下所示将它复制到你的主目录。

$ cp /usr/share/applications/wireshark.desktop ~/.local/share/applications/ 

via: http://ask.xmodulo.com/fix-wireshark-gui-freeze-linux-desktop.html

作者:Dan Nanni 译者:strugglingyouth 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

如果你是一个系统管理员,负责关键的 IT 基础设置或公司的服务,你将明白有效的沟通在日常任务中的重要性。假设你的线上存储服务器故障了。你希望团队所有人达成共识你好尽快的解决问题。当你忙来忙去时,你不会想一半的人问你为什么他们不能访问他们的文档。当一个维护计划快到时间了你想在计划前提醒相关人员,这样避免了不必要的开销。

这一切的要求或多或少改进了你、你的团队、和你服务的用户之间沟通渠道。一个实现它的方法是维护一个集中的系统状态页面,报告和记录故障停机详情、进度更新和维护计划等。这样,在故障期间你避免了不必要的打扰,也可以提醒一些相关方,以及加入一些可选的状态更新。

有一个不错的开源, 自承载系统状态页解决方案叫做 Cachet。在这个教程,我将要描述如何用 Cachet 部署一个自承载系统状态页面。

Cachet 特性

在详细的配置 Cachet 之前,让我简单的介绍一下它的主要特性。

  • 全 JSON API:Cachet API 可以让你使用任意的外部程序或脚本(例如,uptime 脚本)连接到 Cachet 来自动报告突发事件或更新状态。
  • 认证:Cachet 支持基础认证和 JSON API 的 API 令牌,所以只有认证用户可以更新状态页面。
  • 衡量系统:这通常用来展现随着时间推移的自定义数据(例如,服务器负载或者响应时间)。
  • 通知:可选地,你可以给任一注册了状态页面的人发送突发事件的提示邮件。
  • 多语言:状态页被翻译为11种不同的语言。
  • 双因子认证:这允许你使用 Google 的双因子认证来提升 Cachet 管理账户的安全性。
  • 跨数据库支持:你可以选择 MySQL,SQLite,Redis,APC 和 PostgreSQL 作为后端存储。

剩下的教程,我会说明如何在 Linux 上安装配置 Cachet。

第一步:下载和安装 Cachet

Cachet 需要一个 web 服务器和一个后端数据库来运转。在这个教程中,我将使用 LAMP 架构。以下是一些特定发行版上安装 Cachet 和 LAMP 架构的指令。

Debian,Ubuntu 或者 Linux Mint

$ sudo apt-get install curl git apache2 mysql-server mysql-client php5 php5-mysql
$ sudo git clone https://github.com/cachethq/Cachet.git /var/www/cachet
$ cd /var/www/cachet
$ sudo git checkout v1.1.1
$ sudo chown -R www-data:www-data .

在基于 Debian 的系统上设置 LAMP 架构的更多细节,参考这个教程

Fedora, CentOS 或 RHEL

在基于 Red Hat 系统上,你首先需要设置 REMI 软件库(以满足 PHP 的版本需求)。然后执行下面命令。

$ sudo yum install curl git httpd mariadb-server
$ sudo yum --enablerepo=remi-php56 install php php-mysql php-mbstring
$ sudo git clone https://github.com/cachethq/Cachet.git /var/www/cachet
$ cd /var/www/cachet
$ sudo git checkout v1.1.1
$ sudo chown -R apache:apache .
$ sudo firewall-cmd --permanent --zone=public --add-service=http
$ sudo firewall-cmd --reload
$ sudo systemctl enable httpd.service; sudo systemctl start httpd.service
$ sudo systemctl enable mariadb.service; sudo systemctl start mariadb.service

在基于 Red Hat 系统上设置 LAMP 的更多细节,参考这个教程

配置 Cachet 的后端数据库

下一步是配置后端数据库。

登录到 MySQL/MariaDB 服务,然后创建一个空的数据库称为‘cachet’。

$ sudo mysql -uroot -p
mysql> create database cachet;
mysql> quit

现在用一个示例配置文件创建一个 Cachet 配置文件。

$ cd /var/www/cachet
$ sudo mv .env.example .env

在 .env 文件里,填写你自己设置的数据库信息(例如,DB\_*)。其他的字段先不改变。

APP_ENV=production
APP_DEBUG=false
APP_URL=http://localhost
APP_KEY=SomeRandomString

DB_DRIVER=mysql
DB_HOST=localhost
DB_DATABASE=cachet
DB_USERNAME=root
DB_PASSWORD=<root-password>

CACHE_DRIVER=apc
SESSION_DRIVER=apc
QUEUE_DRIVER=database

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ADDRESS=null
MAIL_NAME=null

REDIS_HOST=null
REDIS_DATABASE=null
REDIS_PORT=null

第三步:安装 PHP 依赖和执行数据库迁移

下面,我们将要安装必要的PHP依赖包。我们会使用 composer 来安装。如果你的系统还没有安装 composer,先安装它:

$ curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer

现在开始用 composer 安装 PHP 依赖包。

$ cd /var/www/cachet
$ sudo composer install --no-dev -o

下面执行一次性的数据库迁移。这一步会在我们之前创建的数据库里面创建那些所需的表。

$ sudo php artisan migrate

假设在 /var/www/cachet/.env 的数据库配置无误,数据库迁移应该像下面显示一样成功完成。

下面,创建一个密钥,它将用来加密进入 Cachet 的数据。

$ sudo php artisan key:generate
$ sudo php artisan config:cache

生成的应用密钥将自动添加到你的 .env 文件 APP\_KEY 变量中。你不需要自己编辑 .env。

第四步:配置 Apache HTTP 服务

现在到了配置运行 Cachet 的 web 服务的时候了。我们使用 Apache HTTP 服务器,为 Cachet 创建一个新的虚拟主机,如下:

Debian,Ubuntu 或 Linux Mint

$ sudo vi /etc/apache2/sites-available/cachet.conf
<VirtualHost *:80>
    ServerName cachethost
    ServerAlias cachethost
    DocumentRoot "/var/www/cachet/public"
    <Directory "/var/www/cachet/public">
        Require all granted
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

启用新虚拟主机和 mod\_rewrite:

$ sudo a2ensite cachet.conf
$ sudo a2enmod rewrite
$ sudo service apache2 restart

Fedora, CentOS 或 RHEL

在基于 Red Hat 系统上,创建一个虚拟主机文件,如下:

$ sudo vi /etc/httpd/conf.d/cachet.conf
<VirtualHost *:80>
    ServerName cachethost
    ServerAlias cachethost
    DocumentRoot "/var/www/cachet/public"
    <Directory "/var/www/cachet/public">
        Require all granted
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

现在重载 Apache 配置:

$ sudo systemctl reload httpd.service

第五步:配置 /etc/hosts 来测试 Cachet

这时候,初始的 Cachet 状态页面应该启动运行了,现在测试一下。

由于 Cachet 被配置为Apache HTTP 服务的虚拟主机,我们需要调整你的客户机的 /etc/hosts 来访问他。你将从这个客户端电脑访问 Cachet 页面。(LCTT 译注:如果你给了这个页面一个正式的主机地址,则不需要这一步。)

打开 /etc/hosts,加入如下行:

$ sudo vi /etc/hosts
<cachet 服务器的 IP 地址>    cachethost

上面名为“cachethost”必须匹配 Cachet 的 Apache 虚拟主机文件的 ServerName。

测试 Cachet 状态页面

现在你准备好访问 Cachet 状态页面。在你浏览器地址栏输入 http://cachethost。你将被转到如下的 Cachet 状态页的初始化设置页面。

选择 cache/session 驱动。这里 cache 和 session 驱动两个都选“File”。

下一步,输入关于状态页面的基本信息(例如,站点名称、域名、时区和语言),以及管理员认证账户。

你的状态页初始化就要完成了。

继续创建组件(你的系统单元)、事件或者任意你要做的维护计划。

例如,增加一个组件:

增加一个维护计划:

公共 Cachet 状态页就像这样:

集成了 SMTP,你可以在状态更新时发送邮件给订阅者。并且你可以使用 CSS 和 markdown 格式来完全自定义布局和状态页面。

结论

Cachet 是一个相当易于使用,自托管的状态页面软件。Cachet 一个高级特性是支持全 JSON API。使用它的 RESTful API,Cachet 可以轻松连接单独的监控后端(例如,Nagios),然后回馈给 Cachet 事件报告并自动更新状态。比起手工管理一个状态页它更快和有效率。

最后一句,我喜欢提及一个事。用 Cachet 设置一个漂亮的状态页面是很简单的,但要将这个软件用好并不像安装它那么容易。你需要完全保障所有 IT 团队习惯准确及时的更新状态页,从而建立公共信息的准确性。同时,你需要教用户去查看状态页面。最后,如果没有很好的填充数据,部署状态页面就没有意义,并且/或者没有一个人查看它。记住这个,尤其是当你考虑在你的工作环境中部署 Cachet 时。

故障排查

补充,万一你安装 Cachet 时遇到问题,这有一些有用的故障排查的技巧。

  1. Cachet 页面没有加载任何东西,并且你看到如下报错。
production.ERROR: exception 'RuntimeException' with message 'No supported encrypter found. The cipher and / or key length are invalid.' in /var/www/cachet/bootstrap/cache/compiled.php:6695

解决方案:确保你创建了一个应用密钥,以及明确配置缓存如下所述。

$ cd /path/to/cachet
$ sudo php artisan key:generate
$ sudo php artisan config:cache
  1. 调用 composer 命令时有如下报错。
- danielstjules/stringy 1.10.0 requires ext-mbstring * -the requested PHP extension mbstring is missing from your system.
- laravel/framework v5.1.8 requires ext-mbstring * -the requested PHP extension mbstring is missing from your system.
- league/commonmark 0.10.0 requires ext-mbstring * -the requested PHP extension mbstring is missing from your system.

解决方案:确保在你的系统上安装了必要的 PHP 扩展 mbstring ,并且兼容你的 PHP 版本。在基于 Red Hat 的系统上,由于我们从 REMI-56 库安装PHP,所以要从同一个库安装扩展。

$ sudo yum --enablerepo=remi-php56 install php-mbstring
  1. 你访问 Cachet 状态页面时得到一个白屏。HTTP 日志显示如下错误。
PHP Fatal error:  Uncaught exception 'UnexpectedValueException' with message 'The stream or file "/var/www/cachet/storage/logs/laravel-2015-08-21.log" could not be opened: failed to open stream: Permission denied' in /var/www/cachet/bootstrap/cache/compiled.php:12851

解决方案:尝试如下命令。

$ cd /var/www/cachet
$ sudo php artisan cache:clear
$ sudo chmod -R 777 storage
$ sudo composer dump-autoload

如果上面的方法不起作用,试试禁止 SELinux:

$ sudo setenforce 0 

via: http://xmodulo.com/setup-system-status-page.html

作者:Dan Nanni 译者:wyangsun 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出