Shared posts

11 Jul 03:23

分享 | 最佳开源电子邮件服务器

by linux@linux.cn (linux)

这是一份可以用于发送/接收电子邮件并存储邮件的开源邮件服务器列表。

无论你使用何种 电子邮件客户端,使用像 Gmail、Proton Mail 和 Outlook 这样的电子邮件服务非常方便。

为了实现这一切,你利用的是它们的邮件服务器进行电子邮件传输。因此,你的电子邮件的安全性、可靠性和隐私性取决于他人。

但是,如果你希望拥有自己的电子邮件基础设施并控制数据,那么你需要一个开源电子邮件服务器来解决这个问题。

让我解释得更清楚一些,电子邮件服务器可以让你:

  • 构建自己的邮件后端以存储电子邮件帐户
  • 通过自托管来掌控安全性和可靠性
  • 在你首选的服务器架构上进行托管
  • 让你能够创建无限数量的帐户

当然,这些并不适用于终端用户。中小型企业的系统管理员和自托管者才能用得上这些软件。

考虑到你现在对开源电子邮件服务器的好处有了一定了解,下面是一些你可以找到的最佳选项:

📋 这个列表包括邮件服务器和一些能够构建/创建邮件服务器的解决方案。其中一些可能提供托管服务,而另一些可以进行自托管。

1、Postal

Postal 是一个功能丰富的邮件服务器,可供网站和服务器使用。它专为出站邮件而设计,没有邮箱管理功能。(LCTT 译注:出站邮件指外发邮件,入站邮件指接收邮件供邮件客户端收取。)

它的 文档 对于入门非常有帮助。你可以使用 Docker 在服务器上配置 Postal。

使用 Postal,你可以为多个组织创建邮件服务器/用户,访问出站/入站消息队列,实时的递交信息,并使用内置功能确保电子邮件能够传递。

主要亮点:

  • 实时的递交信息
  • 点击和打开追踪
  • 专为出站邮件设计

🚧 维护和配置你的电子邮件服务器并非易事。只有在全面了解可靠地发送/接收电子邮件所需的一切情况下,才应继续设置邮件服务器。

2、mailcow

mailcow 用户界面

mailcow 是一个邮件服务器套件,其中包含帮助你构建 Web 服务器、管理邮箱等工具。

如果你不打算发送交易性电子邮件,mailcow 可以助你一臂之力。你可以将其视为一个团队协作工具。

(LCTT 译注:交易性电子邮件是指促进商业交易或关系的电子邮件,或提供关于正在进行的商业交易的最新信息。常见的例子包括: 订单确认、通知电子邮件等,例如,运输确认和更新,或订单退款。)

与其他邮件服务器一样,它与 Docker 搭配使用,每个容器是一个应用程序,它们之间相互连接。

mailcow 的 Web 用户界面可让你在一个地方完成所有操作。你可以在其 GitHub 页面 或 文档 中了解更多关于该项目的信息。

主要亮点:

  • 易于管理和更新
  • 可提供经济实惠的付费支持
  • 如果需要,可以与其他邮件服务器配合使用

3、Cuttlefish

Cuttlefish

想要一个简单的交易性邮件服务器吗?Cuttlefish 是一个简单易用的开源邮件服务器。

你可以通过简单的 Web 用户界面查看统计数据,监控出站邮件。

与一些完整的电子邮件服务(如 SendGrid 或 Mailgun)相比,Cuttlefish 在功能方面可能没有那么全面,它目前仍处于测试阶段(beta)。如果你需要超级简单且可靠的解决方案,可以选择它。

在其 GitHub 页面 上了解更多信息。

主要亮点:

  • 简单的交易性邮件服务器
  • 简单易用

4、Apache James

Apache James

James 是 “Java Apache Mail Enterprise Server” 的缩写。

顾名思义,James 是一个使用 Java 构建的面向企业的开源邮件服务器。根据需求,你可以将该邮件服务器用作 SMTP 中继或 IMAP 服务器。

与其他邮件服务器相比,James 可能不是最容易配置或安装的。但是,你可以查看其 文档 或 GitHub 页面 来自行评判。

主要亮点:

  • 配置完成后易于管理
  • 可靠,并被开源企业使用
  • 分布式服务器

5、Haraka

Haraka 是一个使用 Node.js 构建的现代开源 SMTP 服务器。如果你可以为你的业务/网站构建它,你就不需要寻找其他 SMTP 服务

这个邮件服务器专为提供最佳性能而设计。Haraka 的一个亮点是,它具有模块化插件系统,允许程序员根据需要更改服务器的行为。

你可以将其视为一款出色的可扩展的出站邮件递交服务器。一些知名的网站如 Craigslist 和 DuckDuckGo Email Protection 就使用了 Haraka。

在其 GitHub 页面 上可以了解更多信息。

主要亮点:

  • 使用 Node.js 构建
  • 插件系统以扩展功能

6、Modoboa

Modoboa 是一个多合一的开源解决方案。

它可以帮助你构建邮件服务器,并为你管理电子邮件帐户。你可以创建日历,无限制添加域名,创建过滤规则和访问 Webmail。如果你希望获得专业帮助来设置和管理系统,Modoboa 还提供付费维护选项。

除了是一个多功能解决方案外,它还提供了一种快速入门的方式来构建你的电子邮件基础架构。

主要亮点:

  • 全能选项
  • 提供付费帮助
  • 内置监控功能

7、Postfix

Postfix 是一种 邮件传输代理Mail Transfer Agent(MTA)。它本身可能不是一个独立的服务器,但它可以与其他一些解决方案配合使用来构建电子邮件服务器。

虽然 mailcow 包含了 Postfix(你可以将其配置与类似的解决方案一起使用),但你也可以根据你的使用情况选择单独使用它。在 Ubuntu 服务器中,Postfix 也是默认的邮件传输代理。

Postfix 可以用作外部 SMTP。不要忘记,你还可以设置 Postfix 与 Gmail 配合使用。Postfix 容易配置,并且其文档对于使用它非常有用。

主要亮点:

  • 易于配置
  • 灵活

8、Maddy

Maddy 是一个轻量级邮件服务器实现的不错选择。官方描述称它是一款“可组合的一体化邮件服务器”。

与 mailcow 相比较,你会发现 Maddy 提供了一些与 mailcow 相同的功能,也就是说它不仅仅局限于出站邮件等功能。

Maddy 在使用场景上非常受欢迎,它可以用单一实现替代多个选项,如 Postfix。你可以通过 SMTP 和 IMAP 使用 Maddy 进行发送、接收和存储消息。文章撰写时,存储功能仍处于测试阶段(beta)。

主要亮点:

  • 轻量级
  • 替代多种用例,比如 Postfix 等选项
  • 不依赖 Docker

9、Dovecot

Dovecot 是一个开源的 IMAP 服务器,作为 邮件传递代理Mail Delivery Agent(MDA)发挥作用。它可以与 Postfix 一起工作,因为它们执行不同的任务。

与其他解决方案相比,Dovecot 提供了易于管理、可靠的电子邮件发送功能和自我修复能力。

对于大型基础设施,Dovecot 提供了专业支持的高级方案。

主要亮点:

  • 易于管理
  • 自我修复能力
  • 专注于性能

10、Poste.io

Poste.io 邮件服务器

Poste.io 使用了邮件服务器解决方案,如 Haraku、Dovecot 和其他开源组件。从垃圾邮件过滤工具到防病毒引擎,应有尽有。

如果你想使用其中一些组件设置一个开源邮件服务器,并能够轻松管理和保护系统,Poste.io 是一个很好的选择。

主要亮点:

  • 使用多个开源邮件服务器组件进行易管理和构建
  • 管理面板界面

11、iRedMail

iRedMail 类似于 mailcow,它帮助你使用各种开源组件构建邮件服务器。你还可以使用创建的邮件服务器管理你的日历。

尽管你可以自行设置,但如果需要,它也提供付费的专业支持。

你将获得一个 Web 面板,在支持的 Linux 发行版上进行托管,并能够创建无限数量的账户。

主要亮点:

  • 简单易用
  • Web 面板进行易管理

12、Mailu

Mailu 邮件服务器

Mailu 是一个基于 Docker 的邮件服务器,可以为你提供最好的服务,同时限制了一些功能。

这并不意味着它不好;Mailu 的目标是专注于必要功能,而不添加对大多数人无用的许多功能。即便如此,它仍然通过添加 ARM 支持、Kubernetes 支持和其他一些功能而脱颖而出。

你将获得一个标准的邮件服务器、高级电子邮件功能、Web 管理界面和注重隐私的功能。

主要亮点:

  • 简单的界面
  • 关注于功能而不是花俏的解决方案
  • ARM 支持

准备构建和管理你的邮件服务器了吗?

使用开源工具和邮件服务器,你可以掌握你的数据,并为你的业务或网站管理/优化电子邮件通信。

正如我所提到的,这需要很多工作。因此,如果你希望拥有定制化的体验并且有一个可以负责的团队,那么开源自托管的邮件服务器是可行的选择。

💬 当然,还有很多其他选项可供选择,比如 mail in a box,可以帮助你快速部署邮件服务器。

在这里,我们尝试为你挑选最佳选择以供参考。你最喜欢的开源邮件服务器是什么?

(题图:MJ/f85c5c41-a598-4382-8821-73c701fc842b)


via: https://itsfoss.com/open-source-email-servers/

作者:Ankush Das 选题:lkxed 译者:ChatGPT 校对:wxy

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

05 Jun 11:29

观点 | “联邦宇宙”的 5 分钟之旅

by linux@linux.cn (linux)

一个快闪式的游览,介绍所有连接在一起形成开源社交网络世界的网站。

人们希望在互联网上像在现实生活中一样轻松地进行交流,并享有类似的保护,但可能具有更广泛的影响力。换句话说,人们希望能够与不在同一地理位置的一群人聊天,并仍然对谁拥有对话内容进行一定程度的控制。在当今世界,很多公司对你通过互联网发送和接收的数据拥有很多权利。大多数公司似乎认为他们有权管理你的通讯方式、你的信息覆盖范围等等。幸运的是,开源并不需要拥有你的社交生活,因此开源社交网络的开发者正在推出一款首先属于你的社交网络。

“Fediverse”(“联邦”和“宇宙”合成的词,译为“联邦宇宙”)是一组协议、服务器和用户,这些组成了可以相互通信的网络。用户可以通过这些网络交换短消息、博客文章、音乐和视频。你发布的内容是联邦式的,这意味着一旦一个网络知道了你的内容,它就可以将该内容传递给另一个网络,然后再传递给另一个网络,以此类推。

大多数平台由单个公司或组织运行,是一个唯一的数据封闭系统。与其他人分享内容的唯一方法是要求他们加入该服务。

联邦允许不同服务的用户互动,而无需为每个需要共享的资源创建一个帐户。

每个服务实例的管理员可以在存在严重问题的情况下阻止其他实例。用户也可以阻止其他用户或整个实例,以改善自己的体验。

联邦宇宙平台的例子

最近受到了很多关注的联邦宇宙平台是 Mastodon,它专注于微博客(类似于 Twitter)。然而 Mastodon 只是联邦宇宙的一个组成部分。还有更多:

  • 微博客:Mastodon、Pleroma、Misskey
  • 博客:Write.asRead.as
  • 视频托管:Peertube
  • 音频托管:Funkwhale
  • 图像托管:Pixelfed
  • 链接聚合器:Lemmy
  • 活动规划:mobilizon、gettogether.community

联邦宇宙的历史

在 2008 年,Evan Prodromou 创建了一个微博客服务,名为 identi.ca,采用了 Ostatus 协议和 status.net 服务器软件。几年后,他更改了服务协议,采用了一种名为 pump.io 的新协议。他将 Ostatus 协议发布给自由软件基金会,并导入了 GNU/social。以这种方式,联邦宇宙持续了几年。

2016 年 3 月,Eugen Rochco(Gargron)创建了 Mastodon,它使用 GNU/social,并采用了类似于流行的 Twitter 接口 Tweetdeck 的界面。这使得 Mastodon 得到一定的流行度。

联邦宇宙包括 Pixelfed、Mastodon、Misskey、Plume、Nextcloud、Castopod、Bookwyrm 等等

2018 年,一种名为 ActivityPub 的新协议被 W3C 接受为标准化协议。大多数联邦宇宙平台都采用了它。它由 Evan Prodromou、Christine Lemmer-Weber 和其他人编写,并扩展了之前的服务,提供了更好和更灵活的协议。

联邦宇宙看起来像什么?

联邦宇宙由使用 ActivityPub 协议的任何应用程序组成,因此其外观非常多样化。你可以想象,微博客平台与视频共享服务有不同的要求。

然而,进入这个伟大而未知的领域可能令人望而生畏。这里有一些我最喜欢的联合服务的屏幕截图:

Mastodon 网页客户端有简化视图和高级视图。默认的简化视图显示首页信息流的一个单列,右侧有更多选项。

Mastodon 网页客户端具有一个中央面板,用于显示你的定制网络中的活动

下面显示的高级 Web 界面有首页时间线、本地时间线、联邦时间线以及用户的个人资料。当用户第一次使用时,更易于使用的单列视图是默认的。

高级 Mastodon 界面有几列

Pixelfed 的界面专注于图像和视频的显示:

Pixelfed 的界面显示了照片的缩略图

Peertube 用于共享视频:

Peertube 的界面显示可以观看的视频缩略图

Mobilizon 是一个活动计划网站,计划与联邦宇宙集成:

Mobilizon 界面可帮助你计划活动

切换到开源社交网络

准备好开始了吗?请查看 fediverse.info ,了解有关联邦宇宙的视频解释和基于主题的方式来查找(自选的)其他用户。

请查看 fedi.tips ,获取有关如何入门、如何迁移数据和更多信息的详细指南。

Mastodon 有几个入口:

  • joinmastodon.org:Mastodon 服务器的最大列表。
  • joinfediverse.wiki:有关不同联邦宇宙服务和实例的详细信息。
  • fedi.garden:良好策划的实例列表。

如果你需要帮助决定加入哪个实例(假设你还不想自己搭建服务器),请访问 fediverse.party/en/portal/servers。

你是数据迷吗?请访问 the-federation.info 了解有关已知联邦宇宙的统计数据、监控服务以及基于数据的观察。

成为联邦一份子

联邦宇宙是使用社交媒体的一种个性化方式,可以选择一个满足你需求的群体的实例或运行自己的服务器,并使它成为你想要的样子。它避免了广告、算法和其他困扰许多社交网络的令人不愉快的问题。

如果你正在寻找比大型封闭服务更适合你需求的社区,不妨看看 Mastodon 和联邦宇宙,它们也许很适合你。成为联邦一份子吧!

你可以在联邦宇宙上找到我,用户名为 @murph@hackers.town

(题图:MJ/65de601a-4c04-4fe7-a0b7-26076e29f512)


via: https://opensource.com/article/23/3/tour-the-fediverse

作者:Bob Murphy 选题:lkxed 译者:ChatGPT 校对:wxy

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

22 May 07:10

技术 | 在 Ubuntu 上安装和使用 Qemu

by linux@linux.cn (linux)

学习如何在 Ubuntu 中正确安装 Qemu,然后在虚拟机中配置 Linux 发行版。

如果你需要运行 Linux 虚拟机,Qemu 是目前最快的管理程序之一,甚至没有“之一”。

除了速度之外,你还可以获得出色的配置选项。即使你不是一个资深用户,它也给你足够的调整空间。

在本教程中,我将引导你完成:

  • 在 Ubuntu 上安装 Qemu 和 KVM
  • 在 Qemu 上安装另一个发行版
  • 在 Qemu 中启用共享文件夹、自动调整大小和复制粘贴(可选,但会使你的虚拟机体验更顺畅)。

那么让我们从安装开始吧。

在 Ubuntu 上安装 Qemu 和 KVM

✋ 在开始安装之前,让我们检查一下你的机器是否支持虚拟化。

要做到这一点,请使用以下命令:

LC_ALL=C lscpu | grep Virtualization

如果你有一个英特尔处理器,它应该带来以下输出:

检查该计算机是否支持基于硬件的虚拟化

如果你有一个 AMD 处理器,它应该得到以下输出:

Virtualization:                  AMD-V

另外,确保你的系统有多个处理器核心,这样你可以分配一些给你的虚拟机,并且仍然有足够的处理能力提供给宿主机。

如果你不确定,使用下面的命令,输出应该大于零

egrep -c '(vmx|svm)' /proc/cpuinfo

检查 Linux 中系统的核心总数和线程数

一旦你都准备好了,你就可以用以下命令在 Ubuntu 上安装 Qemu 和 KVM:

sudo apt install qemu qemu-kvm virt-manager bridge-utils

安装结束后,重新启动你的系统

将用户添加到适当的组中

为了使 Qemu 工作,你必须 将你的用户加入两个组libvirt-kvm 和 libvirt

要做到这一点,请逐一使用以下命令:

sudo useradd -g $USER libvirt
sudo useradd -g $USER libvirt-kvm

接下来,启用并启动 libvirt 服务:

sudo systemctl enable libvirtd.service && sudo systemctl start libvirtd.service

这就行了!Qemu 的安装已经完成。

用 Qemu 安装另一个 Linux 虚拟机

📋 请下载你想在 Qemu 虚拟机中安装的 Linux 发行版的 ISO 文件。

首先,从系统菜单中打开 虚拟机管理器Virtual Machine Manager

从系统菜单中启动 Qemu

接下来,点击 “文件File” 菜单,选择 “新建虚拟机New Virtual Machine” 选项:

在 Qemu 中创建新的虚拟机

从这里,选择第一个选项 “本地安装介质Local install media”,这将允许你从文件管理器中选择 ISO:

选择本地 ISO 文件以在 Qemu 中创建新的虚拟机

接下来,你将被要求添加 ISO 文件。在这里,点击 “浏览Browse” 按钮;它将打开一个新的提示窗口,在那里,点击 “浏览本地Browse Local”。

它将打开文件管理器,从那里选择 ISO 文件:

在 Qemu 中导入 ISO 文件

在大多数情况下,ISO 文件会被检测到,但如果你发现它没有自动检测到,请按照以下步骤操作:

  • 取消勾选 “自动从安装介质/源检测Automatically detect from the installtion media / source” 选项
  • 选择 “常见的 LinuxGeneric Linux” 选项

解决 Qemu 中未检测到 ISO 的问题

接下来,你将被要求根据你的需要分配内存和存储。我建议桌面版至少要有 2 个核心、4GB 内存和 25GB 的存储空间:

在 Qemu 中为虚拟机分配内存、内核和存储空间

📋 除了磁盘空间,CPU 和内存等系统资源只在 VM 中运行操作系统时使用。

最后,给你的虚拟机起一个合适的名字;完成后,点击 “完成Finish” 按钮:

在 Qemu 中命名你的虚拟机

它将加载 ISO,所以你可以从这里开始安装。

这就完成了。你可能会觉得这已经很不错了,但如果你启用共享文件夹、剪贴板共享等,你会更喜欢它。下面的几节将介绍如何做到这一点。

在 Qemu 中启用共享文件夹(可选)

在本节中,我将向你展示如何将宿主机的现有目录与虚拟机共享。

要做到这一点,你必须执行以下步骤:

  • 通过 Qemu 中的虚拟机设置添加一个共享文件系统
  • 在虚拟机中挂载文件系统

因此,首先从系统菜单中打开虚拟机管理器,选择虚拟机,并点击 “打开Open” 按钮来管理控制台:

打开 Qemu 中虚拟机的设置

现在,点击 “信息Info” 按钮,选择 “内存Memory” 并启用共享内存:

在 Qemu 中启用共享内存

接下来,点击 “添加硬件Add Hardware” 按钮,选择 “文件系统Filesystem” 选项。

在这里,你必须做以下工作:

  • 在 “源路径Source Path” 部分添加一个你想共享的目录的路径
  • 在 “目标路径Target Path” 部分添加该目录的名称

在 Qemu 中创建共享文件夹

完成后,点击 “完成Finish” 按钮,启动虚拟机。

在虚拟机中,打开终端,使用下面的语法来挂载共享目录:

sudo mount -t virtiofs sharename path/to/shared/directory

在我的例子中,它是 Downloads 目录,所以我将使用下面的方式:

sudo mount -t virtiofs Downloads /home/sagar/Downloads

在 Qemu 中挂载共享文件夹

这就行了。

但这是一个临时的解决方案。

要使它成为永久性的,你必须在虚拟机的 /etc/fstab 中创建一个条目。

要这样做,首先,用下面的方法打开 /etc/fstab 配置文件:

sudo nano /etc/fstab

按下Alt + /在 nano 文本编辑器中转到文件的末尾 ,并使用以下语法创建一个条目:

sharename path/to/shared/directory virtiofs defaults 0 0

这是我的配置,看起来像这样:

使 Qemu 中的共享文件夹永久化

一旦完成,保存更改并退出 nano 文本编辑器。

这里我展示了我是如何在主机上的 Downloads 目录下创建一个新文件,并且这些变化反映在我的虚拟机上:

在 Qemu 中使用共享文件夹

因此,现在你可以使用这个共享文件夹在主机和虚拟机之间传输文件,没有任何问题了!

在 Qemu 中启用共享剪贴板(可选)

要启用共享剪贴板,你所要做的就是在虚拟机中安装 spice-vdagent 工具。

因此,如果你的虚拟机是基于 Ubuntu/Debian 的,你可以使用以下方法:

sudo apt install spice-vdagent

对于基于 Arch 的发行版:

sudo pacman -S spice-vdagent

对于基于 Fedora 的发行版:

sudo yum install spice-vdagent

一旦你完成了安装,重启你的虚拟机,剪贴板应该可以如期工作了。

在 Qemu 中启用自动调整大小(可选)

自动调整大小的功能没什么,但当你调整虚拟机窗口的大小时,虚拟机的显示会立即适应大小的变化:

Qemu 中的自动调整大小

要启用 Qemu 中的自动调整大小功能,你必须遵循 2 个简单的步骤:

  • 点击 “视图View”(从顶部菜单栏)。
  • 选择 “缩放显示Scale Display” 并选择 “总是Always” 选项。

这就是我这边看到的情况了。

想要使用 Qemu 的即插即用版本?

在本教程中,我介绍了如何在 Qemu 中手动安装虚拟机,但如果我告诉你,你可以自动完成整个过程,如分配存储空间、内存等步骤呢?

是的,它提供了同样的效率,但当你想尽快创建一个新的虚拟机时,它就会派上用场!这个工具叫 Quickgui,我们有一个专门的安装教程:

用基于 Qemu 的 Quickgui 轻松地创建虚拟机

我希望你会发现这个指南对你有帮助。如果你有任何疑问,欢迎在评论中提问。

(题图:MJ/b3c4d5b2-e727-4b70-9bb8-e864941eef9a)


via: https://itsfoss.com/qemu-ubuntu/

作者:Sagar Sharma 选题:lkxed 译者:wxy 校对:wxy

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

21 May 08:08

技术 | 如何入门 Linux Shell 脚本编写

by linux@linux.cn (linux)

各位读者,我们将在本文中介绍如何在 Linux 或 UNIX 系统中入门 Shell 脚本编写。

什么是 Shell 呢?

Shell(交互界面)是类 UNIX/Linux 操作系统中的一个解释器。它将用户输入的命令解释成操作系统的系统调用来执行这些命令。简单来说,Shell 形式上是操作系统的包装。比如,你可能使用 Shell 命令来列出目录中的文件,如 ls 命令,或使用命令复制,如 cp 命令。

$ ls
Desktop Documents Downloads Music Pictures playbook.yaml Public snap Templates test5 Videos

在上方的例子中,当你输入 ls 并按下回车键。$ 符号是 Shell 的提示符,意味着 Shell 等着命令的输入。下面的一行就是当前目录下的文件名。

什么是 Shell 提示符?

提示符,即 $,被称作命令提示符,是由 Shell 发出的(LCTT 译注:这个概念,可能有误。请参看:https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Controlling-the-Prompt )。当提示符出现后(LCTT 译注:此处提示符并不特指 $ 符号),你就可以输入命令了。Shell 将会在你按下回车键后读取你的输入。它会通过查看你输入的第一个单词来确定你希望执行的命令。“单词”指的是一组连续的字符。空格和制表符作为分割单词的标志。

不同类型的 Shell

由于没有限制只能有一个 Shell,你可以按照自己的意愿来自由选择运行任何一种 Shell。这当然挺好的,但是在不清楚其它替代方案的情况下选择一种 Shell 没有多大益处。下面列出了一些 UNIx/Linux 下常见的 Shell。

Sh(Bourne Shell)

最初的 Unix Shell 通常被称作 Sh,是 Shell(或 Bourne Shell)的简写,以其作者 Steven Bourne 命名。它在几乎所有的类 UNIX 操作系统下都可以找到。基本的 Bourne Shell 仅支持相当有限的命令行编辑。你可以输入字符,使用退格键删除字符,还有就是按下回车键来执行命令。当命令行出现异常了,你可以按下 Ctrl-C 组合键来终止整个命令。

Csh(C Shell)

它是由加利福尼亚大学伯克利分校的 Bill Joy 设计的,由于它的语法和 C 语言相似,所以被命名为 C Shell。这种 Shell 在 Bourne shell 的基础上增加了一些实用功能,尤其是可以重用之前的命令来帮助创建之后要执行的命令。当你去完成一项专门任务的时候,大多数的情况下需要执行不止一条命令,这样 C shell 的能力就相当有用了。

Ksh(Korn Shell)

它是由贝尔实验室的 David Korn 创造的,Korn Shell 提供了和 C Shell 相同的增强,其中有一项重要的不同:Korn Shell 提供了对旧的 Bourne Shell 语法的向后兼容。在 Unix 下,如 AIX & HP-UX 上,Korn Shell 是默认 Shell。

Bash(Bourne Again Shell)

Bash 提供了像 Korn Shell 一样的命令行编辑,像 C Shell 一样的文件名补全和许多其它的高级功能。许多用户认为 Bash 集 Korn Shell 和 C Shell 的优点于一身。在 Linux 和 Mac OS X 系统下,Bash 是默认的 Shell。

Tcsh(T C Shell)

Linux 系统推广了 Tcsh。Tcsh 扩展了传统的 csh,增加了命令行编辑、文件名补全和其它功能。例如,当你按下 Tab 键后,Tcsh 会补全文件和目录名(与 Bash 中的按键相同)。旧的 C Shell 不支持这项功能。

什么是 Shell 脚本呢?

Shell 脚本是包含一条或多条命令的文本文件。在 Shell 脚本中,Shell 程序假定文本文件的每一行是一条不同的命令。这些命令的大部分就和你在 Shell 窗口手动输入的一样。

为什么要使用 Shell 脚本呢?

Shell 脚本被用来自动化管理任务、简化复杂的配置细节,并且充分运用操作系统的性能。有了组合不同命令的能力就可以创造新命令了,从而增加操作系统的价值。此外,结合使用 Shell 与图形化桌面环境,可以兼得二者之长。

从系统管理员的角度看,日复一日的重复工作可以使用 Shell 脚本来实现自动处理,那就可以节约时间从事其它高质量的工作。

创建第一个 Shell 脚本

在当前工作目录下创建一个名为 myscript.sh 的文本文件,所有的 Shell 脚本都有 .sh 的扩展名(LCTT 译注:Linux 下根本没有扩展名一说,没有这个扩展一样是可以执行的)。脚本的第一行是 #!/bin/sh 或 #!/bin/bash,因为 # 符号被称作 “hash” 并且 ! 符号被称作 “bang” 故被称为 shebang(释伴)。至于 /bin/sh 和 /bin/bash 则指出了命令将被 Sh 还是 Bash shell 执行。

以下就是 myscript.sh 的内容:

#!/bin/bash
# Written by LinuxTechi
echo
echo "Current Working Directory: $(pwd)"
echo
echo "Today' Date & Time: $(date)"
DISK=$(df -Th)
echo
echo "Disk Space on System:"
echo "$DISK"

上方的脚本将会展示当前工作目录、今天的日期与时间,还有磁盘空间。我们需要用到 echo 命令 和其它 Linux 命令 来实现这个脚本。

使用如下的 chmod 命令 来给文件增加执行权限:

$ chmod a+x myscript.sh

现在来执行脚本:

$ sh myscript.sh
或
$ ./myscript.sh

注意:在当前目录下执行当前目录下的 Shell 脚本,须使用 ./<脚本名> 方式,如下所示:

在 Shell 脚本中获取用户输入

read 命令用来获取用户的键盘输入,并且将之赋值给一个变量。echo 命令用来展示内容。

让我们更改上方的脚本以使之获取输入:

#!/bin/bash
# Written by LinuxTechi
read -p "Your Name: " NAME
echo
echo "Today' Date & Time: $(date)"
echo
read -p "Enter the file system:" DISK
echo "$(df -Th $DISK)""

现在,再执行脚本试试,这回应该会有输入信息的提醒:

$ ./myscript.sh
Your Name: Pradeep Kumar

Today' Date & Time: Sat 15 Oct 05:32:38 BST 2022

Enter the file system:/mnt/data
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/volgrp01-lv01 ext4 14G 24K 13G 1% /mnt/data

完美,上方的输出表明脚本有输入提醒,并加工处理了相应的数据。

本文结束。希望对你是有用的。非常欢迎任何的疑问、反馈。

(题图:MJ/f83b771e-a70d-4c62-a169-ec42e9004a14)


via: https://www.linuxtechi.com/get-started-shell-scripting-linux/

作者:Pradeep Kumar 选题:lkxed 译者:cyberwaddle 校对:wxy

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

16 May 10:20

技术 | 为什么 0.1 + 0.2 = 0.30000000000000004?

by linux@linux.cn (linux)

嗨!昨天我试着写点关于浮点数的东西,我发现自己对这个 64 位浮点数的计算方法很好奇:

>>> 0.1 + 0.2
0.30000000000000004

我意识到我并没有完全理解它是如何计算的。我的意思是,我知道浮点计算是不精确的,你不能精确地用二进制表示 0.1,但是:肯定有一个浮点数比 0.30000000000000004 更接近 0.3!那为什么答案是 0.30000000000000004 呢?

如果你不想阅读一大堆计算过程,那么简短的答案是: 0.1000000000000000055511151231257827021181583404541015625 + 0.200000000000000011102230246251565404236316680908203125 正好位于两个浮点数之间,即 0.299999999999999988897769753748434595763683319091796875 (通常打印为 0.3) 和 0.3000000000000000444089209850062616169452667236328125(通常打印为 0.30000000000000004)。答案是 0.30000000000000004,因为它的尾数是偶数。

浮点加法是如何计算的

以下是浮点加法的简要计算原理:

  • 把它们精确的数字加在一起
  • 将结果四舍五入到最接近的浮点数

让我们用这些规则来计算 0.1 + 0.2。我昨天才刚了解浮点加法的计算原理,所以在这篇文章中我可能犯了一些错误,但最终我得到了期望的答案。

第一步:0.1 和 0.2 到底是多少

首先,让我们用 Python 计算 0.1 和 0.2 的 64 位浮点值。

>>> f"{0.1:.80f}"
'0.10000000000000000555111512312578270211815834045410156250000000000000000000000000'
>>> f"{0.2:.80f}"
'0.20000000000000001110223024625156540423631668090820312500000000000000000000000000'

这确实很精确:因为浮点数是二进制的,你也可以使用十进制来精确的表示。但有时你只是需要一大堆数字:)

第二步:相加

接下来,把它们加起来。我们可以将小数部分作为整数加起来得到确切的答案:

>>> 1000000000000000055511151231257827021181583404541015625 + 2000000000000000111022302462515654042363166809082031250
3000000000000000166533453693773481063544750213623046875

所以这两个浮点数的和是 0.3000000000000000166533453693773481063544750213623046875

但这并不是最终答案,因为它不是一个 64 位浮点数。

第三步:查找最接近的浮点数

现在,让我们看看接近 0.3 的浮点数。下面是最接近 0.3 的浮点数(它通常写为 0.3,尽管它不是确切值):

>>> f"{0.3:.80f}"
'0.29999999999999998889776975374843459576368331909179687500000000000000000000000000'

我们可以通过 struct.pack 将 0.3 序列化为 8 字节来计算出它之后的下一个浮点数,加上 1,然后使用 struct.unpack

>>> struct.pack("!d", 0.3)
b'?\xd3333333'
# 手动加 1
>>> next_float = struct.unpack("!d", b'?\xd3333334')[0]
>>> next_float
0.30000000000000004
>>> f"{next_float:.80f}"
'0.30000000000000004440892098500626161694526672363281250000000000000000000000000000'

当然,你也可以用 math.nextafter

>>> math.nextafter(0.3, math.inf)
0.30000000000000004

所以 0.3 附近的两个 64 位浮点数是 0.299999999999999988897769753748434595763683319091796875 和 0.3000000000000000444089209850062616169452667236328125

第四步:找出哪一个最接近

结果证明 0.3000000000000000166533453693773481063544750213623046875 正好在 0.299999999999999988897769753748434595763683319091796875 和 0.3000000000000000444089209850062616169452667236328125 的中间。

你可以通过以下计算看到:

>>> (3000000000000000444089209850062616169452667236328125000 + 2999999999999999888977697537484345957636833190917968750) // 2 == 3000000000000000166533453693773481063544750213623046875
True

所以它们都不是最接近的。

如何知道四舍五入到哪一个?

在浮点数的二进制表示中,有一个数字称为“尾数”。这种情况下(结果正好在两个连续的浮点数之间),它将四舍五入到偶数尾数的那个。

在本例中为 0.300000000000000044408920985006261616945266723632812500

我们之前就见到了这个数字的尾数:

  • 0.30000000000000004 是 struct.unpack('!d', b'?\xd3333334') 的结果
  • 0.3 是 struct.unpack('!d', b'?\xd3333333') 的结果

0.30000000000000004 的大端十六进制表示的最后一位数字是 4,它的尾数是偶数(因为尾数在末尾)。

我们用二进制来算一下

之前我们都是使用十进制来计算的,这样读起来更直观。但是计算机并不会使用十进制,而是用 2 进制,所以我想知道它是如何计算的。

我不认为本文的二进制计算部分特别清晰,但它写出来对我很有帮助。有很多数字,读起来可能很糟糕。

64 位浮点数如何计算:指数和尾数

64 位浮点数由 2 部分整数构成:指数尾数,还有 1 比特 符号位.

以下是指数和尾数对应于实际数字的方程:

例如,如果指数是 1,尾数是 2**51,符号位是正的,那么就可以得到:

它等于 2 * (1 + 0.5),即 3。

步骤 1:获取 0.1 和 0.2 的指数和尾数

我用 Python 编写了一些低效的函数来获取正浮点数的指数和尾数:

def get_exponent(f):
    # 获取前 52 个字节
    bytestring = struct.pack('!d', f)
    return int.from_bytes(bytestring, byteorder='big') >> 52

def get_significand(f):
    # 获取后 52 个字节
    bytestring = struct.pack('!d', f)
    x = int.from_bytes(bytestring, byteorder='big')
    exponent = get_exponent(f)
    return x ^ (exponent << 52)

我忽略了符号位(第一位),因为我们只需要处理 0.1 和 0.2,它们都是正数。

首先,让我们获取 0.1 的指数和尾数。我们需要减去 1023 来得到实际的指数,因为浮点运算就是这么计算的。

>>> get_exponent(0.1) - 1023
-4
>>> get_significand(0.1)
2702159776422298

它们根据 2**指数 + 尾数 / 2**(52 - 指数) 这个公式得到 0.1

下面是 Python 中的计算:

>>> 2**-4 + 2702159776422298 / 2**(52 + 4)
0.1

(你可能会担心这种计算的浮点精度问题,但在本例中,我很确定它没问题。因为根据定义,这些数字没有精度问题 -- 从 2**-4 开始的浮点数以 1/2**(52 + 4) 步长递增。)

0.2 也一样:

>>> get_exponent(0.2) - 1023
-3
>>> get_significand(0.2)
2702159776422298

它们共同工作得到 0.2:

>>> 2**-3 + 2702159776422298 / 2**(52 + 3)
0.2

(顺便说一下,0.1 和 0.2 具有相同的尾数并不是巧合 —— 因为 x 和 2*x 总是有相同的尾数。)

步骤 2:重新计算 0.1 以获得更大的指数

0.2 的指数比 0.1 大 -- -3 大于 -4。

所以我们需要重新计算:

2**-4 + 2702159776422298 / 2**(52 + 4)

等于 X / (2**52 + 3)

如果我们解出 2**-4 + 2702159776422298 / 2**(52 + 4) = X / (2**52 + 3),我们能得到:

X = 2**51 + 2702159776422298 /2

在 Python 中,我们很容易得到:

>>> 2**51 + 2702159776422298 //2
3602879701896397

步骤 3:添加符号位

现在我们试着做加法:

2**-3 + 2702159776422298 / 2**(52 + 3) + 3602879701896397 / 2**(52 + 3)

我们需要将 2702159776422298 和 3602879701896397 相加:

>>> 2702159776422298  + 3602879701896397
6305039478318695

棒。但是 6305039478318695 比 2**52-1(尾数的最大值)大,问题来了:

>>> 6305039478318695 > 2**52
True

第四步:增加指数

目前结果是:

2**-3 + 6305039478318695 / 2**(52 + 3)

首先,它减去 2**52:

2**-2 + 1801439850948199 / 2**(52 + 3)

完美,但最后的 2**(52 + 3) 需要改为 2**(52 + 2)

我们需要将 1801439850948199 除以 2。这就是难题的地方 -- 1801439850948199 是一个奇数!

>>> 1801439850948199  / 2
900719925474099.5

它正好在两个整数之间,所以我们四舍五入到最接近它的偶数(这是浮点运算规范要求的),所以最终的浮点结果是:

>>> 2**-2 + 900719925474100 / 2**(52 + 2)
0.30000000000000004

它就是我们预期的结果:

>>> 0.1 + 0.2
0.30000000000000004

在硬件中它可能并不是这样工作的

在硬件中做浮点数加法,以上操作方式可能并不完全一模一样(例如,它并不是求解 “X”),我相信有很多有效的技巧,但我认为思想是类似的。

打印浮点数是非常奇怪的

我们之前说过,浮点数 0.3 不等于 0.3。它实际上是:

>>> f"{0.3:.80f}"
'0.29999999999999998889776975374843459576368331909179687500000000000000000000000000'

但是当你打印它时,为什么会显示 0.3

计算机实际上并没有打印出数字的精确值,而是打印出了最短的十进制数 d,其中 f 是最接近 d 的浮点数。

事实证明,有效做到这一点很不简单,有很多关于它的学术论文,比如 快速且准确地打印浮点数如何准确打印浮点数 等。

如果计算机打印出浮点数的精确值,会不会更直观一些?

四舍五入到一个干净的十进制值很好,但在某种程度上,我觉得如果计算机只打印一个浮点数的精确值可能会更直观 -- 当你得到一个奇怪的结果时,它可能会让你看起来不那么惊讶。

对我来说,0.1000000000000000055511151231257827021181583404541015625 + 0.200000000000000011102230246251565404236316680908203125 = 0.3000000000000000444089209850062616169452667236328125 比 0.1 + 0.2 = 0.30000000000000000004 惊讶少一点。

这也许是一个坏主意,因为它肯定会占用大量的屏幕空间。

PHP 快速说明

有人在评论中指出在 PHP 中 <?php echo (0.1 + 0.2 );?> 会输出 0.3,这是否说明在 PHP 中浮点运算不一样?

非也 —— 我在 这里 运行:

<?php echo (0.1 + 0.2 )- 0.3);?>,得到了与 Python 完全相同的答案:5.5511151231258E-17。因此,浮点运算的基本原理是一样的。

我认为在 PHP 中 0.1 + 0.2 输出 0.3 的原因是 PHP 显示浮点数的算法没有 Python 精确 —— 即使这个数字不是最接近 0.3 的浮点数,它也会显示 0.3

总结

我有点怀疑是否有人能耐心完成以上所有些算术,但它写出来对我很有帮助,所以我还是发表了这篇文章,希望它能有所帮助。

(题图:MJ/53e9a241-14c6-4dc7-87d0-f9801cd2d7ab)


via: https://jvns.ca/blog/2023/02/08/why-does-0-1-plus-0-2-equal-0-30000000000000004/

作者:Julia Evans 选题:lkxed 译者:MjSeven 校对:wxy

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

05 Oct 04:56

使用Python将图片转化为ASCII字符图

by 钱魏Way

在一些TXT文件中我们经常能看到一些以字符呈现的图像。这一类的图像一般称为ASCII art。

使用Python可以非常方面的生成ASCII art。今天要做的是将以下《戴珍珠耳环的少女》图片转化为ASCII ART。

在转换之前我们先要了解下关于图片的原理。

  • 彩色图像中的单个像素可以表示成一个三元组,其中每个元素取值都介于0和255之间,分别表示红色,绿色和蓝色的值。这些值越高,表示相应通道的亮度越大。例如,白色像素的三元组表示为(255,255,2555)。
  • 灰度图又称灰阶图。 把白色与黑色之间按对数关系分为若干等级,称为灰度。 灰度分为256阶。 用灰度表示的图像称作灰度图。255代表全白,0表示全黑。

在将图片转化为ASCII前,首页需要做的是先将彩色图片转化为灰阶图。原因是ASCII字符不能显示颜色。

要将灰阶图转化为ASCII字符图的核心原理是将每个像素点的值转化成不同的字符。字符本身需要有一定的骨子额,比如下面的字符:

CHARACTERS = (' ', '.', '°', 'o', 'O', '*', '#', '@')

上面有八个字符,转化的时候实际上需要将灰阶的0-255转化为以上8个符号。即将接近黑色的点(0~32)转化为’@’字符,将接近白色的点(223~255)转化为’ ‘字符。这样就有了明暗交替的效果了。

以下为网上找到的关于ASCII阶度的字符列表。注意:列表使用时一定要按照从高到低或从低到高的顺序排序。

gscale1 = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~i!lI;:,\"^`". "    #70 levels of gray
gscale2 = "@%#*+=-:. "         #10 levels of gray

当然,除了使用英文字符,也可以使用中文字符。比如这次的demo我使用的是“戴珍珠耳环的少女”这几个字,然后我对这些字按照笔画的数量进行了简单的排序。

ASCII_CHARS = "戴珠珍环的耳女少"

整体转化的流程大体是这样,但在转化过程中还会存在一个问题,即将原来的一个像素点转化为一个文字,尺寸会相应的变大。是转化后的尺寸与原尺寸会产生差异。解决办法是重新设置字符的宽度。

整体代码如下:

from PIL import Image

# ASCII_CHARS = "@%#*+=-:. "
ASCII_CHARS = "戴珠珍环的耳女少"


def img2ascii(image_path, ascii_path, image_width=100):
    im = Image.open(image_path).convert('L')
    im.save('Gray-Scale-Image.jpg')
    width, height = im.size
    image_height = image_width * height // width
    im = im.resize((image_width, image_height))
    im.show()
    pixels = im.getdata()
    ascii_str = ""
    for pixel in pixels:
        ascii_str += ASCII_CHARS[len(ASCII_CHARS) * pixel // 256]
    ascii_str_len = len(ascii_str)

    ascii_img = ""
    for i in range(0, ascii_str_len, image_width):
        ascii_img += ascii_str[i:i + image_width] + "\n"

    with open(ascii_path, "w") as f:
        f.write(ascii_img)


if __name__ == "__main__":
    image_path = 'Meisje_met_de_parel.jpg'
    ascii_path = 'ascii_image.txt'
    image_width = 256
    img2ascii(image_path, ascii_path, image_width)

最终效果:

参考链接:

05 Aug 06:06

如何阻止社交网络上的傻子

by williamlone@gmail.com (williamlong)

  由于现在上网的门槛实在太低,导致社交网络上的傻子越来越多,据2020年第46次中国互联网络发展状况统计报告显示,受过大学本科以上教育的网民群体仅为8.8%,初中以下文化程度的网民占比高达60%。

  那么问题来了,正常用户在使用社交网络的时候,会发现一个问题,用户无法阻止傻子和自己互动,傻子制造的大量信息会破坏用户的网络使用体验,浪费用户的宝贵时间。

  我们知道,在日常生活中的社交很少会出现这种情况,那么,网络用户可以参考日常生活中的经验,在社交网络阻止傻子和自己互动。

  在日常生活中,如果有傻子和你互动,人们的主要应对方法是回避,没人愿意和傻子争论,那是毫无意义的事情。

  同样道理,在社交网络上,阻止傻子和自己互动的一个简单有效方法是屏蔽拉黑,我们的时间是宝贵的,我们的精力是有限的,不要浪费时间和傻子多说一句话,帮助和改造傻子是别人的事情,我们生活的目的是为了读万卷书、行万里路、提升自己、要多交志同道合的朋友,远离你身边格局小的人,才能让自己拥有更大的格局。

  不过,屏蔽拉黑需要手动操作,效率不高,不能快速地判断和分析目前互动的人是否是傻子,我们可以通过一些技巧来提升效率,例如:

  1、傻子的关注者通常也是傻子,判断出一个傻子,他的关注者可以一起屏蔽拉黑。

  2、分析一些热门的考验智商的投票或问题,从投票或点赞里筛选出哪些人是傻子,批量拉黑投票某个答案的人,或者拉黑给某个问题点赞同的人。

  此外,在日常生活中,我们不会去一些傻子们常去的场所,这样就避免和傻子同处一个地点的尴尬,同样道理,在社交网站上,少去一些傻子聚集的网站,也是一个躲避傻子的方法。

13 Jun 11:22

CentOS 7安装Docker记录

by 标点符

目前很多开源的工具与软件都可以使用Docker进行部署测试,比如先前写的使用Docker安装多用户版的JupyterHub

今天主要分享的是CentOS 7环境下安装Docker CE的过程,非常简单,具体流程如下:

# 卸载旧版本Docker
sudo yum remove docker docker-common docker-selinux docker-engine
# 安装依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# 添加国内 yum 软件源:
sudo yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo

# 安装Docker CE
sudo yum makecache fast
sudo yum install docker-ce

# 启动 Docker CE
sudo systemctl enable docker
sudo systemctl start docker

# 将当前用户加入 docker 组
sudo usermod -aG docker $USER

# 镜像加速
# sudo echo "DOCKER_OPTS=\"--registry-mirror=https://registry.docker-cn.com\"" >> /etc/default/docker  #更改为国内源
sudo nano /etc/docker/daemon.json
{
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}

# 重新启动服务
sudo systemctl daemon-reload
sudo systemctl restart docker

# 测试 Docker 是否安装正确
sudo docker run hello-world

# 安装 Docker-Compose
# 通过访问 https://github.com/docker/compose/releases/latest 得到最新的 docker-compose 版本
sudo curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose
sudo chmod +x /usr/bin/docker-compose

13 Jun 11:21

Python检验数据是否正态分布

by 标点符

判断数据是否符合正态分布,比如使用3-sigma判断数据异常前,首先需要确定的是数据是否符合正态分布。今天一起梳理下检测正态分布的方法。

Shapiro-Wilk test

Shapiro-Wilk test是一种在频率上统计检验中检验正态性的方法。该检验的零检验是样本$x_1,\cdots ,x_n$来自于一个正态分布的母体。这个检验的统计量是:

$$W = \frac{(\sum_{i=1}^{n}a_{i}x_{(i)})^2}{\sum_{i=1}^{n}(x_i-\bar{x})^2}$$

其中:

  • $x_{(i)}$用括号包含下标索引i的;不与x混淆,它是第i阶统计量,即样本中的第i个最小数
  • $\overline {x}=(x_{1}+\cdots +x_{n})/n$是样本的平均值。
  • 常量$a_i$通过公式$(a_1,\dots ,a_n)=\frac{m^{T}V^{-1}}{\sqrt{(m^{T}V^{-1}V^{-1}m)}}, m=(m_1,\dots ,m_n)^T$,其中$m_1,\dots ,m_n$是从一个标准的正态分布随机变量上采样的有序独立同分布的统计量的期望值。V是这些有序统计量的协方差。

这个统计检验的假设是样本来自于一个正态母体,因此,一方面,如果p值小于选择的显著度水平(通常0.05),那么在更大概率下我们应该拒绝零假设,数据的证据显示我们的样本不是来自一个正态分布母体。另一方面,如果p值比选择的显著度水平大,那么我们没有证据拒绝零假设,数据来自于一个正态分布。

Python代码:

import numpy as np
from scipy import stats
np.random.seed(0)
x = np.random.randn(1, 1000)
print(stats.shapiro(x[0]))
# (0.9985557794570923, 0.5914123058319092)
# 输出(统计量W的值,P值)
# W的值越接近1就越表明数据和正态分布拟合得越好,P值>指定水平, 不拒绝原假设,可以认为样本数据服从正态分布
# 不适合样本>5000的情况

参考链接:

Kolmogorov-Smirnov test

Kolmogorov-Smirnov是比较一个频率分布f(x)与理论分布g(x)或者两个观测值分布的检验方法。其原假设H0:两个数据分布一致或者数据符合理论分布。D=max|f(x)- g(x)|,当实际观测值D>D(n,α)则拒绝H0,否则接受H0假设。

KS检验与t-检验之类的其他方法不同是KS检验不需要知道数据的分布情况,可以算是一种非参数检验方法。当然这样方便的代价就是当检验的数据分布符合特定的分布时,KS检验的灵敏度没有相应的检验来的高。在样本量比较小的时候,KS检验最为非参数检验在分析两组数据之间是否不同时相当常用。

Kolmogorov检验找出在每一个数据点上经验累积概率与目标分布的累积概率之差的上界,列出公式是这样的:

$$D_n = \underset{x}{sup}|F_n(x)-F(x)|$$

其中sup函数表示一组距离中的上确界,这是个数学概念,表示在原假设$F_n(x)=F(x)$的条件下,$F_n(x)-F(x)$的绝对值的最小上界。$F_n(x),F(x)$分别代表经验的和理论的累积概率。其意图在于如果原假设成立,则$D_n$应该很小,如果很大,则原假设不成立。但是,这个上确界怎么求出来呢?请看下面的公式:

$$D_n = \underset{x}{sup}|F_n(x)-F(x)|=\underset{1\leq k\leq n}{max}\{|F_n(x_k)-F_0(x_k)|,|F_0(x_{k+1}-F_n(x_k)|\}$$

其中k为样本从小到大排列后的序数。从公式中看出$D_n$是经验和目标累积概率之差和错一位后再求出的差中最大的一个。Kolmogorov还给出了这个距离的分布函数,并给出了判断的临界值。当然现在的统计软件都直接计算p值,很少有人查表了。

Kolmogorov-Smirnov检验(K-S检验)基于累积分布函数,用以检验一个经验分布是否符合某种理论分布或比较两个经验分布是否有显著性差异。

两样本K-S检验由于对两样本的经验分布函数的位置和形状参数的差异都敏感而成为比较两样本的最有用且常规的非参数方法之一。

  • 优点:该检验不依赖于要测试的累积分布函数,相比于卡方拟合检验(卡方检验需要50个以上的样本),不需要大量的样本。
  • 缺点:只适用于连续分布;在分布中间敏感,在两端不够敏感;最大的局限在于整个分布需要完全确定,如果位置,形状等参数都是从数据中估计的,判定区间不再有效,因此这些参数一般只能通过模拟得到。

scipy.stats.kstest是一个很强大的检验模块,除了正态性检验,还能检验 scipy.stats 中的其他数据分布类型。

scipy.stats.kstest(rvs, cdf, args=(), N=20, alternative=’two-sided’, mode=’approx’)

  • rvs:待检验的数据
  • cdf:检验方法,这里我们设置为‘norm’,即正态性检验
  • args:分布参数,可选
  • N:样本数量
  • alternative:默认为双尾检验,可以设置为‘less’或‘greater’作单尾检验
  • mode:定义计算p-value的方式

使用示例:

import numpy as np
from scipy import stats

np.random.seed(0)
x = np.random.randn(1, 100)
print(stats.kstest(x[0], 'norm'))
# KstestResult(statistic=0.0582486387238324, pvalue=0.8865884365301941)

输出结果中第一个为统计量,第二个为P值(注:统计量越接近0就越表明数据和标准正态分布拟合的越好,如果P值大于显著性水平,通常是0.05,接受原假设,则判断样本的总体服从正态分布)

参考链接:

Anderson-Darling test

这个方法是由T. W. Anderson和D. A. Darling于1954年提出的,与K-S检验相比,AD检验度量经验累积概率和理论累积概率之差的方法显得更加自然。下面的公式就是其方法:

$$Z = n\int_{-\infty}^{\infty}[F_n(x)-F(x)]^{2}w(x)f(x)dx$$

是不是感觉像是计算方差的公式,我的直观感觉,就是把每个数据点的差求平方以后相加,得到总的分布偏差,这样就考虑了所有的差异点,而不是像K-S检验那样只考虑一个最大的。

公式中f(x)是理论分布密度函数,w(x)是某个权重函数。若w(x)≡1,则为Cramér-Von Mises统计量$W^2$。

用上面的积分公式计算统计量比较麻烦,因此两位统计学家又推导出了简单的计算方法,见下面的公式:

$$A^2=-n-\sum_{i}^{n}\frac{2i-1}{n}[\ln F(Y_i)+\ln (1-F(Y_{n+1-i})]$$

其中$Y_i=\frac{X_i-\hat{\mu}}{\hat{\sigma}}$

注意这个公式计算所采用的数据顺序是从小到大排列的,不是原来的数据排列顺序。

scipy.stats.anderson是由 scipy.stats.kstest 改进而来的,可以做正态分布、指数分布、Logistic 分布、Gumbel 分布等多种分布检验。默认参数为 norm,即正态性检验。

返回:statistic – 统计数;critical_values – 评判值;significance_level – 显著性水平

import numpy as np
from scipy import stats

np.random.seed(0)
x = np.random.randn(1, 100)
print(stats.anderson(x[0], 'norm'))
# AndersonResult(statistic=0.18097695613924714, critical_values=array([0.555, 0.632, 0.759, 0.885, 1.053]), significance_level=array([15. , 10. ,  5. ,  2.5,  1. ]))
# 如果输出的统计量值statistic < critical_values,则表示在相应的significance_level下,接受原假设,认为样本数据来自给定的正态分布。

参考链接:

scipy.stats.normaltest

scipy.stats.normaltest运用了D’Agostino–Pearson综合测试法,返回(得分值,p值),得分值=偏态平方+峰态平方

scipy.stats.normaltest(a, axis=0, nan_policy='propagate')

这里的三个参数都有必要看一下:

  • a:待检验的数据
  • axis:默认为0,表示在0轴上检验,即对数据的每一行做正态性检验,我们可以设置为axis=None来对整个数据做检验
  • nan_policy:当输入的数据中有空值时的处理办法。默认为 propagate,返回空值;设置为raise时,抛出错误;设置为omit时,在计算中忽略空值。

代码示例:

import numpy as np
from scipy import stats

np.random.seed(0)
x = np.random.randn(1, 100)
print(stats.normaltest(x[0]))
# NormaltestResult(statistic=0.45430460563864783, pvalue=0.7967994182504964)

如果pvalue是>0.05,则代表是正态分布。

参考链接:

Lilliefors-test

检验样本数据是否来自正态总体。采用方法是:当总体均值和方差未知时,用样本的均值和方差代替后 再用K-S检验法。据说效果不如Anderson-Darling test。原假设 H0:样本服从正态分布; 备择假设 H1:样本不服从正态分布

import numpy as np
from statsmodels.stats.diagnostic import lilliefors

np.random.seed(0)
x = np.random.randn(1, 100)
print(lilliefors(x[0]))
# 输出(统计量的值,P值)=(0.06433451870420759, 0.40018452551214856),P值>指定水平0.05,接受原假设,可以认为样本数据服从正态分布

参考链接:

27 Dec 13:31

大连地铁时报12.26

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报12.26
发信站: 水木社区 (Tue Dec 26 20:41:53 2017), 站内

有的人 愣是把人生活成了一个梗

女:“我们分手吧,我实在忍受不了你这种一点男子汉气概都没有的人。”男子强忍着泪水,安慰自己:“不能哭,一定不能哭,如果哭出来,今天化的妆就会花的。”

医生:“从你的X光片来看,你的两根肋骨已经断了。”“天呐,医生,那我该怎么办?”医生:“没事,我已经用美图秀秀帮你修好了。”

我的脚有点臭,每次回到家,老婆第一件事就是让我去洗脚。昨晚太累了,我没洗脚就直接坐在沙发上看电视,一岁多的儿子在沙发旁边玩,闻到我的脚臭味转身走到卧室去了……那是儿子第一次学会走路。

小牛犊看到主人后,兴奋得活蹦乱跳,用小犄角顶主人玩儿。主人摸着它脑袋说:“哈哈,你是真皮啊。”第二天,主人用小牛犊做了个真皮钱包。

记得小学三年级,数学课上学了“四舍五入”,我兴奋得不行,回家悄悄拿了老爸50块钱,理所当然地花了3块钱,又放了回去……后来,老爸的那顿揍让我开始怀疑数学老师教得不对。

昨晚下了一晚雪,第二天我去楼下开车,发现车窗玻璃没了,车里面都是雪。我特别气愤,去找物业,告诉他们有人砸了我的车玻璃。物业工作人员看了一眼车:“姑娘,你下次能把车窗摇上不?”

一天,食堂大妈生病了,需要打针。护士拿着针管比划了半天,手还一直抖个不停。大妈看得胆战心惊:“姑娘,你抖啥?”姑娘面无表情地说:“当年在学校食堂,我也这样问过你,不记得了吗?”

宾馆的餐厅里,顾客问服务员:“你能告诉我,你们餐厅的桌布多长时间换一次吗?”“对不起,我到这里工作才3个月,我也不知道。”服务员抱歉地说。


笑出马甲线

量变导致质变,比如,马云本来是马云,但财富积累到一定程度,他突然就变成了有些人的爸爸。

要说不实用的小家电,我认为第一要数扫地机器人,那天,我家狗在地上拉了粑粑,扫地机器人竟然把它抹匀了。

在大城市打拼的小刘感到头顶压力很大,于是不到25岁就秃顶了;小李上有老下有小,感到肩上的担子很重,于是得了肩周炎。


段子手荟萃

为了身体健康,我每天都坚持6点起床。久而久之,我终于养成了睡回笼觉的好习惯。

爸爸:“孩子,考试考得怎么样?”女儿:“不怎么好。”爸爸:“考了多少分?”女儿:“数学零分,语文6分。”爸爸:“嗯,是不怎么好,有点偏科啊。”

考试前一星期,我是家里的一级保护动物;考完试,我变成了野生动物;分数出来后,我又成了人人喊打的害虫。

25 Dec 09:25

大连地铁时报12.20

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报12.20
发信站: 水木社区 (Wed Dec 20 21:11:56 2017), 站内

讲道理,真没必要跟吃货较真儿

昨天去食堂排队买饭,一个小伙子没端好热汤,泼了我一腿,然后他马上返回餐台,我以为他去给我要点纸,结果他说:“师傅,加点汤……”

媳妇儿晚上睡觉时,突然咳嗽醒了,我赶紧问:“你怎么了?”
结果媳妇儿说:“我梦见一桌子好吃的,咽了咽口水准备吃,结果呛到自己了,咳着咳着就醒了”

在微信上看到一向很宅的老婆今天居然走了800步,我问她是怎么做到的,她说:“饭后百步走。”唉,希望她以后每天只走300步。

晚上吃晚饭,在食堂看见食堂的大师傅在吃泡面,觉得好心酸。可后来想想,我好像明白了什么……

睡觉前,女儿要吃苹果,我哄她说:“苹果里面有虫子,明天妈妈把虫子洗掉了你再吃。”女儿:“妈妈,你快让我吃了吧,明天苹果就被虫子吃光了。”

有个土豪哥们叫大伙到他家聚餐,问我们吃什么好?我说大冷天的,吃羊肉吧,他说不会做,我叫他把食材准备好,我来做。到他家一看,一只活羊拴在院子里,别说宰了,我打都打不过它。

第一次去男朋友家,男朋友的七大姑八大姨纷纷来凑热闹。临走时,他们把送给我们的鸡鸭鱼蛋等东西纷纷往男友车子的后备箱里塞……眼看就要塞完了,男朋友一下关了后备箱,把我拉上车说:“快……快撤!我二叔赶着一头猪来了。”

坐火车,对面妹子不停地吃零食,看得我有点饿了,下意识地咽了咽口水,妹子愣了一下,然后非常紧张地捂紧了零食!



笑出马甲线

昨天过生日,收到一个快递,装着一个红色信封,还是空的。正在纳闷,老妈来电话了:“给你快递了一个红包,让你高兴高兴,钱转你卡上了,快递不安全,就寄个皮。”

周末我跟我哥去公园玩海盗船,下来后我一直哆嗦,我哥却跟没事人一样。
我妈就说我:“吓成这熊样,以后别玩了!浪费钱!”
看到我哥一直在笑,老妈又说他:“你一点都不怕,下次别玩了!浪费钱!”
果然是亲妈,解释都好合理啊!

最讨厌看见露腿就问冷不冷的人了,我又不是机器人当然冷了!这么冷我都露腿了还不是为了臭美吗?



段子手荟萃

朋友:这次画展又没卖出去画啊?
画家:没,但是很受鼓舞。
朋友:为啥?
画家:有幅画被偷了。 笑话大全

19 Dec 14:11

持续集成服务 Travis CI 教程

编写代码只是软件开发的一小部分,更多的时间往往花在构建(build)和测试(test)。

为了提高软件开发的效率,构建和测试的自动化工具层出不穷。Travis CI 就是这类工具之中,市场份额最大的一个。

本文介绍 Travis CI 的基本用法。用好这个工具不仅可以提高效率,还能使开发流程更可靠和专业化,从而提高软件的价值。而且,它对于开源项目是免费的,不花一分钱,就能帮你做掉很多事情。

一、什么是持续集成?

Travis CI 提供的是持续集成服务(Continuous Integration,简称 CI)。它绑定 Github 上面的项目,只要有新的代码,就会自动抓取。然后,提供一个运行环境,执行测试,完成构建,还能部署到服务器。

持续集成指的是只要代码有变更,就自动运行构建和测试,反馈运行结果。确保符合预期以后,再将新代码"集成"到主干。

持续集成的好处在于,每次代码的小幅变更,就能看到运行结果,从而不断累积小的变更,而不是在开发周期结束时,一下子合并一大块代码。

二、使用准备

Travis CI 只支持 Github,不支持其他代码托管服务。这意味着,你必须满足以下条件,才能使用 Travis CI。

  • 拥有 GitHub 帐号
  • 该帐号下面有一个项目
  • 该项目里面有可运行的代码
  • 该项目还包含构建或测试脚本

如果这些条件都没问题,就可以开始使用 Travis CI 了。

首先,访问官方网站 travis-ci.org,点击右上角的个人头像,使用 Github 账户登入 Travis CI。

Travis 会列出 Github 上面你的所有仓库,以及你所属于的组织。此时,选择你需要 Travis 帮你构建的仓库,打开仓库旁边的开关。一旦激活了一个仓库,Travis 会监听这个仓库的所有变化。

三、.travis.yml

Travis 要求项目的根目录下面,必须有一个.travis.yml文件。这是配置文件,指定了 Travis 的行为。该文件必须保存在 Github 仓库里面,一旦代码仓库有新的 Commit,Travis 就会去找这个文件,执行里面的命令。

这个文件采用 YAML 格式。下面是一个最简单的 Python 项目的.travis.yml文件。


language: python
script: true

上面代码中,设置了两个字段。language字段指定了默认运行环境,这里设定使用 Python 环境。script字段指定要运行的脚本,script: true表示不执行任何脚本,状态直接设为成功。

Travis 默认提供的运行环境,请参考官方文档 。目前一共支持31种语言,以后还会不断增加。

下面是一个稍微复杂一点的.travis.yml


language: python
sudo: required
before_install: sudo pip install foo
script: py.test

上面代码中,设置了四个字段:运行环境是 Python,需要sudo权限,在安装依赖之前需要安装foo模块,然后执行脚本py.test

四、运行流程

Travis 的运行流程很简单,任何项目都会经过两个阶段。

  • install 阶段:安装依赖
  • script 阶段:运行脚本

4.1 install 字段

install字段用来指定安装脚本。


install: ./install-dependencies.sh

如果有多个脚本,可以写成下面的形式。


install:
  - command1
  - command2

上面代码中,如果command1失败了,整个构建就会停下来,不再往下进行。

如果不需要安装,即跳过安装阶段,就直接设为true


install: true

4.2、script 字段

script字段用来指定构建或测试脚本。


script: bundle exec thor build

如果有多个脚本,可以写成下面的形式。


script:
  - command1
  - command2

注意,scriptinstall不一样,如果command1失败,command2会继续执行。但是,整个构建阶段的状态是失败。

如果command2只有在command1成功后才能执行,就要写成下面这样。


script: command1 && command2

4.3 实例:Node 项目

Node 项目的环境需要写成下面这样。


language: node_js
node_js:
  - "8"

上面代码中,node_js字段用来指定 Node 版本。

Node 项目的installscript阶段都有默认脚本,可以省略。

  • install默认值:npm install
  • script默认值:npm test

更多设置请看官方文档

4.4 部署

script阶段结束以后,还可以设置通知步骤(notification)和部署步骤(deployment),它们不是必须的。

部署的脚本可以在script阶段执行,也可以使用 Travis 为几十种常见服务提供的快捷部署功能。比如,要部署到 Github Pages,可以写成下面这样。


deploy:
  provider: pages
  skip_cleanup: true
  github_token: $GITHUB_TOKEN # Set in travis-ci.org dashboard
  on:
    branch: master

其他部署方式,请看官方文档

4.5 钩子方法

Travis 为上面这些阶段提供了7个钩子。

  • before_install:install 阶段之前执行
  • before_script:script 阶段之前执行
  • after_failure:script 阶段失败时执行
  • after_success:script 阶段成功时执行
  • before_deploy:deploy 步骤之前执行
  • after_deploy:deploy 步骤之后执行
  • after_script:script 阶段之后执行

完整的生命周期,从开始到结束是下面的流程。

  1. before_install
  2. install
  3. before_script
  4. script
  5. aftersuccess or afterfailure
  6. [OPTIONAL] before_deploy
  7. [OPTIONAL] deploy
  8. [OPTIONAL] after_deploy
  9. after_script

下面是一个before_install钩子的例子。


before_install:
  - sudo apt-get -qq update
  - sudo apt-get install -y libxml2-dev

上面代码表示before_install阶段要做两件事,第一件事是要更新依赖,第二件事是安装libxml2-dev。用到的几个参数的含义如下:-qq表示减少中间步骤的输出,-y表示如果需要用户输入,总是输入yes

4.6 运行状态

最后,Travis 每次运行,可能会返回四种状态。

  • passed:运行成功,所有步骤的退出码都是0
  • canceled:用户取消执行
  • errored:before_installinstallbefore_script有非零退出码,运行会立即停止
  • failed :script有非零状态码 ,会继续运行

五、使用技巧

5.1 环境变量

.travis.ymlenv字段可以定义环境变量。


env:
  - DB=postgres
  - SH=bash
  - PACKAGE_VERSION="1.0.*"

然后,脚本内部就使用这些变量了。

有些环境变量(比如用户名和密码)不能公开,这时可以通过 Travis 网站,写在每个仓库的设置页里面,Travis 会自动把它们加入环境变量。这样一来,脚本内部依然可以使用这些环境变量,但是只有管理员才能看到变量的值。具体操作请看官方文档

5.2 加密信息

如果不放心保密信息明文存在 Travis 的网站,可以使用 Travis 提供的加密功能。

首先,安装 Ruby 的包travis


$ gem install travis

然后,就可以用travis encrypt命令加密信息。

在项目的根目录下,执行下面的命令。


$ travis encrypt SOMEVAR=secretvalue

上面命令中,SOMEVAR是要加密的变量名,secretvalue是要加密的变量值。执行以后,屏幕上会输出如下信息。


secure: ".... encrypted data ...."

现在,就可以把这一行加入.travis.yml


env:
  global:
    - secure: ".... encrypted data ...."

然后,脚本里面就可以使用环境变量$SOMEVAR了,Travis 会在运行时自动对它解密。

travis encrypt命令的--add参数会把输出自动写入.travis.yml,省掉了修改env字段的步骤。


$ travis encrypt SOMEVAR=secretvalue --add

详细信息请看官方文档

5.3 加密文件

如果要加密的是文件(比如私钥),Travis 提供了加密文件功能。

安装命令行客户端以后,使用下面的命令登入 Travis CI。


$ travis login 

然后,进入项目的根目录,使用travis encrypt-file命令加密那些想要加密的文件。


$ travis encrypt-file bacon.txt

encrypting bacon.txt for rkh/travis-encrypt-file-example
storing result as bacon.txt.enc
storing secure env variables for decryption

Please add the following to your build script (before_install stage in your .travis.yml, for instance):

    openssl aes-256-cbc -K $encrypted_0a6446eb3ae3_key -iv $encrypted_0a6446eb3ae3_key -in bacon.txt.enc -out bacon.txt -d

Pro Tip: You can add it automatically by running with --add.

Make sure to add bacon.txt.enc to the git repository.
Make sure not to add bacon.txt to the git repository.
Commit all changes to your .travis.yml.

上面的代码对文件bacon.txt进行加密,加密后会生成bacon.txt.enc,该文件需要提交到代码库。此外,该命令还会生成一个环境变量$encrypted_0a6446eb3ae3_key,保存密钥,储存在 Travis CI,文件解密时需要这个环境变量。你需要把解密所需的openssl命令,写在.travis.ymlbefore_install字段里面。这些都写在上面的命令行提示里面。

--add参数可以自动把环境变量写入.travis.yml


$ travis encrypt-file bacon.txt --add

encrypting bacon.txt for rkh/travis-encrypt-file-example
storing result as bacon.txt.enc
storing secure env variables for decryption

Make sure to add bacon.txt.enc to the git repository.
Make sure not to add bacon.txt to the git repository.
Commit all changes to your .travis.yml.

详细信息请看官方文档,实际的例子可以参考下面两篇文章。

(完)

文档信息

16 Dec 07:37

大连地铁时报12.14

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报12.14
发信站: 水木社区 (Fri Dec 15 07:28:25 2017), 站内

你只猜对了故事的开头

我一朋友,有一次坐黑车,车被交警拦下了。情急之下,司机连忙解释:“我们是朋友,我有他电话。”说着,便打他手机。因为我朋友坐他车好几次了,所以互相留了电话号码。这时,朋友的手机响了,交警拿过来一瞧,上面写着:“黑车司机”……

昨天下午,家里安排我跟一个妹子相亲,我俩都接到了家里的死命令:必须跟对方吃完晚饭才能回家!时间还早,我和妹子在茶馆尴尬无语中……然后,妹子掏出手机,一边抽烟一边玩游戏。而我,看她玩得正欢,只好从包里默默地拿出了即将完工的十字绣……

我姐比我大两岁,我妈说,我还不会走路的时候,有一次,我妈做饭,让我姐看着我,不要让我随便吃脏东西。然后,我妈无意间隔着窗户发现,我在地上爬着,抓起一片干鸡屎就往嘴里塞。我姐看见了,大喊一声,然后冲过来吹了吹鸡屎片上面的灰,又递给了我……

记得上学时语文考试有一道题目,李清照是什么派,我写的是武当派。发试卷时,老师说有一位同学的答案可以去请家长了,当时我吓得瑟瑟发抖,瞄了一眼同桌写的答案——蛋黄派,瞬间轻松了许多。

小明带了一个小朋友回家玩,小朋友走后妈妈问:“小明,刚才那个同学,在班里第几名呀?”小明:“倒数第一名。”妈妈生气,啪啪地逮住小明一顿暴打:“让你不学好,让你不学好,我不是说过不要跟比你差的孩子玩吗?你要跟第一名玩!”小明委屈地说:“我刚开始跟他玩的时候,他确实是第一名呀!”

翻了一下老婆以前的动态,刚认识那会儿,她在朋友圈晒过我俩的合照。这个我记得,不过那时我和她家里人不是好友,看不到他们的评论。现在我们结婚了,终于可以看到了。当时丈母娘在我们俩的合照下方评论:中下。小姨子:同意楼上。老丈人:这小子看起来心术不正!

昨天晚上请女友吃饭,正打算求婚,刚好碰见一个卖花的小姑娘。于是,我花10块钱向小姑娘买了一朵玫瑰花,并叮嘱她一会儿我会把求婚戒指套在玫瑰花上,让她先藏起来。等女友来了,她再假装过来卖花,我买一朵再顺势向女友求婚。谁料,等一切就绪时,小姑娘竟然跑来悄悄地对我说:“加100,不然我马上叫你‘爸爸’!”

14 Dec 07:07

大连地铁时报12.13

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报12.13
发信站: 水木社区 (Wed Dec 13 22:05:22 2017), 站内

梦想,咋就这么容易实现

大早上闺女跟我说:“前一天晚上做了个梦,梦到跟奶奶去超市了,奶奶什么吃的也没给我买。”这不一大早搂着奶奶不依不饶的,非让奶奶给补上。不补上就不去上学。这大概就是吃货的最境界了。

单位有一个同事,处的第一个女朋友分手后去了韩国,第二个女朋友分手后去了日本,第三个去了塞班岛。昨天同事大姐给他介绍对象,对他说:“这女孩想去新加坡来着,结果没去成,我寻思让她跟你处个对象,借借你的运气!”

小时候梦想什么也不用干,人家抢着给我塞钱。如今梦想终于实现了,我成了一名饭店服务员,昨天一桌4个人吃完饭抢着结账,拽着我,往我手里、兜里塞钱,梦想实现的感觉,很难形容。

女儿3岁时,我责备她不该重复别人的谎言,告诫她千万别说谎。她问:“为什么?”我说:“说谎的小孩会变成花,种在花盆里当装饰。”为了确定她明白我的苦心,我问:“你知道我的意思吗?”她冷静地回答:“知道,这是个谎言。”

上个月收拾屋子的时候,我在男朋友的鞋里面发现了私房钱,正打算生气的时候,又翻到一张纸条,上面写着“给老婆买口红的”,顿时心里暖暖的,我就原封不动地把这钱放回去了,可是我等了1个月也没等到自己的口红。

过去我给人一种很瘦弱的感觉,听说健身能改变人的气质,于是忍痛用这个月的工资办了一张健身卡,现在的我气质果然不一样了,给人一种到处蹭饭、很讨厌的感觉。

业务员:“需要理财顾问吗?”
我:“已经有了!”
业务员:“哪家公司的?”
我:“我老婆!”
业务员:“先生,您可以考虑其他投资,请问您想投资贵金属吗?”
我:“已经投了很多了!”
业务员:“您都投资了什么贵金属?”
我:“老婆的金戒指、金耳环、金项链!”

坐公交遇到一对母子,男孩就六七岁。小孩要开窗户,他自己打不开就让他妈帮他打开,他妈说自己没劲,打不开窗户。孩子说:“你打我就有劲儿,让你开个窗户就没劲儿。”



笑出马甲线

@想要锁骨的妹纸
我一个室友向我抱怨说:“越来越讨厌现在的游戏了,动不动就要充值、邀请好友,本来我就是因为没钱、没朋友才玩游戏的。”

@快递员
当快递员不能跟客户混太熟,他们每次在附近打不着车时,就打电话给我,骗我说有快件要发,还是很急很急的那种,告诉我他们在哪个路口等我,最后我只能无可奈何地捎他回家。

@我是你大哥
13 Dec 10:02

大连地铁时报12.11

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报12.11
发信站: 水木社区 (Tue Dec 12 08:01:21 2017), 站内

有些“优点”还是不暴露的好

1.小表弟的头不小心撞到了墙上,一直在哭,便问目击者乐乐,他是怎么撞到的。乐乐二话不说,直接用自己的头往墙上撞去,哇地一声哭了,边哭还边说:“就是这样撞到的。”家里顿时可热闹了,“男子二重哭”不绝于耳……

2.古时有一小国,因战事频频导致国库不支。
皇帝慌忙叫来朝中一个大臣,命其将自己家产充公,以做军费。
大臣不愿却也不敢抗命,只怯怯地问了一句:“朝中大臣那么多,为何是我?”
皇帝走到他的面前,拍拍他的肩膀说:“因为爱卿,不会轻易悲伤……”

3.男生声音好听真得非常重要。我有个朋友在外面犯了事,本来是要拘留24小时的,后来有个女警官听到他回答询问的声音后,主动帮他延长到48个小时。

4.合租室友毛病很多,我实在忍受不下去,于是找他谈话。
我:“有话跟你说,憋不住了。”
室友:“啥?”
我:“我不住了!”
室友:“不住就不住呗,可你为啥说自己是鳖?”

5.第一次跟男朋友去他家,刚看到他妈妈,我赶紧打招呼:“阿姨好。”他妈妈拉着我的手亲切地说:“叫什么阿姨呀,叫妈好了。”我害羞低叫了一声:“妈。”他妈妈高兴地说道:“哎,我就认你这个女儿了,以后有机会给你介绍个好点的对象。”

6.去饮品店买果汁,店员介绍说:“我们家的混合果汁不错,苹果+梨、橙+蓝莓都很好喝。”我喜欢吃李子,于是问她:“那李+橙会是什么味道?”她想了想说:“很有钱的味道吧。”

7.约会时如何判断一个女人真的吃饱了?
直接问她:“你吃饱了吗?”这是直男常见的错误。
无论饱没饱,你得到的答案都会是吃饱了,或者差不多、不需要……
正确的应该是,你暗中观察她补口红没有?如果补了口红那就说明真的饱了,不想再吃了。
女人可以随意欺骗男人,但是她们绝对不会浪费自己的化妆品。

8.苦者登高问禅师:“大师,有钱到底有多快乐?”禅师笑而不语,拿出一叠又一叠的钱,直到桌上已经堆钱如山了,苦者不禁问:“您是要把这些钱都给我,让我体验一下吗?”禅师摇摇头:“不不不,我只是要让你看看我有多快乐。哈哈哈,看到了吗?”


笑出马甲线

@啊勒路呀
今天和老妈去吃酒席,去之前老妈教我,出去嘴要甜一点,说看见别人小孩长得还过得去的,就要夸奖人家长得好漂亮,实在看着丑的就夸奖别人长得好高。不知道为什么,吃个饭的功夫,已经有好多人夸我长得高了。

@百思不得姐
13 Dec 09:59

你小时候做过哪些匪夷所思的事情。

by Rio2016
发信人: Rio2016 (2016 Summer Olympics), 信区: Joke
标 题: 你小时候做过哪些匪夷所思的事情。
发信站: 水木社区 (Fri Dec 8 17:33:49 2017), 站内

我先说一个,小时候看电视剧,每集结束后会有演职员字幕。那时候我都是瞪大眼睛尽量把每一个人名都看到。 我这么做的原因是,我当时觉得那么多工作人员费心卖力的拍电视剧最终的回报就是片尾显示下自己的名字。 如果没人看他们肯定很伤心。

直到有一年电视台播一部叫做莲花争霸的港台片,片尾字幕那叫一个快,基本上是一闪而过,我当时就怀疑人生了
--

※ 来源:·水木社区 http://m.newsmth.net·[FROM: 61.148.243.*]

06 Dec 14:23

我和快递小哥之间的搞笑经历

by jiale123
发信人: jiale123 (jiale123), 信区: Joke
标 题: 我和快递小哥之间的搞笑经历
发信站: 水木社区 (Tue Dec 5 17:18:22 2017), 站内

有一次买了一个除毛器,大概路上颠簸的时候开关被震开了,快递小哥送货的时候狂打我电话,那时我正在上班,没接到,他直接冲到我单位一边跑一边喊:“某某你的快递!!!一直在震动!!!是不是炸弹啊!!!你拆开看看啊!!!”
--
我同事便说:好端端上着班突然来个炸弹?太尼玛惊心动魄了!还让不让人安心工作了?
※ 修改:·jiale123 于 Dec 5 17:19:27 2017 修改本文·[FROM: 113.116.51.*]
※ 来源:·水木社区 http://www.newsmth.net·[FROM: 113.116.51.*]
05 Dec 07:07

50条知乎点赞最高的段子,已笑喷

by infinetely
发信人: infinetely (∞∞∞∞∞∞∞∞), 信区: Joke
标 题: 50条知乎点赞最高的段子,已笑喷
发信站: 水木社区 (Tue Dec 5 11:47:48 2017), 站内

不是段子
这就是生活

1
说一句很有内涵的诗句
一懒众衫小

2
你听过的第一个3D环绕音乐是什么?
丢手绢

3
一整个披萨你要切8块还是12块?
8块吧,12块我吃不下

4
如果你是别人,你愿意和自己处对象么?
想都不敢想,哪有这种福气

5
要是在古代,姐的颜值能撑起整个青楼!
你是说你长得像柱子吗?

6
用一句话形容你的罩杯
随爹[doge]

7
对不起,我们可能不太合适
放屁,我百搭

8
穷不是一种状态
穷是一种常态

9
你怎么一个人逛街啊?
半个人逛街我怕吓着你!

10
地球外面那一层是什么?
香飘飘奶茶

11
历史老师:你为什么交白卷?
我:我怕我会篡改历史

12
小学生当街闹分手
网友:请给90后空巢老人多些关爱

13
你们这些年轻人,就是把钱看得太重了!
放桌上也不拿东西压,风吹跑了怎么办。

14
服务员:“很高兴为您服务”
我:“你高兴的太早了”

15
男朋友吃女朋友豆腐正常吗?
没结婚就动手动脚的,那结婚后岂不是要上床?

16
问:在武侠世界里开一家客栈要注意什么?
答:墙上贴上字:要打出去打。



17
服务员:“请问我有什么可以帮您的吗”
“有啊,你能帮我付钱吗”

18
一次dota,队友:我有点卡,你们呢?
另一队友:这游戏还有点卡?!在哪买?

19
广播体操太假了,
女生做了十几年的扩胸运动一点效果都没。
那你看见过跳拉丁舞的男生丁丁被拉长吗。

20
北冥有鱼,其名为鲲,
鲲之大,跟你体型差不多。
化而为鸟,其名为鹏,
鹏之背,跟你运气差不多。

21
有一次看别人求婚,
我问我朋友为什么求婚是单膝跪地?
她说双膝跪地那是上坟。


22
谁能想到,这名16岁少女,
4年前只是一位12岁少年。

23
问:世上不会游泳的动物是?
答:媳妇和妈

24
我想摸你的头发只是简单的试探啊
嗯!真的很油!

25
sunshine组合新歌《我要做你女朋友》
网友:我拒绝

26
寒冷的环境可以使人变得更年轻
小明爷爷今年70岁,出门冻得跟孙子似的

27
女生:我生气了,你就算给我买cpb也没用
男生:那不买了不买了,别生气了

28
如果被车撞飞10米远,
爬起来之后说什么最帅?
下一辆。

29
孙悟空头上的圈叫什么
猴头菇

30
妈,我是你的什么
妈的智障

31
我问电风扇我丑么,
然后电风扇摇了一夜的头,
顿时感觉好多了
别听电风扇的,它都是吹的

32
05 Dec 07:01

Re: 你们捡到过什么好东西么?

by panxf
发信人: panxf (panxf), 信区: Joke
标 题: Re: 你们捡到过什么好东西么?
发信站: 水木社区 (Sun Dec 3 10:21:02 2017), 站内


【 在 DDOO 的大作中提到: 】

邻居家的大大哥有一对让人羡慕的鸡蛋大小的铁蛋珠,

一天他不小心把一只铁蛋珠掉草丛中了,找了小半天找不到。
他放弃了,然后他很失落的去河边洗了手。

正打算去游泳的我路过那草丛,一眼就看到了那铁蛋珠。
然后下了河想摸点田螺,一把又从一个石头缝里摸出一另一颗铁蛋珠。

于是前后不到两分钟,那对让人羡慕的铁蛋珠尽入我手!!!!

--

※ 来源:·水木社区 http://www.newsmth.net·[FROM: 114.240.70.*]
30 Nov 10:25

病例一则

by TGIF
发信人: TGIF (周末), 信区: Joke
标 题: 病例一则
发信站: 水木社区 (Wed Nov 29 11:48:13 2017), 站内

【病例一则】
某女,因丈夫家暴而长期失眠。
医生按《黄帝内经》的理论给开了生铁落饮,可是药房抓不到这味药,医生嘱其改用磨刀水煮大枣喝。
于是该女每天在家磨菜刀。
从此,再未听说家暴的事,她的失眠症也很快治愈了!
--

※ 来源:·水木社区 http://www.newsmth.net·[FROM: 114.243.251.*]
29 Nov 05:12

大连地铁时报11.16

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报11.16
发信站: 水木社区 (Fri Nov 17 06:33:18 2017), 站内

和熊孩子斗智斗勇那点事儿

晚上散步,听见一个老太太对小孙女说:“我的同学们约定一年聚一次,一直坚持了十几年,可来的人越来越少。今年只剩下我和另外三个同学了……”闻此言我心头一紧,心想人生不过尔尔,终要归去。然后老太太停顿片刻,厉声发问:“我都启发到这了,还想不起来吗?”小女孩:“想起来了,遥知兄弟登高处,遍插茱萸少一人。”

昨晚跑顺风车,接了一单送小情侣回学校,当时差不多10点40了,听他们的意思过了11点寝室就关大门。我听到男生说:“估计来不及了,要不今天外边住吧。”女生害羞地“嗯”了一声。我顿时倦意全无,猛地抬头说:“你们放心,哥的车350马力,绝对来得及!”然后一顿炫酷的操作,准时把他们送回了学校!

老师打电话到家里告状,说我上课时和同桌一起睡觉,都打呼噜了,性质极其恶劣,严重影响了其他同学的正常学习。挂掉电话后,老妈边打我,边骂道:“叫你晚上熬夜玩手机!叫你晚上熬夜玩手机!”老爸边打我,边骂道:“你同桌男的女的!你同桌男的女的!”

大儿子今年15岁了,老婆又给我生个儿子。在这个生男不如生女的年代,唯一的好处就是,买东西讨价还价的时候,如果我低着头和老板说:“我有俩个儿子。”多少人家都会给我便宜点儿。

儿子上一年级了,为了培养儿子多读书,我给他买了《水浒传》的彩图画册,他很喜欢看。昨天儿子问我:“爸爸,五花大是谁?”我左思右想也没想起水浒中有个五花大,就让儿子把书拿来我看一下,只见书上赫然写着:李逵一觉醒来,已经被五花大绑了起来!

去吃米线的时候,领桌一对母女正在讨论以后做什么工作。妈妈说:“你长大了我就给你整容。”女儿问:“整容干吗?”妈妈说:“整容了好当明星!”女儿说:“明星不一定整容啊,我才不整容。”妈妈又说了:“你不整容你就当笑星吧。”

30年前,人们惊呼流行音乐会毁掉下一代;20年前,人们惊呼电视节目会毁掉下一代;10年前,人们惊呼电脑和因特网会毁掉下一代;现在,人们开始惊呼手机会毁掉下一代……可人类发展的历史证明: 没有任何力量能毁掉下一代,除了上一代。

29 Nov 05:10

大连地铁时报11.27

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报11.27
发信站: 水木社区 (Mon Nov 27 21:23:30 2017), 站内

是特别的缘分,让我有这样的家人?

我最佩服那些一见到美女就暂时性失忆的人,好像突然就忘了自己有老婆孩子一样,能坦然地跟美女打情骂俏。我就不行了,一调戏美女就会想到自己的老婆孩子,良心就痛,所以想问问大家,离婚手续办起来麻烦吗?

我爷爷曾警告过人们泰坦尼克号的事,当时他大喊:“前面有冰山!船要沉了!”结果却根本没有人听,只是把他撵出了电影院。

我虽然不是富二代,但我相信,只要我够努力、够上进,我就可以把我的孩子教育成一个吃得起苦的人。

跟哥们闲聊,我问他:“要是有人绑架了你媳妇,你愿意出多少钱赎?”哥们说:“一分钱也出不了。”他抽口烟又说,“除非她告诉我银行卡密码。”

昨晚吃完饭,老公突然说:“全天下的女人在我眼里就两个样子,一个是你。”我有些羞涩,问:“另一个呢?”老公说:“瘦子。”

老婆在纸上写了一大堆数据,然后跟我说:“你看,每个月房贷、车贷、柴米油盐、水电费、孩子的花费……你的工资就这么没了。”我:“那你的工资呢?”她:“我的工资关你什么事!”

老公最近健忘得很。家里灯泡坏了,他骑着摩托车去买灯泡,买回来一看钱包忘在店里了,又回去拿钱包,结果又把手机忘在店里了,又回去拿手机。回家安灯泡后发现不亮,老公又得回去换灯泡,这次他学聪明了,带着我去,我俩刚到店里,老板就来了一句:“哟呵,老婆也不想要了?”

我姐夫是做微商的,到现在都买第5辆保时捷了,他说他就喜欢保时捷。后来他拉我入行,我仅仅用了1年的时间就积累了20多万,说真的,我活这么大都没欠过这么多钱。


神句ONE

各个社交和购物网站的“猜你喜欢”从没有猜中过我喜欢什么。

用一句话形容我的长相就是:眼皮无双至,下巴不单行。

别看有些人表面上一副无所畏惧的样子,实际上早就悄悄把棉裤穿上了。

当才华撑不起野心的时候,就要多读书,读着读着,野心也就没了。

(部分笑话取自网络,如有侵权请联系删除)
--

※ 来源:·水木社区 http://m.newsmth.net·[FROM: 123.151.77.*]

29 Nov 05:07

大连地铁时报11.23

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报11.23
发信站: 水木社区 (Thu Nov 23 20:41:20 2017), 站内

生活微苦,但你得甜

当代单身男性大学生太可怕了。昨晚我在帘子里看剧,正好看到女主角去厨房洗水果,洗了三四秒吧,我帘子突然被掀开,舍友硕大的脑袋赫然出现在我面前,一双透露着无限渴望的眼睛直勾勾盯着我:“是不是有女的洗澡呢?我看看。”

在城里摸打滚爬了7年,终于买了套小房子。去取公积金的时候,工作人员是个妹子,她先给了我张表格,然后问我:“单身吗?”我愣了下,心想,难道我今天特别帅吗?我如实答道:“不好意思啊,我有女朋友了。”妹子白了我一眼说:“是单身还是已婚!”

昨天在电器商场,看到电视里讲一个男主角白手起家成为亿万富翁的故事,我便暗暗发誓,一定要努力赚钱,把这台两千块钱的电视买回家。

单身久了,一个同学来图书馆带吃的给我,我连以后怎么给我们收养的孩子解释为什么他会比别人多一个爸爸少一个妈妈都想好了。

程序员家的水管坏了,他打电话叫水管工来修理。水管工鼓捣了1个小时,终于把管子修好了,他递给程序员一张600元的帐单。“600元!”程序员愤怒地说,“我当程序员一天都赚不了这么多钱!”“是啊。”水管工平静地说,“我当程序员的时候也是。”

如果美女说:“哈哈,我去洗澡!”过了一年没回你,表示她根本不想回你。如果程序员说:“哈哈,我去上班!”过了一年没回你,表示他根本还没下班。

晚上健完身有点口渴,看到路边摊有卖橘子,于是挑了几颗好看的橘子。老板拿起几颗有斑点的就往袋子里塞,说:“帅哥,这种长得不好看的其实更甜。”我好奇地问:“是因为橘子觉得自己长得不好看,所以努力让自己变甜吗?”老板微微一愣,看智障似的看着我:“不是,我只想早点卖完回家。”

小时候有一次,我考了倒数第一,我拿着成绩单回到家里,觉得自己可能活不过那个晚上了。我想起电视里有句台词:“我死也要死得美美的!”于是我瘫在沙发上,随手拿起妈妈的口红,给自己抹了个红嘴唇,然后撅起嘴到处亲,最后亲在了爸爸的白衬衫上……晚上妈妈下班回家了,他俩打得不可开交,都没人管我考了几分。


笑出马甲线

@大面包小草莓
作为一名监考老师,我还是要奉劝一下各位考生,在考场的时候千万不要睡觉,因为看见你们睡觉我也想睡!

@半醉半醒半懵74
有一次我坐公交车,突然有人昏倒了,周围乘客都不知该如何是好。这时我注意到车上写着如遇紧急情况请凿碎玻璃的提示。我按着提示去做了,可那人还是不醒。

27 Nov 07:07

[转载]0,0,0,0 求 24 点

by pauljoe
发信人: pauljoe (袋鼠妈妈有个袋袋), 信区: Joke
标 题: [转载]0,0,0,0 求 24 点
发信站: 水木社区 (Mon Nov 27 08:58:54 2017), 站内 [累计积分奖励: 500/0]

我弟今年上了大班,有一天我爸突然半夜找我,问我会不会算 24 点。

我弟幼儿园布置了一道 24 点的作业,我爸根本不会做。

哇,一听我就来劲了。

然后我爸就给我发来了一道题。

0,0,0,0 求 24 点。

????

这种老题目都做烂了。

(0!+0!+0!+0!)!=24

我给我爸解释了遍什么叫「阶乘」。

问题是,我弟才大班,现在小朋友学的都这么超前的吗?

我爸问我还有没有别的方法,这个估计我弟听不懂。

我思考了会,安慰了我爸一波。

「现在跟以前不一样了,他们接触的世界是多元化的。学的东西也比以前难好多了。而且这题只有这一种解法啊。」

我爸回了个 微笑 的表情。

第二天,我问我爸,那题目怎么样了。

我爸说,不太对。

然后我问他答案。

00:00
--

※ 来源:·水木社区 http://www.newsmth.net·[FROM: 211.103.173.*]
27 Nov 07:06

大连地铁时报11.26

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报11.26
发信站: 水木社区 (Sun Nov 26 20:18:14 2017), 站内

有泪不轻弹,还不是因为不够惨?

表妹受过情伤,和前男友分得坚定决绝,拉黑了微信QQ,相互发誓生死不再相见。昨天她骑着电瓶车去了前男友小区,把他脸挠花了。我劝她想开点,她气愤地说:“太缺德了!就一个支付宝没删,王八蛋竟敢偷我能量!”

我和儿子有个共同的心愿,就是出国旅游。昨天儿子考试得了全班第一,我跟媳妇合计着带他出国见见世面。吃晚饭的时候,我问他:“儿子,你的心愿是什么?”儿子:“吃汉堡包。”我:“往大了说。”儿子:“买变形金刚。”我:“今天你爹说了算,想想,咱俩共同的心愿是什么?”儿子怯生生地瞅了媳妇一眼说:“换个妈?”

我在一个公司工作,3年的工资是6万块。老板说他有一张布加迪的10万块优惠券,问我工资要6万现金还是布加迪10万块优惠券,我毫不犹豫地要了10万块的布加迪优惠券,我是不是很机智?

昨天我在小区楼下等顾客下来拿外卖,我旁边的一男生估计是在等女朋友,他抽了口烟,忧伤地说:“有时候我真羡慕你们送外卖的,一个电话姑娘就下来了,不像我,每次都要等半小时,还不敢打电话催。”这一刻,我竟不知该如何安慰他。

我小时候有一次考砸了,因为怕挨揍,就打算假装上吊吓唬老爸,让他舍不得打我。那天我先回到家,搞了条绳子绑在吊扇上,我再站在凳子上,把脖子套到绳子系出来的圈圈里,计划等爸爸一回来我就踹凳子。我爸终于回来了,当时天热,他还没进客厅,就伸手进来先开吊扇。我瞬间脖子一紧,眼前一黑,像陀螺一样在空中转了起来……

昨天看到一对情侣在街头吵架,女的说:“够了!谁要你的关心!”这时,旁边推车卖杂货的小贩喇叭里传来这样的声音:“蟑螂要、蚂蚁要、臭虫要、老鼠要……”

很多朋友问我如何选购车辆,说实话,我并不太擅长,因为我的车基本上都是用一次就换了,并不能很深入地了解每辆车的实际性能。当然,这倒也不是因为我有钱任性,因为共享单车就是这样规定的!

我陪女友逛街买衣服,女友突然说:“咱俩在一起你是不是很幸福?我觉得你这几年成熟了许多。”我想想,的确是,两年前我还不会洗衣服煮饭洗碗拖地呢。



神句ONE

我有一个朋友听说抽烟影响生育,毅然决然地戒了要孩子的念头。

一个朋友刚24岁就说要去植发,我心里感叹,这才多大呀,就挣够植发的钱了。

才知道章鱼是喜欢吃龙虾的,这么便宜的食材吃这么贵的食材,不要脸!

小时候我们辞不达意,长大了我们言不由衷。
25 Nov 05:09

今早的对话

by maggiehuh
发信人: maggiehuh (darougougou), 信区: Joke
标 题: 今早的对话
发信站: 水木社区 (Thu Nov 23 15:30:45 2017), 站内

大清早被闺女吵醒,我恨恨的说:好梦都被你打断了
闺女:做的啥梦?
我:和你爹在日本玩。
闺女:有我没?
我:没
闺女:讨厌!都不带我


--
发自xsmth (iOS版)
--

※ 来源:·水木社区 http://m.newsmth.net·[FROM: 106.38.140.*]
25 Nov 05:07

Reddit: 奇葩的911紧急求助电话

by Sunyata
发信人: Sunyata (水木诗妖龙静颜), 信区: Joke
标 题: Reddit: 奇葩的911紧急求助电话
发信站: 水木社区 (Thu Nov 23 12:29:09 2017), 站内

蛋奶 @ 2017.11.23 , 12:00 pm
Reddit热帖之“911接线员们,你们都接过哪些奇奇怪怪的紧急求助电话?”:

neinta:
“这里是911,请问有什么紧急情况?”
“我在路上看到了一头猪,超级无敌大。”
“先生,你的位置是哪里?”
“在红绿灯路口,我TM从来没见过那么大的猪。赶紧派人过来!”
(我们的小镇只有一个红绿灯路口,路口附近就有一个酒吧。当时是凌晨2:30,酒吧已经关门了。)
“那只猪有多大?”
“可能有只大众汽车那么大!”
“请问您喝了多少酒?”
“我特么根本没醉!这只巨猪大得快赶上一只小汽车了!我说你们是不是有毛病啊?”
警官赶过去的时候,发现了一只成年河马,是从当地野生动物园逃出来的。

dustydigital101:
很多老年人因为尿路感染而出现了幻觉。有一次,一名女性打电话过来请教如何给别人实施心肺复苏。急救队员赶到那里的时候,发现她正(轻轻地)给她家喵星人进行胸部按压。喵星人一脸懵逼,它看上去完全没有毛病。

Reddit: 奇葩的911紧急求助电话
CREDIT: 123RF

UncomfortableChuckle:
我妈曾当过20多年的911调度员。她跟我讲过一个奇怪的求助电话,一开始,电话那头并没有说话声音,只能听得到呼吸声。我妈一直在问问题,让他回答“是”或“否”,想要知道究竟发生了什么。最后那边的人终于吐出了几个字,他说想要伤害他的人还在现场,于是警员们都带上枪过去了。不过,他只说那个人还在那里,但没说那个人已经死了。

最后他们发现,这个人之所以讲不了话,是因为他的喉咙被割开了,而且还是他自己割的。这是为了让他自己看起来像是正当防卫,嗯,他杀了他的老婆。

HonestWill:
这是我听到过的事情,不是打给911的,但也差不多。紧急医疗服务站(EMS)接到了一个电话,有个男的说,有好多土豆钻进了他的直肠里面。而且不是红皮土豆,是棕色的大个的那种。

最好笑的是,这个男人是这样解释的:“我在浴缸里洗土豆,脚底打滑摔了一跤,那些土豆就跑进去了。” O_O exo me?

本文译自 reddit,由译者 蛋奶 基于创作共用协议(BY-NC)发布。
--

※ 来源:·水木社区 http://m.newsmth.net·[FROM: 121.195.114.*]
24 Nov 03:58

CentOS 7 Nginx配置Let’s Encrypt SSL证书

by 标点符

去年购买的阿里云到期了,由于阿里云续费比新买贵很多,所以重现买了一台虚拟机,迁移过程中需要重新配置Let’s Encrypt证书,在执行过程中发现了一些问题,经过几个小时的摸索,终于搞定。

安装Let’s Encrypt证书一般的流程

yum install epel-release -y
yum install certbot -y

然后执行:

certbot certonly --webroot -w /home/www/www.biaodianfu.com -d www.biaodianfu.com -m biaodianfu@email.com --agree-tos

相关参数含义:

  • –webroot是运行模式
    • standalone模式:需要停止当前的 web server 服务,让出 80 端口,由客户端内置的 web server 启动与Let’ s Encrypt通信。
    • webroot模式:不需要停止当前 web server,但需要在域名根目录下创建一个临时目录,并要保证外网通过域名可以访问这个目录。
  • -w 指定网站所在目录
  • -d 指定网站域名
  • -m 指定联系邮箱,填写真实有效的,letsencrypt会在证书在过期以前发送预告的通知邮件
  • –agree-tos 表示接受相关协议

使用webroot模式,Certbot在验证服务器域名的时候,会生成一个随机文件,然后Certbot的服务器会通过HTTP访问你的这个文件,因此要确保你的 Nginx 配置好,以便可以访问到这个文件。

因为默认LNMP的虚拟主机里是禁止 . 开头的隐藏文件及目录的,所以访问http://www.biaodianfu.com/.well-known/acme-challenge/**** 这个链接的话返回403错误,所以必须在nginx配置的server节点下添加

location ~ /.well-known {
    allow all;
}

最终的配置文件如下:

server {
    listen       80;
    server_name  biaodainfu.com www.biaodianfu.com;
    index index.html index.htm index.php;
    charset utf-8;
 
    root   /home/www/www.biaodianfu.com;
    
    location / {
        try_files $uri $uri/ =404;
    }
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
 
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass php-fpm;
        #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    
    location ~ .*.(gif|jpg|jpeg|png|bmp|swf|flv|mp3|wma)$
    {
        expires      30d;
    }
    
    location ~ .*.(js|css)$
    {
        expires      12h;
    }
	
    location ~ /.well-known {
        allow all;
    }
}

重新nginx后执行申请证书的操作,正常情况下可以看到如下的显示内容:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem. Your cert will
   expire on 2018-02-25. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you lose your account credentials, you can recover through
   e-mails sent to biaodianfu@email.com.
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

完成后,再配置nginx服务器,将服务器配置成支持https的访问。

server {
  listen 80;
  server_name biaodianfu.com www.biaodianfu.com;
  return 301 https://www.biaodianfu.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name  biaodainfu.com www.biaodianfu.com;
    index index.html index.htm index.php;
    charset utf-8;

    root   /home/www/www.biaodianfu.com;

    ssl_certificate /etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.biaodianfu.com/privkey.pem;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass php-fpm;
        #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    
    location ~ .*.(gif|jpg|jpeg|png|bmp|swf|flv|mp3|wma)$
    {
        expires      30d;
    }
    
    location ~ .*.(js|css)$
    {
        expires      12h;
    }
    
    location = /favicon.ico {
	log_not_found off;
	access_log off;
    }
    
    location ~ /.well-known {
        allow all;
    }
}

 

以上为一般的步骤与过程,现在在执行centos 7.2时并没有遇到什么问题,这次使用的是centos 7.4却发生了问题。

解决证书安装中的问题

问题一:ImportError: No module named ‘requests.packages.urllib3’

原因是系统自带的requests的版本太低,参照这个地址上的临时解决方案:

pip install requests urllib3 pyOpenSSL --force --upgrade

执行完引发第二个问题:ImportError: ‘pyOpenSSL’ module missing required functionality. Try upgrading to v0.14 or newer.

主要原因是RHEL/CentOS的官方源和epel源的pyOpenSSL版本太旧了,新版的certbot依赖于高版本的pyOpenSSL库,从而失败。

解决方案,卸载epel中的certbot和PyOpenSSL,使用pip进行安装certbot。

pip search certbot
yum remove certbot pyOpenSSL
pip install certbot

pip install certbot。 如果碰到了Python.h或者pyconfig.h找不到的错误,可以安装Python的devel包: yum install -y python-devel;再次运行命令,提示找不到opensslv.h头文件,再安装OpenSSL的devel包: yum install -y openssl-devel;再次运行pip install certbot命令,成功安装certbot。

完成后执行

certbot certificates
  进行验证。输出正常,说明pip安装了最新版的certbot,并且能正确运行。

证书的自动更新

由于这个证书的时效只有 90 天,我们需要设置自动更新的功能,帮我们自动更新证书的时效。首先先在命令行模拟证书更新:

certbot renew --dry-run

模拟更新成功的效果如下:

[root@iZuf64dhkm7u57qfwrrhw6Z ~]# certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/www.biaodianfu.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for www.biaodianfu.com
Waiting for verification...
Cleaning up challenges

-------------------------------------------------------------------------------
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
-------------------------------------------------------------------------------

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
[root@iZuf64dhkm7u57qfwrrhw6Z ~]#

在无法确认你的 nginx 配置是否正确时,一定要运行模拟更新命令,确保certbot和服务器通讯正常。使用 crontab -e 的命令来启用自动任务,命令行:

crontab -e

添加配置:(每隔两个月凌晨2:30自动执行证书更新操作)后保存退出。

30 2 * */2 * /usr/bin/certbot renew --quiet && /bin/systemctl restart nginx

查看证书有效期的命令:

openssl x509 -noout -dates -in /etc/letsencrypt/live/www.biaodianfu.com/cert.pem

测试服务器 SSL 安全性

Qualys SSL Labs 提供了全面的 SSL 安全性测试,填写你的网站域名,给自己的 HTTPS 配置打个分。理想情况下得分是A+,如果你和我一样获得的是A-那么还有很多的改善空间。另外又扑云也有一个测试https的工具:https://www.upyun.com/https

相关改进:

1、生成Perfect Forward Security(PFS)键值

mkdir /etc/ssl/private/ -p
cd /etc/ssl/private/
openssl dhparam 2048 -out dhparam.pem

Perfect Forward Security(PFS),中文翻译成完美前向保密,2014年时候,由于心血漏洞(存在服务器私钥泄漏的可能),没有使用前向保密的站点,加密通信的数据可以通过私钥来解密,导致信息泄漏,这使得前向保密被重视起来。总的来说会更加安全,不能获得A+的评分主要原因也是因为它。(生成的时间有点长)

2、更新配置文件

# https://mozilla.github.io/server-side-tls/ssl-config-generator/
server {
    listen 80;
    server_name biaodianfu.com www.biaodianfu.com;
    return 301 https://www.biaodianfu.com$request_uri;
}
server {
    listen 443 ssl http2;
    server_name  biaodainfu.com www.biaodianfu.com;
    index index.html index.htm index.php;
    charset utf-8;
	
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;

    root   /home/www/www.biaodianfu.com;

    ssl_certificate /etc/letsencrypt/live/www.biaodianfu.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.biaodianfu.com/privkey.pem;
	
	ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

	# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /etc/ssl/private/dhparam.pem;

	# intermediate configuration. tweak to your needs.
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    # 一般推荐使用的ssl_ciphers值: https://wiki.mozilla.org/Security/Server_Side_TLS
    ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;
	
    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;
	
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass php-fpm;
        #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    
    location ~ .*.(gif|jpg|jpeg|png|bmp|swf|flv|mp3|wma)$
    {
        expires      30d;
    }
    
    location ~ .*.(js|css)$
    {
        expires      12h;
    }
    
    location = /favicon.ico {
	    log_not_found off;
	    access_log off;
    }
    
    location ~ /.well-known {
        allow all;
    }
}

其他参考:

22 Nov 06:10

大连地铁时报11.20

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报11.20
发信站: 水木社区 (Mon Nov 20 21:04:16 2017), 站内

兄弟,一首凉凉送给你

我在网上发了张自拍,很快就有一个妹子私聊我:“你真的这么帅吗?”我立刻给她发了一张没有美颜的照片。她依旧不信,让我拍身份证,我也拍了。她还是不信,让我拍一下反面,看看是不是真的,我又拍了。她仍然不信,让我用手拿着身份证对比着拍,我拍了。终于,她被我的英俊打动,跟我要电话,我激动得不得了,把号码发给了她,她就再没联系过我。最近几天,我接到了好多小额贷款要账的电话,想问问大家是什么情况?

我觉得当代居住环境有点太冷漠了。以前在农村,家里缺点啥,邻居之间上门借一借就都有了,有啥好吃的也不藏着掖着,会挨家给邻居们也分点。我记得我小时候在家挨打,还有一大帮邻居过来劝架呢,可现在不行了!昨天我爸揍了我有半个小时,邻居一点动静都没有,可以说是世态炎凉了。

记得有一次相亲,女方是我哥们的表妹。在相亲前哥们跟我说,他表妹特别看重第一印象,要是比较满意的话,就会跟对方聊一聊,不满意的话就会直接问对方有没有车房和存款,用这样的问题刁难对方,我谨记在心。相亲那天,他表妹看了我两三秒,开口问:“你有别墅吗?”我……

我刚买房那阵,要办各种手续证明文件、办贷款,然后交房接房、联系装修、跑建材市场,为了还房贷,我除了忙工作,还要接私活。我妈不想看到我这么累,于是出门旅游去了……

朋友被他家狗咬了,我们去探望。见到我们,他声泪俱下:“昨天晚上,感觉一个人喝酒没劲,就让它陪了两盅,没想到它酒品不行啊。”

我上小学一年级那年的教师节,班里有个脑回路很清奇的同学,叠了两个金元宝送给班主任。后来都五年级了,他还没当上少先队员。

在火车上听旁边一群年轻人聊天,说的是哪个地方的菜好吃,川湘鲁粤什么的。一个挺漂亮的女孩说:“我不爱吃湘菜。”旁边一个很久没插上话的男生立马接道:“我也是!还有生姜!”

冬天太冷了,我对老婆说:“夏天有空调,有冰激凌,我还是喜欢夏天,不喜欢冬天。”她说:“你喜欢夏天还不是因为街上的美女夏天穿得少?”我简直要疯了,女人所谓的第六感也太准了吧!



神句 ONE

冬天到了,我折起来后想想又放下的裤脚,就是我逝去的青春。

我们每个人都是梦想家,当梦走了,就只剩想家了。

如果武侠世界里最强者是扫地僧,那么机器人界里的最强者想必是扫地机器人了。

万死不辞:每天被气死一万次,但仍然不辞职。

22 Nov 06:09

大连地铁时报11.19

by nzhth
发信人: nzhth (n站同号), 信区: Joke
标 题: 大连地铁时报11.19
发信站: 水木社区 (Mon Nov 20 06:37:22 2017), 站内

和熊孩子斗智斗勇那点事儿

20年前,那时的我身上只有5块钱,你嫌弃我没钱,离开了我。感谢你离开我,我看清了这社会有多现实。于是我变得有了上进心,努力工作,改变了所有的缺点。如今我的身价,足足翻了66倍,我现在想问问你,你后悔了吗?

你想一夜暴富吗?你想身家过亿吗?你想衣食无忧吗?你想生活不愁吗?如果你想,那和我在一起,我们俩一起想。

花椒:温中散寒,除湿止痛,治积食停饮;辣椒:驱寒止痢,增强食欲,促进消化;肥牛:补中益气,滋养脾胃,化痰息风、止咳止涎;肥羊:暖中补虚,开胃健身,养胆明目……所以如果你说想要吃比火锅更健康更养生的东西,那我是没办法了。

吃过最苦的,是她的喜糖。喝过最酸的,是她的喜酒。拿过最烫的,是她的喜贴。遇见最高兴的,是她的儿子长得像我。

我最近总是手脚冰凉,网上说是肾虚所致。我坚持健身、喝枸杞泡茶一段时间还是不见效,于是一咬牙把取暖费交了,病就好了。

有些人耳根子特别软,你说什么东西好,他就买了;你说哪好玩,他就去了。你以为人家是没主见吗?错,人家有钱。

以后在聚会上,有人问你“要不要帮你介绍对象”时,你可以礼貌地微笑答道:“不必了,我已经有喜欢的人了,而且很多年来一直忘不掉他。”此时众人必然起哄,兴冲冲地追问你:“谁啊谁啊?”你再沉吟低眉,一字一句道:“可那个人啊,永远都是17岁了。”全场肯定顿时陷入死寂,从此再不会有人问你这个尴尬的问题……而没有人会知道你说的是柯南。

我去超市买东西,看到收银小妹长得挺漂亮,于是我就逗她:“老公、老爸、老妈,哪一个跟你没有血缘关系?”“老公。”收银小妹不假思索地答道。我赶紧笑咪咪地说:“哎,乖,老婆!”收银小妹羞怒嗔道:“呸!讨厌!”然后就我被她男朋友打得脸都花了……哈哈,骗你们的,其实腿也被打断了。



神句 ONE

在夏天说喜欢冬天的人,是不是又悄悄开始喜欢夏天了?

我的朋友很多,他们来自五湖四海。等我需要帮助的时候,他们又回去了。

俄罗斯方块教导我们:最受欢迎的总是那个又高又瘦的。

这世上没有谁离不开谁,就算是一条鱼离开水,也能烤着吃。

(部分笑话取自网络,如有侵权请联系删除)
--

※ 来源:·水木社区 http://m.newsmth.net·[FROM: 123.151.77.*]