重复性压迫损伤 Repetitive Strain Injury （RSI）是职业性损伤综合症，非特异性手臂疼痛或工作引起的上肢障碍。RSI 是由于过度使用双手从事重复性任务导致的，如打字、书写和使用鼠标. 不幸的是，大部分人不了解什么是 RSI 以及它的危害有多大。你可以使用名叫 Workrave 的开源软件轻松的预防 RSI。RSI 有哪些症状？我从这个页面引用过来的，看看哪些你被说中了：疲惫缺乏忍耐力？手掌及上肢乏力疼痛麻木甚至失去知觉？沉重：你有没有感觉手很沉？笨拙: 你有没有感觉抓不紧东西？你有没有感觉手上无力？很难打开罐子或切菜无力？缺乏协调和控制？手总是冰凉的？健康意识有待提高？稍不注意身体就发现有毛病了。是否过敏？频繁的自我按摩（潜意识的）？共鸣的疼痛？当别人在谈论手痛的时候，你是否也感觉到了手疼？如何减少发展为 RSI 的风险使用计算机的时候每隔 30 分钟间隔休息一下。借助软件如 workrave 预防 RSI。有规律的锻炼可以预防各种损伤，包括 RSI。使用合理的姿势。调整你的电脑桌和椅子使身体保持一个肌肉放松状态。WorkraveWorkrave 是一款预防计算机用户发展为 RSI 或近视的自由开源软件。软件会定期锁屏为一个动画： “Workrave 小姐”，引导用户做各种伸展运动并敦促其休息一下。这个软件经常提醒你暂停休息一下，并限制你每天的限度。程序可以运行在 MS-Window、Linux 以及类 UNIX 操作系统下。安装 workrave在 Debian/Ubuntu Linux 系统运行以下 apt 命令/apt-get 命令：$ sudo apt-get install workraveFedora Linux 发行版用户运行以下 dnf 命令：$ sudo dnf install workraveRHEL/CentOS Linux 用户可以启动 EPEL 仓库并用 yum 命令安装：### [ **在CentOS/RHEL 7.x 及衍生版本上测试** ] ### $ sudo yum install epel-release $ sudo yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm $ sudo yum install workraveArch Linux 用户运行以下 pacman 命令来安装：$ sudo pacman -S workraveFreeBSD 用户可用以下 pkg 命令安装：# pkg install workraveOpenBSD 用户可用以下 pkg\_add 命令安装：$ doas pkg_add workrave如何配置 workraveWorkrave 以一个小程序运行，它的用户界面位于面板中。你可以为 workrave 增加一个面板来控制软件的动作和外观。增加一个新 workrave 对象到面板：在面板空白区域右键，打开面板弹出菜单选择新增到面板新增面板对话框打开，在加载器顶部，可以看到可用的面板对象按照字母排列。选中 workrave 程序并单击新增。图 01：新增 workrave 对象到面板如果修改 workrave 对象的属性，执行以下步骤：右键 workrave 对象打开面板对象弹出选中偏好。使用属性对话框修改对应属性图 02：修改 Workrave 对象属性Workrave 运行展示主窗口显示下一次提醒休息的剩余时间，这个窗口可以关闭，时间提示窗口会显示在面板上。图 03：时间计数器图 04：Workrave 小姐 - 引导你做伸展运动的动画休息提示窗口，请求你暂停一下工作：图 05：休息提示倒计时图 06：你可以跳过休息参考链接:Workrave 项目 主页pokoy 防止 RSI 和其他计算机压力的轻量级守护进程GNOME3 下的 Pomodoro 计数器RSI 的维基百科关于作者作者是 nixCraft 创始人，经验丰富的系统管理员，同时也是一个 Linux/Unix 系统下的 shell 脚本培训师。他曾服务于全球客户，并与多个行业合作包括 IT、教育、国防和航天研究，以及非盈利机构。可以在 Twitter、Facebook、Google+ 上关注他。via: https://www.cyberciti.biz/tips/repetitive-strain-injury-prevention-software.html作者：Vivek Gite 译者：guevaraya 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
手册页（man）是由系统管理员和 IT 技术开发人员写的，更多的是为了作为参考而不是教你如何使用。手册页对于已经熟悉使用 Linux、Unix 和 BSD 操作系统的人来说是非常有用的。如果你仅仅需要知道某个命令或者某个配置文件的格式那么你可以使用手册页，但是手册页对于 Linux 新手来说并没有太大的帮助。想要通过使用手册页来学习一些新东西不是一个好的选择。这里有将提供 30 个学习 Linux 和 Unix 操作系统的最佳在线网页文档。值得一提的是，相对于 Linux，BSD 的手册页更好。1：Red Hat Enterprise Linux（RHEL）RHEL 是由红帽公司开发的面向商业市场的 Linux 发行版。红帽的文档是最好的文档之一，涵盖从 RHEL 的基础到一些高级主题比如安全、SELinux、虚拟化、目录服务器、服务器集群、JBOSS 应用程序服务器、高性能计算（HPC）等。红帽的文档已经被翻译成 22 种语言，发布成多页面 HTML、单页面 HTML、PDF、EPUB 等文件格式。好消息同样的文档你可以用于 Centos 和 Scientific Linux（社区企业发行版）。这些文档随操作系统一起下载提供，也就是说当你没有网络的时候，你也可以使用它们。RHEL 的文档涵盖从安装到配置器群的所有内容。唯一的缺点是你需要成为付费用户。当然这对于企业公司来说是一件完美的事。RHEL 文档：HTML/PDF格式（LCTT 译注：此链接需要付费用户才可以访问）是否支持论坛：只能通过红帽公司的用户网站提交支持案例。关于 CentOS Wiki 和论坛的说明CentOS（ 社区企业操作系统 Community ENTerprise Operating System ）是由 RHEL 提供的自由源码包免费重建的。它为个人电脑或其它用途提供了可靠的、免费的企业级 Linux。你可以不用付出任何支持和认证费用就可以获得 RHEL 的稳定性。CentOS的 wiki 分为 Howto、技巧等等部分，链接如下：文档：wiki 格式是否支持论坛：是2：Arch 的 Wiki 和论坛Arch linux 是一个独立开发的 Linux 操作系统，它有基于 wiki 网站形式的非常不错的文档。它是由 Arch 社区的一些用户共同协作开发出来的，并且允许任何用户添加或修改内容。这些文档教程被分为几类比如说优化、软件包管理、系统管理、X window 系统还有获取安装 Arch Linux 等。它的官方论坛在解决许多问题的时候也非常有用。它有总共 4 万多个注册用户、超过 1 百万个帖子。 该 wiki 包含一些 其它 Linux 发行版也适用的通用信息。Arch 社区文档：Wiki 格式是否支持论坛：是3：Gentoo Linux Wiki 和论坛Gentoo Linux 基于 Portage 包管理系统。Gentoo Linux 用户根据它们选择的配置在本地编译源代码。多数 Gentoo Linux 用户都会定制自己独有的程序集。 Gentoo Linux 的文档会给你一些有关 Gentoo Linux 操作系统的说明和一些有关安装、软件包、网络和其它等主要出现的问题的解决方法。Gentoo 有对你来说 非常有用的论坛，论坛中有超过 13 万 4 千的用户，总共发了有 5442416 个文章。Gentoo 社区文档：手册 和 Wiki 格式是否支持论坛：是4：Ubuntu Wiki 和文档Ubuntu 是领先的台式机和笔记本电脑发行版之一。其官方文档由 Ubuntu 文档工程开发维护。你可以在从官方文档中查看大量的信息，比如如何开始使用 Ubuntu 的教程。最好的是，此处包含的这些信息也可用于基于 Debian 的其它系统。你可能会找到由 Ubuntu 的用户们创建的社区文档，这是一份有关 Ubuntu 的使用教程和技巧等。Ubuntu Linux 有着网络上最大的 Linux 社区的操作系统，它对新用户和有经验的用户均有助益。Ubuntu 社区文档：wiki 格式Ubuntu 官方文档：wiki 格式是否支持论坛：是5：IBM Developer WorksIBM Developer Works 为 Linux 程序员和系统管理员提供技术资源，其中包含数以百计的文章、教程和技巧来协助 Linux 程序员的编程工作和应用开发还有系统管理员的日常工作。IBM 开发者项目文档：HTML 格式是否支持论坛：是6：FreeBSD 文档和手册FreeBSD 的手册是由 FreeBSD 文档项目 FreeBSD Documentation Project 所创建的，它介绍了 FreeBSD 操作系统的安装、管理和一些日常使用技巧等内容。FreeBSD 的手册页通常比 GNU Linux 的手册页要好一点。FreeBSD 附带有全部最新手册页的文档。 FreeBSD 手册涵盖任何你想要的内容。手册包含一些通用的 Unix 资料，这些资料同样适用于其它的 Linux 发行版。FreeBSD 官方论坛会在你遇到棘手问题时给予帮助。FreeBSD 文档：HTML/PDF 格式是否支持论坛：是7：Bash Hackers Wiki这是一个对于 bash 使用者来说非常好的资源。Bash 使用者的 wiki 是为了归纳所有类型的 GNU Bash 文档。这个项目的动力是为了提供可阅读的文档和资料来避免用户被迫一点一点阅读 Bash 的手册，有时候这是非常麻烦的。Bash Hackers Wiki 分为各个类，比如说脚本和通用资料、如何使用、代码风格、bash 命令格式和其它。Bash 用户教程：wiki 格式8：Bash 常见问题这是一个为 bash 新手设计的一个 wiki。它收集了 IRC 网络的 #bash 频道里常见问题的解决方法，这些解决方法是由该频道的普通成员提供。当你遇到问题的时候不要忘了在 BashPitfalls 部分检索查找答案。这些常见问题的解决方法可能会倾向于 Bash，或者偏向于最基本的 Bourne Shell，这决定于是谁给出的答案。大多数情况会尽力提供可移植的（Bourne）和高效的（Bash，在适当情况下）的两类答案。Bash 常见问题：wiki 格式9: Howtoforge - Linux 教程博客作者 Falko 在 Howtoforge 上有一些非常不错的东西。这个网站提供了 Linux 关于各种各样主题的教程，比如说其著名的“最佳服务器系列”，网站将主题分为几类，比如说 web 服务器、linux 发行版、DNS 服务器、虚拟化、高可用性、电子邮件和反垃圾邮件、FTP 服务器、编程主题还有一些其它的内容。这个网站也支持德语。Howtoforge： html 格式是否支持论坛：是10：OpenBSD 常见问题和文档OpenBSD 是另一个基于 BSD 的类 Unix 计算机操作系统。OpenBSD 是由 NetBSD 项目分支而来。OpenBSD 因高质量的代码和文档、对软件许可协议的坚定立场和强烈关注安全问题而闻名。OpenBSD 的文档分为多个主题类别，比如说安装、包管理、防火墙设置、用户管理、网络、磁盘和磁盘阵列管理等。OpenBSD：html 格式是否支持论坛：否，但是可以通过 邮件列表 来咨询11: Calomel - 开源研究和参考文档这个极好的网站是专门作为开源软件和那些特别专注于 OpenBSD 的软件的文档来使用的。这是最简洁的引导网站之一，专注于高质量的内容。网站内容分为多个类，比如说 DNS、OpenBSD、安全、web 服务器、Samba 文件服务器、各种工具等。Calomel 官网：html 格式是否支持论坛：否12：Slackware 书籍项目Slackware Linux 是我的第一个 Linux 发行版。Slackware 是基于 Linux 内核的最早的发行版之一，也是当前正在维护的最古老的 Linux 发行版。 这个发行版面向专注于稳定性的高级用户。 Slackware 也是很少有的的“类 Unix” 的 Linux 发行版之一。官方的 Slackware 手册是为了让用户快速开始了解 Slackware 操作系统的使用方法而设计的。 这不是说它将包含发行版的每一个方面，而是为了说明它的实用性和给使用者一些有关系统的基础工作使用方法。手册分为多个主题，比如说安装、网络和系统配置、系统管理、包管理等。Slackware Linux 手册：html 格式、pdf 和其它格式是否支持论坛：是13：Linux 文档项目（TLDP） Linux 文档项目 Linux Documentation Project 旨在给 Linux 操作系统提供自由、高质量文档。网站是由志愿者创建和维护的。网站分为具体主题的帮助、由浅入深的指南等。在此我想推荐一个非常好的文档，这个文档既是一个教程也是一个 shell 脚本编程的参考文档，对于新用户来说这个 HOWTO 的列表也是一个不错的开始。Linux 文档工程 支持多种查阅格式是否支持论坛：否14：Linux Home NetworkingLinux Home Networking 是学习 linux 的另一个比较好的资源，这个网站包含了 Linux 软件认证考试的内容比如 RHCE，还有一些计算机培训课程。网站包含了许多主题，比如说网络、Samba 文件服务器、无线网络、web 服务器等。Linux home networking 可通过 html 格式和 PDF（少量费用）格式查阅是否支持论坛：是15：Linux Action ShowLinux Action Show（LAS) 是一个关于 Linux 的播客。这个网站是由 Bryan Lunduke、Allan Jude 和 Chris Fisher 共同管理的。它包含了 FOSS 的最新消息。网站内容主要是评论一些应用程序和 Linux 发行版。有时候也会发布一些和开源项目著名人物的采访视频。Linux action show 支持音频和视频格式是否支持论坛：是16：CommandlinefuCommandlinefu 列出了各种有用或有趣的 shell 命令。这里所有命令都可以评论、讨论和投票（支持或反对）。对于所有 Unix 命令行用户来说是一个极好的资源。不要忘了查看评选出来的最佳命令。Commandlinefu 支持 html 格式是否支持论坛：否17：Debian 管理技巧和资源这个网站包含一些只和 Debian GNU/Linux 相关的主题、技巧和教程，特别是包含了关于系统管理的有趣和有用的信息。你可以在上面贡献文章、建议和问题。提交了之后不要忘记查看最佳文章列表里有没有你的文章。Debian 系统管理 支持 html 格式是否支持论坛：否18: Catonmat - Sed、Awk、Perl 教程这个网站是由博客作者 Peteris Krumins 维护的。主要关注命令行和 Unix 编程主题，比如说 sed 流编辑器、perl 语言、AWK 文本处理工具等。不要忘了查看 sed 介绍、sed 含义解释，还有命令行历史的权威介绍。catonmat 支持 html 格式是否支持论坛：否19：Debian GNU/Linux 文档和 WikiDebian 是另外一个 Linux 操作系统，其主要使用的软件以 GNU 许可证发布。Debian 因严格坚持 Unix 和自由软件的理念而闻名，它也是很受欢迎并且有一定影响力的 Linux 发行版本之一。 Ubuntu 等发行版本都是基于 Debian 的。Debian 项目以一种易于访问的形式提供给用户合适的文档。这个网站分为 Wiki、安装指导、常见问题、支持论坛几个模块。Debian GNU/Linux 文档 支持 html 和其它格式访问Debian GNU/Linux wiki是否支持论坛：是20：Linux SeaLinux Sea 这本书提供了比较通俗易懂但充满技术（从最终用户角度来看）的 Linux 操作系统的介绍，使用 Gentoo Linux 作为例子。它既没有谈论 Linux 内核或 Linux 发行版的历史，也没有谈到 Linux 用户不那么感兴趣的细节。Linux sea 支持 html 格式访问是否支持论坛: 否21：O'reilly CommonsO'reilly 出版社发布了不少 wiki 格式的文章。这个网站主要是为了给那些喜欢创作、参考、使用、修改、更新和修订来自 O'Reilly 或者其它来源的素材的社区提供资料。这个网站包含关于 Ubuntu、PHP、Spamassassin、Linux 等的免费书籍。Oreilly commons 支持 Wiki 格式是否支持论坛：否22：Ubuntu 袖珍指南这本书的作者是 Keir Thomas。这本指南（或者说是书籍）对于所有 ubuntu 用户来说都值得一读。这本书旨在向用户介绍 Ubuntu 操作系统和其所依赖的理念。你可以从官网下载这本书的 PDF 版本，也可以在亚马逊买印刷版。Ubuntu pocket guide 支持 PDF 和印刷版本.是否支持论坛：否23: Linux: Rute User’s Tutorial and Exposition这本书涵盖了 GNU/LINUX 系统管理，主要是对主流的发布版本比如红帽和 Debian 的说明，可以作为新用户的教程和高级管理员的参考。这本书旨在给出 Unix 系统的每个面的简明彻底的解释和实践性的例子。想要全面了解 Linux 的人都不需要再看了 —— 这里没有涉及的内容。Linux: Rute User’s Tutorial and Exposition 支持印刷版和 html 格式是否支持论坛：否24：高级 Linux 编程这本书是写给那些已经熟悉了 C 语言编程的程序员的。这本书采取一种教程式的方式来讲述大多数在 GNU/Linux 系统应用编程中重要的概念和功能特性。如果你是一个已经对 GNU/Linux 系统编程有一定经验的开发者，或者是对其它类 Unix 系统编程有一定经验的开发者，或者对 GNU/Linux 软件开发有兴趣，或者想要从非 Unix 系统环境转换到 Unix 平台并且已经熟悉了优秀软件的开发原则，那你很适合读这本书。另外，你会发现这本书同样适合于 C 和 C++ 编程。高级 Linux 编程 支持印刷版和 PDF 格式是否支持论坛：否25: LPI 101 Course NotesLPIC 1、2、3 级是用于 Linux 系统管理员认证的。这个网站提供了 LPI 101 和 LPI 102 的测试训练。这些是根据 GNU 自由文档协议 GNU Free Documentation Licence （FDL）发布的。这些课程材料基于 Linux 国际专业协会的 LPI 101 和 102 考试的目标。这个课程是为了提供给你一些必备的 Linux 系统的操作和管理的技能。LPI 训练手册 支持 PDF 格式是否支持论坛：否26: FLOSS 手册FLOSS 手册是一系列关于自由和开源软件以及用于创建它们的工具和使用这些工具的社区的手册。社区的成员包含作者、编辑、设计师、软件开发者、积极分子等。这些手册中说明了怎样安装使用一些自由和开源软件，如何操作（比如设计和维持在线安全）开源软件，这其中也包含如何使用或支持自由软件和格式的自由文化服务手册。你也会发现关于一些像 VLC、 Linux 视频编辑、 Linux、 OLPC / SUGAR、 GRAPHICS 等软件的手册。你可以浏览 FOSS 手册 支持 Wiki 格式是否支持论坛：否27：Linux 入门包刚接触 Linux 这个美好世界？想找一个简单的入门方式？你可以下载一个 130 页的指南来入门。这个指南会向你展示如何在你的个人电脑上安装 Linux，如何浏览桌面，掌握最主流行的 Linux 程序和修复可能出现的问题的方法。Linux 入门包支持 PDF 格式是否支持论坛：否28：Linux.com - Linux 信息来源Linux.com 是 Linux 基金会的一个产品。这个网站上提供一些新闻、指南、教程和一些关于 Linux 的其它信息。利用全球 Linux 用户的力量来通知、写作、连接 Linux 的事务。在线访问 Linux.com是否支持论坛：是29: LWNLWN 是一个注重自由软件及用于 Linux 和其它类 Unix 操作系统的软件的网站。这个网站有周刊、基本上每天发布的单独文章和文章的讨论对话。该网站提供有关 Linux 和 FOSS 相关的开发、法律、商业和安全问题的全面报道。在线访问 lwn.net是否支持论坛：否30：Mac OS X 相关网站与 Mac OS X 相关网站的快速链接：Mac OS X 提示 —— 这个网站专用于苹果的 Mac OS X Unix 操作系统。网站有很多有关 Bash 和 Mac OS X 的使用建议、技巧和教程Mac OS 开发库 —— 苹果拥有大量和 OS X 开发相关的优秀系列内容。不要忘了看一看 bash shell 脚本入门Apple 知识库 - 这个有点像 RHN 的知识库。这个网站提供了所有苹果产品包括 OS X 相关的指南和故障报修建议。30: NetBSD（LCTT 译注：没错，又一个 30）NetBSD 是另一个基于 BSD Unix 操作系统的自由开源操作系统。NetBSD 项目专注于系统的高质量设计、稳定性和性能。由于 NetBSD 的可移植性和伯克利式的许可证，NetBSD 常用于嵌入式系统。这个网站提供了一些 NetBSD 官方文档和各种第三方文档的链接。在线访问 netbsd 文档，支持 html、PDF 格式是否支持论坛：否你要做的事这是我的个人列表，这可能并不完全是权威的，因此如果你有你自己喜欢的独特 Unix/Linux 网站，可以在下方参与评论分享。// 图片来源: Flickr photo PanelSwitchman。一些连接是用户在我们的 Facebook 粉丝页面上建议添加的。关于作者作者是 nixCraft 的创建者和经验丰富的系统管理员以及 Linux 操作系统 / Unix shell 脚本的培训师。它曾与全球客户及各行各业合作，包括 IT、教育，国防和空间研究以及一些非营利部门。可以关注作者的 Twitter、Facebook、Google+。via: https://www.cyberciti.biz/tips/linux-unix-bsd-documentations.html作者：Vivek Gite 译者：ScarboroughCoral 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
Bash 脚本中如何使用 here 文档将数据写入文件
here 文档 here document （LCTT 译注：here 文档又称作 heredoc ）不是什么特殊的东西，只是一种 I/O 重定向方式，它告诉 bash shell 从当前源读取输入，直到读取到只有分隔符的行。这对于向 ftp、cat、echo、ssh 和许多其他有用的 Linux/Unix 命令提供指令很有用。 此功能适用于 bash 也适用于 Bourne、Korn、POSIX 这三种 shell。here 文档语法语法是：command <<EOF cmd1 cmd2 arg1 EOF或者允许 shell 脚本中的 here 文档使用 EOF<<- 以自然的方式缩进：command <<-EOF msg1 msg2 $var on line EOF或者command <<'EOF' cmd1 cmd2 arg1 $var won't expand as parameter substitution turned off by single quoting EOF或者 重定向并将其覆盖 到名为 my_output_file.txt 的文件中：command <<EOF > my_output_file.txt mesg1 msg2 msg3 $var on $foo EOF或重定向并将其追加到名为 my_output_file.txt 的文件中：command <<EOF >> my_output_file.txt mesg1 msg2 msg3 $var on $foo EOF示例以下脚本将所需内容写入名为 /tmp/output.txt 的文件中：#!/bin/bash OUT=/tmp/output.txt echo "Starting my script..." echo "Doing something..." cat <<EOF >$OUT Status of backup as on $(date) Backing up files $HOME and /etc/ EOF echo "Starting backup using rsync..."你可以使用cat命令查看/tmp/output.txt文件：$ cat /tmp/output.txt示例输出： Status of backup as on Thu Nov 16 17:00:21 IST 2017 Backing up files /home/vivek and /etc/禁用路径名/参数/变量扩展、命令替换、算术扩展像 $HOME 这类变量和像 $(date) 这类命令在脚本中会被解释为替换。 要禁用它，请使用带有 'EOF' 这样带有单引号的形式，如下所示：#!/bin/bash OUT=/tmp/output.txt echo "Starting my script..." echo "Doing something..." # No parameter and variable expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. # If any part of word is quoted, the delimiter is the result of quote removal on word, and the lines in the here-document # are not expanded. So EOF is quoted as follows cat <<'EOF' >$OUT Status of backup as on $(date) Backing up files $HOME and /etc/ EOF echo "Starting backup using rsync..."你可以使用 cat 命令查看 /tmp/output.txt 文件：$ cat /tmp/output.txt示例输出： Status of backup as on $(date) Backing up files $HOME and /etc/ 关于 tee 命令的使用语法是：tee /tmp/filename <<EOF >/dev/null line 1 line 2 line 3 $(cmd) $var on $foo EOF或者通过在单引号中引用 EOF 来禁用变量替换和命令替换：tee /tmp/filename <<'EOF' >/dev/null line 1 line 2 line 3 $(cmd) $var on $foo EOF这是我更新的脚本：#!/bin/bash OUT=/tmp/output.txt echo "Starting my script..." echo "Doing something..." tee $OUT <<EOF >/dev/null Status of backup as on $(date) Backing up files $HOME and /etc/ EOF echo "Starting backup using rsync..."关于内存 here 文档的使用这是我更新的脚本：#!/bin/bash OUT=/tmp/output.txt ## in memory here docs ## thanks https://twitter.com/freebsdfrau exec 9<<EOF Status of backup as on $(date) Backing up files $HOME and /etc/ EOF ## continue echo "Starting my script..." echo "Doing something..." ## do it cat <&9 >$OUT echo "Starting backup using rsync..."via: https://www.cyberciti.biz/faq/using-heredoc-rediection-in-bash-shell-script-to-write-to-file/作者：Vivek Gite 译者：Flowsnow 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
我是从 Linux 迁移过来的 FreeBSD 新用户，Linux 中使用的是 netfilter 防火墙框架（LCTT 译注：netfilter 是由 Rusty Russell 提出的 Linux 2.4 内核防火墙框架）。那么在 FreeBSD 上，我该如何设置 PF 防火墙，来保护只有一个公共 IP 地址和端口的 web 服务器呢？PF 是 包过滤器 packet filter 的简称。它是为 OpenBSD 开发的，但是已经被移植到了 FreeBSD 以及其它操作系统上。PF 是一个包状态过滤引擎。在这篇教程中，我将向你展示如何在 FreeBSD 10.x 以及 11.x 中设置 PF 防火墙，从而来保护 web 服务器。第一步：开启 PF 防火墙你需要把下面这几行内容添加到文件 /etc/rc.conf 文件中：# echo 'pf_enable="YES"' >> /etc/rc.conf # echo 'pf_rules="/usr/local/etc/pf.conf"' >> /etc/rc.conf # echo 'pflog_enable="YES"' >> /etc/rc.conf # echo 'pflog_logfile="/var/log/pflog"' >> /etc/rc.conf在这里：pf_enable="YES" - 开启 PF 服务pf_rules="/usr/local/etc/pf.conf" - 从文件 /usr/local/etc/pf.conf 中读取 PF 规则pflog_enable="YES" - 为 PF 服务打开日志支持pflog_logfile="/var/log/pflog" - 存储日志的文件，即日志存于文件 /var/log/pflog 中第二步：在 /usr/local/etc/pf.conf 文件中创建防火墙规则输入下面这个命令打开文件（超级用户模式下）：# vi /usr/local/etc/pf.conf在文件中添加下面这些 PF 规则集：# vim: set ft=pf # /usr/local/etc/pf.conf ## 设置公共端口 ## ext_if="vtnet0" ## 设置服务器公共 IP 地址 ## ext_if_ip="172.xxx.yyy.zzz" ## 设置并删除下面这些公共端口上的 IP 范围 ## martians = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, \ 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \ 0.0.0.0/8, 240.0.0.0/4 }" ## 设置 http(80)/https (443) 端口 ## webports = "{http, https}" ## 启用下面这些服务 ## int_tcp_services = "{domain, ntp, smtp, www, https, ftp, ssh}" int_udp_services = "{domain, ntp}" ## 跳过回环端口 - 跳过端口上的所有 PF 处理 ## set skip on lo ## 设置 PF 应该统计的端口信息，如发送/接收字节数，通过/禁止的包的数目 ## set loginterface $ext_if ## 设置默认策略 ## block return in log all block out all # 基于 IP 分片的错误处理来防御攻击 scrub in all # 删除所有不可达路由地址 block drop in quick on $ext_if from $martians to any block drop out quick on $ext_if from any to $martians ## 禁止欺骗包 antispoof quick for $ext_if # 打开 SSH 端口，SSH 服务仅从 VPN IP 139.xx.yy.zz 监听 22 号端口 # 出于安全原因，我不允许/接收 SSH 流量 pass in quick on $ext_if inet proto tcp from 139.xxx.yyy.zzz to $ext_if_ip port = ssh flags S/SA keep state label "USER_RULE: Allow SSH from 139.xxx.yyy.zzz" ## 使用下面这些规则来为所有来自任何 IP 地址的用户开启 SSH 服务 # ## pass in inet proto tcp to $ext_if port ssh ### [ OR ] ### ## pass in inet proto tcp to $ext_if port 22 # Allow Ping-Pong stuff. Be a good sysadmin pass inet proto icmp icmp-type echoreq # All access to our Nginx/Apache/Lighttpd Webserver ports pass proto tcp from any to $ext_if port $webports # 允许重要的发送流量 pass out quick on $ext_if proto tcp to any port $int_tcp_services pass out quick on $ext_if proto udp to any port $int_udp_services # 在下面添加自定义规则保存并关闭文件。欢迎来参考我的规则集。如果要检查语法错误，可以运行：# service pf check或/etc/rc.d/pf check或# pfctl -n -f /usr/local/etc/pf.conf第三步：开始运行 PF 防火墙命令如下。请小心，如果是基于 SSH 的会话，你可能会和服务器断开连接。开启 PF 防火墙：# service pf start停用 PF 防火墙：# service pf stop检查语法错误：# service pf check重启服务：# service pf restart查看 PF 状态：# service pf status示例输出：Status: Enabled for 0 days 00:02:18 Debug: Urgent Interface Stats for vtnet0 IPv4 IPv6 Bytes In 19463 0 Bytes Out 18541 0 Packets In Passed 244 0 Blocked 3 0 Packets Out Passed 136 0 Blocked 12 0 State Table Total Rate current entries 1 searches 395 2.9/s inserts 4 0.0/s removals 3 0.0/s Counters match 19 0.1/s bad-offset 0 0.0/s fragment 0 0.0/s short 0 0.0/s normalize 0 0.0/s memory 0 0.0/s bad-timestamp 0 0.0/s congestion 0 0.0/s ip-option 0 0.0/s proto-cksum 0 0.0/s state-mismatch 0 0.0/s state-insert 0 0.0/s state-limit 0 0.0/s src-limit 0 0.0/s synproxy 0 0.0/s map-failed 0 0.0/s开启/关闭/重启 pflog 服务的命令输入下面这些命令：# service pflog start # service pflog stop # service pflog restart第四步：pfctl 命令的简单介绍你需要使用 pfctl 命令来查看 PF 规则集和参数配置，包括来自 包过滤器 packet filter 的状态信息。让我们来看一下所有常见命令：显示 PF 规则信息# pfctl -s rules示例输出：block return in log all block drop out all block drop in quick on ! vtnet0 inet from 172.xxx.yyy.zzz/24 to any block drop in quick inet from 172.xxx.yyy.zzz/24 to any pass in quick on vtnet0 inet proto tcp from 139.aaa.ccc.ddd to 172.xxx.yyy.zzz/24 port = ssh flags S/SA keep state label "USER_RULE: Allow SSH from 139.aaa.ccc.ddd" pass inet proto icmp all icmp-type echoreq keep state pass out quick on vtnet0 proto tcp from any to any port = domain flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = ntp flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = smtp flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = http flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = https flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = ftp flags S/SA keep state pass out quick on vtnet0 proto tcp from any to any port = ssh flags S/SA keep state pass out quick on vtnet0 proto udp from any to any port = domain keep state pass out quick on vtnet0 proto udp from any to any port = ntp keep state显示每条规则的详细内容# pfctl -v -s rules在每条规则的详细输出中添加规则编号：# pfctl -vvsr show显示状态信息# pfctl -s state # pfctl -s state | more # pfctl -s state | grep 'something'如何在命令行中禁止 PF 服务# pfctl -d如何在命令行中启用 PF 服务# pfctl -e如何在命令行中刷新 PF 规则/NAT/路由表# pfctl -F all示例输出：rules cleared nat cleared 0 tables deleted. 2 states cleared source tracking entries cleared pf: statistics cleared pf: interface flags reset如何在命令行中仅刷新 PF 规则# pfctl -F rules如何在命令行中仅刷新队列# pfctl -F queue如何在命令行中刷新统计信息（它不是任何规则的一部分）# pfctl -F info如何在命令行中清除所有计数器# pfctl -z clear第五步：查看 PF 日志PF 日志是二进制格式的。使用下面这一命令来查看：# tcpdump -n -e -ttt -r /var/log/pflog示例输出：Aug 29 15:41:11.757829 rule 0/(match) block in on vio0: 86.47.225.151.55806 > 45.FOO.BAR.IP.23: S 757158343:757158343(0) win 52206 [tos 0x28] Aug 29 15:41:44.193309 rule 0/(match) block in on vio0: 5.196.83.88.25461 > 45.FOO.BAR.IP.26941: S 2224505792:2224505792(0) ack 4252565505 win 17520 (DF) [tos 0x24] Aug 29 15:41:54.628027 rule 0/(match) block in on vio0: 45.55.13.94.50217 > 45.FOO.BAR.IP.465: S 3941123632:3941123632(0) win 65535 Aug 29 15:42:11.126427 rule 0/(match) block in on vio0: 87.250.224.127.59862 > 45.FOO.BAR.IP.80: S 248176545:248176545(0) win 28200 <mss 1410,sackOK,timestamp 1044055305 0,nop,wscale 8> (DF) Aug 29 15:43:04.953537 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.7475: S 1164335542:1164335542(0) win 1024 Aug 29 15:43:05.122156 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.7475: R 1164335543:1164335543(0) win 1200 Aug 29 15:43:37.302410 rule 0/(match) block in on vio0: 94.130.12.27.18080 > 45.FOO.BAR.IP.64857: S 683904905:683904905(0) ack 4000841729 win 16384 <mss 1460> Aug 29 15:44:46.574863 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.7677: S 3451987887:3451987887(0) win 1024 Aug 29 15:44:46.819754 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.7677: R 3451987888:3451987888(0) win 1200 Aug 29 15:45:21.194752 rule 0/(match) block in on vio0: 185.40.4.130.55910 > 45.FOO.BAR.IP.80: S 3106068642:3106068642(0) win 1024 Aug 29 15:45:32.999219 rule 0/(match) block in on vio0: 185.40.4.130.55910 > 45.FOO.BAR.IP.808: S 322591763:322591763(0) win 1024 Aug 29 15:46:30.157884 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6511: S 2412580953:2412580953(0) win 1024 [tos 0x28] Aug 29 15:46:30.252023 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6511: R 2412580954:2412580954(0) win 1200 [tos 0x28] Aug 29 15:49:44.337015 rule 0/(match) block in on vio0: 189.219.226.213.22640 > 45.FOO.BAR.IP.23: S 14807:14807(0) win 14600 [tos 0x28] Aug 29 15:49:55.161572 rule 0/(match) block in on vio0: 5.196.83.88.25461 > 45.FOO.BAR.IP.40321: S 1297217585:1297217585(0) ack 1051525121 win 17520 (DF) [tos 0x24] Aug 29 15:49:59.735391 rule 0/(match) block in on vio0: 36.7.147.209.2545 > 45.FOO.BAR.IP.3389: SWE 3577047469:3577047469(0) win 8192 <mss 1460,nop,wscale 8,nop,nop,sackOK> (DF) [tos 0x2 (E)] Aug 29 15:50:00.703229 rule 0/(match) block in on vio0: 36.7.147.209.2546 > 45.FOO.BAR.IP.3389: SWE 1539382950:1539382950(0) win 8192 <mss 1460,nop,wscale 8,nop,nop,sackOK> (DF) [tos 0x2 (E)] Aug 29 15:51:33.880334 rule 0/(match) block in on vio0: 45.55.22.21.53510 > 45.FOO.BAR.IP.2362: udp 14 Aug 29 15:51:34.006656 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6491: S 151489102:151489102(0) win 1024 [tos 0x28] Aug 29 15:51:34.274654 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6491: R 151489103:151489103(0) win 1200 [tos 0x28] Aug 29 15:51:36.393019 rule 0/(match) block in on vio0: 60.191.38.78.4249 > 45.FOO.BAR.IP.8000: S 3746478095:3746478095(0) win 29200 (DF) Aug 29 15:51:57.213051 rule 0/(match) block in on vio0: 24.137.245.138.7343 > 45.FOO.BAR.IP.5358: S 14134:14134(0) win 14600 Aug 29 15:52:37.852219 rule 0/(match) block in on vio0: 122.226.185.125.51128 > 45.FOO.BAR.IP.23: S 1715745381:1715745381(0) win 5840 <mss 1420,sackOK,timestamp 13511417 0,nop,wscale 2> (DF) Aug 29 15:53:31.309325 rule 0/(match) block in on vio0: 189.218.148.69.377 > 45.FOO.BAR.IP5358: S 65340:65340(0) win 14600 [tos 0x28] Aug 29 15:53:31.809570 rule 0/(match) block in on vio0: 13.93.104.140.53184 > 45.FOO.BAR.IP.1433: S 39854048:39854048(0) win 1024 Aug 29 15:53:32.138231 rule 0/(match) block in on vio0: 13.93.104.140.53184 > 45.FOO.BAR.IP.1433: R 39854049:39854049(0) win 1200 Aug 29 15:53:41.459088 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6028: S 168338703:168338703(0) win 1024 Aug 29 15:53:41.789732 rule 0/(match) block in on vio0: 77.72.82.22.47218 > 45.FOO.BAR.IP.6028: R 168338704:168338704(0) win 1200 Aug 29 15:54:34.993594 rule 0/(match) block in on vio0: 212.47.234.50.5102 > 45.FOO.BAR.IP.5060: udp 408 (DF) [tos 0x28] Aug 29 15:54:57.987449 rule 0/(match) block in on vio0: 51.15.69.145.5100 > 45.FOO.BAR.IP.5060: udp 406 (DF) [tos 0x28] Aug 29 15:55:07.001743 rule 0/(match) block in on vio0: 190.83.174.214.58863 > 45.FOO.BAR.IP.23: S 757158343:757158343(0) win 27420 Aug 29 15:55:51.269549 rule 0/(match) block in on vio0: 142.217.201.69.26112 > 45.FOO.BAR.IP.22: S 757158343:757158343(0) win 22840 <mss 1460> Aug 29 15:58:41.346028 rule 0/(match) block in on vio0: 169.1.29.111.29765 > 45.FOO.BAR.IP.23: S 757158343:757158343(0) win 28509 Aug 29 15:59:11.575927 rule 0/(match) block in on vio0: 187.160.235.162.32427 > 45.FOO.BAR.IP.5358: S 22445:22445(0) win 14600 [tos 0x28] Aug 29 15:59:37.826598 rule 0/(match) block in on vio0: 94.74.81.97.54656 > 45.FOO.BAR.IP.3128: S 2720157526:2720157526(0) win 1024 [tos 0x28]stateful Aug 29 15:59:37.991171 rule 0/(match) block in on vio0: 94.74.81.97.54656 > 45.FOO.BAR.IP.3128: R 2720157527:2720157527(0) win 1200 [tos 0x28] Aug 29 16:01:36.990050 rule 0/(match) block in on vio0: 182.18.8.28.23299 > 45.FOO.BAR.IP.445: S 1510146048:1510146048(0) win 16384如果要查看实时日志，可以运行：# tcpdump -n -e -ttt -i pflog0如果你想了解更多信息，可以访问 PF FAQ 和 FreeBSD HANDBOOK 以及下面这些 man 页面：# man tcpdump # man pfctl # man pf关于作者我是 nixCraft 的创立者，一个经验丰富的系统管理员，同时也是一位 Linux 操作系统/Unix shell 脚本培训师。我在不同的行业与全球客户工作过，包括 IT、教育、国防和空间研究、以及非营利组织。你可以在 Twitter、Facebook 或 Google+ 上面关注我。via: https://www.cyberciti.biz/faq/how-to-set-up-a-firewall-with-pf-on-freebsd-to-protect-a-web-server/作者：Vivek Gite 译者：ucasFL 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
如何下载并使用运行在 Ubuntu Linux 服务器上的 KVM 云镜像？如何在 Ubuntu Linux 16.04 LTS 服务器上无需完整安装即可创建虚拟机？如何在 Ubuntu Linux 上使用 KVM 云镜像？基于内核的虚拟机（KVM）是 Linux 内核的虚拟化模块，可将其转变为虚拟机管理程序。你可以在命令行使用 Ubuntu 为 libvirt 和 KVM 提供的虚拟化前端通过 KVM 创建 Ubuntu 云镜像。这个快速教程展示了如何安装和使用 uvtool，它为 Ubuntu 云镜像下载，libvirt 和 clout\_int 提供了统一的集成虚拟机前端。步骤 1 - 安装 KVM你必须安装并配置 KVM。使用 apt 命令/apt-get 命令，如下所示：$ sudo apt install qemu-kvm libvirt-bin virtinst bridge-utils cpu-checker $ kvm-ok ## [configure bridged networking as described here][3] $ sudo vi /etc/network/interfaces $ sudo systemctl restart networking $ sudo brctl show 参阅如何在 Ubuntu 16.04 LTS Headless 服务器上安装 KVM 以获得更多信息。（LCTT 译注：Headless 服务器是指没有本地接口的计算设备，专用于向其他计算机及其用户提供服务。）步骤 2 - 安装 uvtool键入以下 apt 命令/apt-get 命令：$ sudo apt install uvtool 示例输出：[sudo] password for vivek: Reading package lists... Done Building dependency tree Reading state information... Done The following packages were automatically installed and are no longer required: gksu libgksu2-0 libqt5designer5 libqt5help5 libqt5printsupport5 libqt5sql5 libqt5sql5-sqlite libqt5xml5 python3-dbus.mainloop.pyqt5 python3-notify2 python3-pyqt5 python3-sip Use 'sudo apt autoremove' to remove them. The following additional packages will be installed: cloud-image-utils distro-info python-boto python-pyinotify python-simplestreams socat ubuntu-cloudimage-keyring uvtool-libvirt Suggested packages: cloud-utils-euca shunit2 python-pyinotify-doc The following NEW packages will be installed: cloud-image-utils distro-info python-boto python-pyinotify python-simplestreams socat ubuntu-cloudimage-keyring uvtool uvtool-libvirt 0 upgraded, 9 newly installed, 0 to remove and 0 not upgraded. Need to get 1,211 kB of archives. After this operation, 6,876 kB of additional disk space will be used. Get:1 http://in.archive.ubuntu.com/ubuntu artful/main amd64 distro-info amd64 0.17 [20.3 kB] Get:2 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 python-boto all 2.44.0-1ubuntu2 [740 kB] Get:3 http://in.archive.ubuntu.com/ubuntu artful/main amd64 python-pyinotify all 0.9.6-1 [24.6 kB] Get:4 http://in.archive.ubuntu.com/ubuntu artful/main amd64 ubuntu-cloudimage-keyring all 2013.11.11 [4,504 B] Get:5 http://in.archive.ubuntu.com/ubuntu artful/main amd64 cloud-image-utils all 0.30-0ubuntu2 [17.2 kB] Get:6 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 python-simplestreams all 0.1.0~bzr450-0ubuntu1 [29.7 kB] Get:7 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 socat amd64 1.7.3.2-1 [342 kB] Get:8 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 uvtool all 0~git122-0ubuntu1 [6,498 B] Get:9 http://in.archive.ubuntu.com/ubuntu artful/universe amd64 uvtool-libvirt all 0~git122-0ubuntu1 [26.9 kB] Fetched 1,211 kB in 3s (393 kB/s) Selecting previously unselected package distro-info. (Reading database ... 199933 files and directories currently installed.) Preparing to unpack .../0-distro-info_0.17_amd64.deb ... Unpacking distro-info (0.17) ... Selecting previously unselected package python-boto. Preparing to unpack .../1-python-boto_2.44.0-1ubuntu2_all.deb ... Unpacking python-boto (2.44.0-1ubuntu2) ... Selecting previously unselected package python-pyinotify. Preparing to unpack .../2-python-pyinotify_0.9.6-1_all.deb ... Unpacking python-pyinotify (0.9.6-1) ... Selecting previously unselected package ubuntu-cloudimage-keyring. Preparing to unpack .../3-ubuntu-cloudimage-keyring_2013.11.11_all.deb ... Unpacking ubuntu-cloudimage-keyring (2013.11.11) ... Selecting previously unselected package cloud-image-utils. Preparing to unpack .../4-cloud-image-utils_0.30-0ubuntu2_all.deb ... Unpacking cloud-image-utils (0.30-0ubuntu2) ... Selecting previously unselected package python-simplestreams. Preparing to unpack .../5-python-simplestreams_0.1.0~bzr450-0ubuntu1_all.deb ... Unpacking python-simplestreams (0.1.0~bzr450-0ubuntu1) ... Selecting previously unselected package socat. Preparing to unpack .../6-socat_1.7.3.2-1_amd64.deb ... Unpacking socat (1.7.3.2-1) ... Selecting previously unselected package uvtool. Preparing to unpack .../7-uvtool_0~git122-0ubuntu1_all.deb ... Unpacking uvtool (0~git122-0ubuntu1) ... Selecting previously unselected package uvtool-libvirt. Preparing to unpack .../8-uvtool-libvirt_0~git122-0ubuntu1_all.deb ... Unpacking uvtool-libvirt (0~git122-0ubuntu1) ... Setting up distro-info (0.17) ... Setting up ubuntu-cloudimage-keyring (2013.11.11) ... Setting up cloud-image-utils (0.30-0ubuntu2) ... Setting up socat (1.7.3.2-1) ... Setting up python-pyinotify (0.9.6-1) ... Setting up python-boto (2.44.0-1ubuntu2) ... Setting up python-simplestreams (0.1.0~bzr450-0ubuntu1) ... Processing triggers for doc-base (0.10.7) ... Processing 1 added doc-base file... Setting up uvtool (0~git122-0ubuntu1) ... Processing triggers for man-db (2.7.6.1-2) ... Setting up uvtool-libvirt (0~git122-0ubuntu1) ... 步骤 3 - 下载 Ubuntu 云镜像你需要使用 uvt-simplestreams-libvirt 命令。它维护一个 libvirt 容量存储池，作为一个 简单流 simplestreams 源的镜像子集的本地镜像，比如 Ubuntu 云镜像。要使用当前所有 amd64 镜像更新 uvtool 的 libvirt 容量存储池，运行：$ uvt-simplestreams-libvirt sync arch=amd64 要更新/获取 Ubuntu 16.04 LTS (xenial/amd64) 镜像，运行：$ uvt-simplestreams-libvirt --verbose sync release=xenial arch=amd64 示例输出：Adding: com.ubuntu.cloud:server:16.04:amd64 20171121.1 通过 query 选项查询本地镜像：$ uvt-simplestreams-libvirt query 示例输出：release=xenial arch=amd64 label=release (20171121.1) 现在，我为 Ubuntu xenial 创建了一个镜像，接下来我会创建虚拟机。步骤 4 - 创建 SSH 密钥你需要使用 SSH 密钥才能登录到 KVM 虚拟机。如果你根本没有任何密钥，请使用 ssh-keygen 命令创建一个新的密钥。$ ssh-keygen 参阅“如何在 Linux / Unix 系统上设置 SSH 密钥” 和 “Linux / UNIX: 生成 SSH 密钥” 以获取更多信息。步骤 5 - 创建 VM是时候创建虚拟机了，它叫 vm1，即创建一个 Ubuntu Linux 16.04 LTS 虚拟机：$ uvt-kvm create vm1 默认情况下 vm1 使用以下配置创建：内存：512M磁盘大小：8GiBCPU：1 vCPU core要控制内存、磁盘、CPU 和其他配置，使用以下语法：$ uvt-kvm create vm1 \ --memory MEMORY \ --cpu CPU \ --disk DISK \ --bridge BRIDGE \ --ssh-public-key-file /path/to/your/SSH_PUBLIC_KEY_FILE \ --packages PACKAGES1, PACKAGES2, .. \ --run-script-once RUN_SCRIPT_ONCE \ --password PASSWORD 其中--password PASSWORD：设置 ubuntu 用户的密码和允许使用 ubuntu 的用户登录（不推荐，使用 ssh 密钥）。--run-script-once RUN_SCRIPT_ONCE : 第一次启动时，在虚拟机上以 root 身份运行 RUN_SCRIPT_ONCE 脚本，但再也不会运行。这里给出完整的路径。这对于在虚拟机上运行自定义任务时非常有用，例如设置安全性或其他内容。--packages PACKAGES1, PACKAGES2, .. : 在第一次启动时安装以逗号分隔的软件包。要获取帮助，运行：$ uvt-kvm -h $ uvt-kvm create -h 如何删除虚拟机？要销毁/删除名为 vm1 的虚拟机，运行（请小心使用以下命令，因为没有确认框）：$ uvt-kvm destroy vm1 获取 vm1 的 IP 地址，运行：$ uvt-kvm ip vm1 192.168.122.52 列出所有运行的虚拟机$ uvt-kvm list 示例输出：vm1 freebsd11.1 步骤 6 - 如何登录 vm1语法是：$ uvt-kvm ssh vm1 示例输出：Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-101-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Get cloud support with Ubuntu Advantage Cloud Guest: http://www.ubuntu.com/business/services/cloud 0 packages can be updated. 0 updates are security updates. Last login: Thu Dec 7 09:55:06 2017 from 192.168.122.1 另一个选择是从 macOS/Linux/Unix/Windows 客户端使用常规的 ssh 命令：$ ssh ubuntu@192.168.122.52 $ ssh -i ~/.ssh/id_rsa ubuntu@192.168.122.52 示例输出：一旦创建了 vim，你可以照常使用 virsh 命令：$ virsh list via: https://www.cyberciti.biz/faq/how-to-use-kvm-cloud-images-on-ubuntu-linux/作者：Vivek Gite 译者：MjSeven 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
如何记录 Linux 的系统运行时间的统计信息
Linux/Unix 系统管理员对服务器的系统运行时间有一种奇怪的痴迷。这里有一个关于这个主题的 xkcd 漫画，一个好的系统管理员是一股不可阻挡的力量，他伫立在你家猫咪博客的服务器之前，对抗黑暗势力。我们可以使用 uptime 命令或 w 命令 或 top 命令来判断 Linux 系统运行了多久。我可以使用 tuptime 工具保留每次重新启动的运行时间，以获得系统运行时间的历史和统计报告。这就像 uptime 命令一样，但输出结果更令人印象深刻。最近我发现了另一种称为 uptimed 的工具，用于记录关于机器的系统运行时间和统计信息。让我们看看如何使用 Linux 操作系统上的 uptimed 和 uprecords 来获得运行时间的记录统计信息。查找系统运行时间非常简单，只需在基于 Linux 的系统上键入以下命令即可：$ uptime -p up 2 weeks, 4 days, 7 hours, 28 minutes 要保留有关 uptime 的历史统计信息，请使用 tuptime 或 uptimed 工具。安装 uptimed安装 uptimed 的最简单的方式是通过你的软件包管理器，比如 apt/apt-get/yum 这些你的 Linux 发行版的朋友。在 Debian/Ubuntu Linux 上安装 uptimed键入以下 apt 命令/apt-get 命令：$ sudo apt-get install uptimed 示例输出：Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: libuptimed0 The following NEW packages will be installed: libuptimed0 uptimed 0 upgraded, 2 newly installed, 0 to remove and 3 not upgraded. Need to get 40.7 kB of archives. After this operation, 228 kB of additional disk space will be used. Do you want to continue? [Y/n] y Get:1 http://mirrors.linode.com/ubuntu xenial/universe amd64 libuptimed0 amd64 1:0.3.17-4 [9,050 B] Get:2 http://mirrors.linode.com/ubuntu xenial/universe amd64 uptimed amd64 1:0.3.17-4 [31.6 kB] Fetched 40.7 kB in 0s (2,738 kB/s) Preconfiguring packages ... Selecting previously unselected package libuptimed0. (Reading database ... 39163 files and directories currently installed.) Preparing to unpack .../libuptimed0_1%3a0.3.17-4_amd64.deb ... Unpacking libuptimed0 (1:0.3.17-4) ... Selecting previously unselected package uptimed. Preparing to unpack .../uptimed_1%3a0.3.17-4_amd64.deb ... Unpacking uptimed (1:0.3.17-4) ... Processing triggers for systemd (229-4ubuntu21) ... Processing triggers for ureadahead (0.100.0-19) ... Processing triggers for man-db (2.7.5-1) ... Setting up libuptimed0 (1:0.3.17-4) ... Setting up uptimed (1:0.3.17-4) ... Processing triggers for libc-bin (2.23-0ubuntu9) ... Processing triggers for systemd (229-4ubuntu21) ... Processing triggers for ureadahead (0.100.0-19) ... 在 CentOS/RHEL/Fedora/Oracle/Scientific Linux 上安装 uptimed首先 在 CentOS/RHEL 使用 EPEL 仓库：$ sudo yum -y install epel-release 然后，键入以下 yum 命令：$ sudo yum install uptimed 示例输出：Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: centos.excellmedia.net * epel: ftp.cuhk.edu.hk * extras: centos.excellmedia.net * updates: centos.excellmedia.net Resolving Dependencies --> Running transaction check ---> Package uptimed.x86_64 0:0.4.0-6.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved =============================================================================== Package Arch Version Repository Size =============================================================================== Installing: uptimed x86_64 0.4.0-6.el7 epel 47 k Transaction Summary =============================================================================== Install 1 Package Total download size: 47 k Installed size: 98 k Is this ok [y/d/N]: y Downloading packages: uptimed-0.4.0-6.el7.x86_64.rpm | 47 kB 00:01 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : uptimed-0.4.0-6.el7.x86_64 1/1 Verifying : uptimed-0.4.0-6.el7.x86_64 1/1 Installed: uptimed.x86_64 0:0.4.0-6.el7 Complete! 如果你正在使用 Fedora Linux，运行以下 dnf 命令：$ sudo dnf install uptimed 在 Arch Linux 上安装 uptimed键入以下 pacman 命令：$ sudo pacman -S uptimed 在 Gentoo Linux 上安装 uptimed键入以下 emerge 命令：$ sudo emerge --ask uptimed 如何配置 uptimed使用文本编辑器编辑 /etc/uptimed.conf 文件，例如 vim 命令：$ sudo vim /etc/uptimed.conf 最少设置一个 email 地址来发送记录。假定有个兼容 sendmail 的 MTA 安装在 /usr/lib/sendmail。EMAIL=vivek@server1.cyberciti.biz 保存并关闭文件。如何在系统启动时启动 uptimed 服务？使用 systemctl 命令启动 uptimed 服务：$ sudo systemctl enable uptimed 我该如何 启动/停止/重启 或者查看 uptimed 服务的状态？$ sudo systemctl start uptimed ## start it ## $ sudo systemctl stop uptimed ## stop it ## $ sudo systemctl restart uptimed ## restart it ## $ sudo systemctl status uptimed ## view status ## 示例输出：● uptimed.service - uptime record daemon Loaded: loaded (/lib/systemd/system/uptimed.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2017-11-09 17:49:14 UTC; 18min ago Main PID: 11137 (uptimed) CGroup: /system.slice/uptimed.service └─11137 /usr/sbin/uptimed -f Nov 09 17:49:14 gfs04 systemd[1]: Started uptime record daemon. 如何查看 uptime 记录只需键入以下命令即可查看 uptimed(8) 程序的统计信息：$ uprecords 示例输出：uprecords 有一些选项：$ uprecords -? 示例输出：usage: uprecords [OPTION]... -? this help -a do not print ansi codes -b sort by boottime -B reverse sort by boottime -k sort by sysinfo -K reverse sort by sysinfo -d print downtime seen before every uptimes instead of system -c do not show current entry if not in top entries -f run continously in a loop -s do not print extra statistics -w wide output (more than 80 cols per line) -i INTERVAL use INTERVAL seconds for loop instead of 5, implies -f -m COUNT show a maximum of top COUNT entries instead of 10 -M show next milestone -v version information 结论这是一个极好的小工具，可以显示服务器正常运行时间的记录，以证明机器正常运行时间和你的业务连续性。在相关说明中，你可以看到官方的 XKCD 系统管理员 T恤 因为漫画被制作成衬衫，其中包括背面的新插图。via: https://www.cyberciti.biz/hardware/see-records-statistics-about-a-linux-servers-uptime/作者：Vivek Gite 译者：MjSeven 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
Q：我正在电脑上使用 Debian Linux 9 “stretch”。 我想用 NetworkManager 来建网桥。但是根本就没有添加 br0的选项。我该如何在 Linux 里使用 nmcli 来为 NetworkManager 创建或者添加网桥呢？网桥没什么特别的，只是把两个网络连在一起。它工作在数据链路层，即 OSI 模型的第二层。网桥经常用在虚拟机或别的一些软件中。为了使用网桥而关闭桌面 Linux 上的 NetworkManager 显然是不明智的。nmcli 可以创建一个永久的网桥而不需要编辑任何文件。本文将展示如何使用 NetworkManager 的命令行工具 nmcli 来创建网桥。如何使用 nmcli 来创建/添加网桥使用 NetworkManager 在 Linux 上添加网桥接口的步骤如下：打开终端获取当前连接状态： nmcli con show添加新的网桥： nmcli con add type bridge ifname br0创建子网卡： nmcli con add type bridge-slave ifname eno1 master br0打开 br0： nmcli con up br0让我们从细节层面看看如何创建一个名为 br0 的网桥。获取当前网络配置你可以通过 NetworkManager 的 GUI 来了解本机的网络连接：也可以使用如下命令行来查看：$ nmcli con show $ nmcli connection show --active 我有一个使用网卡 eno1 的 “有线连接”。我的系统还有一个 VPN 接口。我将要创建一个名为 br0 的网桥，并连接到 eno1。如何创建一个名为 br0 的网桥$ sudo nmcli con add ifname br0 type bridge con-name br0 $ sudo nmcli con add type bridge-slave ifname eno1 master br0 $ nmcli connection show 你也可以禁用 STP：$ sudo nmcli con modify br0 bridge.stp no $ nmcli con show $ nmcli -f bridge con show br0 最后一条命令展示了禁用 STP 后的网桥参数：bridge.mac-address: -- bridge.stp: no bridge.priority: 32768 bridge.forward-delay: 15 bridge.hello-time: 2 bridge.max-age: 20 bridge.ageing-time: 300 bridge.multicast-snooping: yes 如何打开网桥你必须先关闭 Wired connection 1 ，然后打开 br0：$ sudo nmcli con down "Wired connection 1" $ sudo nmcli con up br0 $ nmcli con show 使用 ip 命令 来查看 IP 信息：$ ip a s $ ip a s br0 附录: 如何在 KVM 上使用 br0现在你可以使用 KVM/VirtualBox/VMware workstation 创建的 VM（虚拟机）来直接连接网络而非通过 NAT。使用 vi 或者 cat 命令为虚拟机创建一个名为 br0.xml 的文件：$ cat /tmp/br0.xml 添加以下代码：<network> <name>br0</name> <forward mode="bridge"/> <bridge name="br0" /> </network> 如下所示运行 virsh命令：# virsh net-define /tmp/br0.xml # virsh net-start br0 # virsh net-autostart br0 # virsh net-list --all 输出： Name State Autostart Persistent ---------------------------------------------------------- br0 active yes yes default inactive no yes 阅读 man 页面获取更多信息：$ man ip $ man nmcli 关于作者作者是 nixCraft 的创建者、老练的系统管理员和一个 Linux/Unix shell 脚本编程培训师。他为全球客户和各种公司工作，包括 IT，教育，国防，空间研究以及非营利组织。 他的联系方式 Twitter、 Facebook、 Google+。via: https://www.cyberciti.biz/faq/how-to-add-network-bridge-with-nmcli-networkmanager-on-linux/作者：Vivek Gite 译者：kennethXia 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
有些误解认为 shell 脚本仅用于 CLI 环境。实际上在 KDE 或 Gnome 桌面下，你可以有效的使用各种工具编写 GUI 或者网络（socket）脚本。shell 脚本可以使用一些 GUI 组件（菜单、警告框、进度条等），你可以控制终端输出、光标位置以及各种输出效果等等。利用下面的工具，你可以构建强壮的、可交互的、对用户友好的 UNIX/Linux bash 脚本。制作 GUI 应用不是一项困难的任务，但需要时间和耐心。幸运的是，UNIX 和 Linux 都带有大量编写漂亮 GUI 脚本的工具。以下工具是基于 FreeBSD 和 Linux 操作系统做的测试，而且也适用于其他类 UNIX 操作系统。1、notify-send 命令notify-send 命令允许你借助通知守护进程发送桌面通知给用户。这种避免打扰用户的方式，对于通知桌面用户一个事件或显示一些信息是有用的。在 Debian 或 Ubuntu 上，你需要使用 apt 命令 或 apt-get 命令 安装的包：sudo apt-get install libnotify-bin CentOS/RHEL 用户使用下面的 yum 命令：sudo yum install libnotify Fedora Linux 用户使用下面的 dnf 命令：`$ sudo dnf install libnotify` In this example, send simple desktop notification from the command line, enter: ### 发送一些通知 ### notify-send "rsnapshot done :)" 示例输出：下面是另一个附加选项的代码：... alert=18000 live=$(lynx --dump http://money.rediff.com/ | grep 'BSE LIVE' | awk '{ print $5}' | sed 's/,//g;s/\.[0-9]*//g') [ $notify_counter -eq 0 ] && [ $live -ge $alert ] && { notify-send -t 5000 -u low -i "BSE Sensex touched 18k"; notify_counter=1; } ... 示例输出：这里：-t 5000：指定超时时间（毫秒） （5000 毫秒 = 5 秒）-u low： 设置紧急等级 （如：低、普通、紧急）-i gtk-dialog-info： 设置要显示的图标名称或者指定的图标（你可以设置路径为：-i /path/to/your-icon.png）关于更多使用 notify-send 功能的信息，请参考 man 手册。在命令行下输入 man notify-send 即可看见：man notify-send 2、tput 命令tput 命令用于设置终端特性。通过 tput 你可以设置：在屏幕上移动光标。获取终端信息。设置颜色（背景和前景）。设置加粗模式。设置反转模式等等。下面有一段示例代码：#!/bin/bash # clear the screen tput clear # Move cursor to screen location X,Y (top left is 0,0) tput cup 3 15 # Set a foreground colour using ANSI escape tput setaf 3 echo "XYX Corp LTD." tput sgr0 tput cup 5 17 # Set reverse video mode tput rev echo "M A I N - M E N U" tput sgr0 tput cup 7 15 echo "1. User Management" tput cup 8 15 echo "2. Service Management" tput cup 9 15 echo "3. Process Management" tput cup 10 15 echo "4. Backup" # Set bold mode tput bold tput cup 12 15 read -p "Enter your choice [1-4] " choice tput clear tput sgr0 tput rc 示例输出：关于 tput 命令的详细信息，参见手册：man 5 terminfo man tput 3、setleds 命令setleds 命令允许你设置键盘灯。下面是打开数字键灯的示例：setleds -D +num 关闭数字键灯，输入：setleds -D -num -caps：关闭大小写锁定灯+caps：打开大小写锁定灯-scroll：关闭滚动锁定灯+scroll：打开滚动锁定灯查看 setleds 手册可看见更多信息和选项 man setleds。4、zenity 命令zenity 命令显示 GTK+ 对话框，并且返回用户输入。它允许你使用各种 Shell 脚本向用户展示或请求信息。下面是一个 whois 指定域名目录服务的 GUI 客户端示例。#!/bin/bash # Get domain name _zenity="/usr/bin/zenity" _out="/tmp/whois.output.$$" domain=$(${_zenity} --title "Enter domain" \ --entry --text "Enter the domain you would like to see whois info" ) if [ $? -eq 0 ] then # Display a progress dialog while searching whois database whois $domain | tee >(${_zenity} --width=200 --height=100 \ --title="whois" --progress \ --pulsate --text="Searching domain info..." \ --auto-kill --auto-close \ --percentage=10) >${_out} # Display back output ${_zenity} --width=800 --height=600 \ --title "Whois info for $domain" \ --text-info --filename="${_out}" else ${_zenity} --error \ --text="No input provided" fi 示例输出：参见手册获取更多 zenity 信息以及其他支持 GTK+ 的组件：zenity --help man zenity 5、kdialog 命令kdialog 命令与 zenity 类似，但它是为 KDE 桌面和 QT 应用设计。你可以使用 kdialog 展示对话框。下面示例将在屏幕上显示信息：kdialog --dontagain myscript:nofilemsg --msgbox "File: '~/.backup/config' not found." 示例输出：参见 《KDE 对话框 Shell 脚本编程》 教程获取更多信息。6、DialogDialog 是一个使用 Shell 脚本的应用，显示用户界面组件的文本。它使用 curses 或者 ncurses 库。下面是一个示例代码：#!/bin/bash dialog --title "Delete file" \ --backtitle "Linux Shell Script Tutorial Example" \ --yesno "Are you sure you want to permanently delete \"/tmp/foo.txt\"?" 7 60 # Get exit status # 0 means user hit [yes] button. # 1 means user hit [no] button. # 255 means user hit [Esc] key. response=$? case $response in 0) echo "File deleted.";; 1) echo "File not deleted.";; 255) echo "[ESC] key pressed.";; esac 参见 dialog 手册获取详细信息：man dialog。关于其他用户界面工具的注意事项UNIX、Linux 提供了大量其他工具来显示和控制命令行中的应用程序，shell 脚本可以使用一些 KDE、Gnome、X 组件集：gmessage - 基于 GTK xmessage 的克隆xmessage - 在窗口中显示或询问消息（基于 X 的 /bin/echo）whiptail - 显示来自 shell 脚本的对话框python-dialog - 用于制作简单文本或控制台模式用户界面的 Python 模块7、logger 命令logger 命令将信息写到系统日志文件，如：/var/log/messages。它为系统日志模块 syslog 提供了一个 shell 命令行接口：logger "MySQL database backup failed." tail -f /var/log/messages logger -t mysqld -p daemon.error "Database Server failed" tail -f /var/log/syslog 示例输出：Apr 20 00:11:45 vivek-desktop kernel: [38600.515354] CPU0: Temperature/speed normal Apr 20 00:12:20 vivek-desktop mysqld: Database Server failed 参见 《如何写消息到 syslog 或 日志文件》 获得更多信息。此外，你也可以查看 logger 手册获取详细信息：man logger8、setterm 命令setterm 命令可设置不同的终端属性。下面的示例代码会强制屏幕在 15 分钟后变黑，监视器则 60 分钟后待机。setterm -blank 15 -powersave powerdown -powerdown 60 下面的例子将 xterm 窗口中的文本以下划线展示：setterm -underline on; echo "Add Your Important Message Here" setterm -underline off 另一个有用的选项是打开或关闭光标显示：setterm -cursor off 打开光标：setterm -cursor on 参见 setterm 命令手册获取详细信息：man setterm9、smbclient：给 MS-Windows 工作站发送消息smbclient 命令可以与 SMB/CIFS 服务器通讯。它可以向 MS-Windows 系统上选定或全部用户发送消息。smbclient -M WinXPPro <<eof Message 1 Message 2 ... .. EOF 或echo "${Message}" | smbclient -M salesguy2 参见 smbclient 手册或者阅读我们之前发布的文章：《给 Windows 工作站发送消息》：man smbclient10、Bash 套接字编程在 bash 下，你可以打开一个套接字并通过它发送数据。你不必使用 curl 或者 lynx 命令抓取远程服务器的数据。bash 和两个特殊的设备文件可用于打开网络套接字。以下选自 bash 手册：/dev/tcp/host/port - 如果 host 是一个有效的主机名或者网络地址，而且端口是一个整数或者服务名，bash 会尝试打开一个相应的 TCP 连接套接字。/dev/udp/host/port - 如果 host 是一个有效的主机名或者网络地址，而且端口是一个整数或者服务名，bash 会尝试打开一个相应的 UDP 连接套接字。你可以使用这项技术来确定本地或远程服务器端口是打开或者关闭状态，而无需使用 nmap 或者其它的端口扫描器。# find out if TCP port 25 open or not (echo >/dev/tcp/localhost/25) &>/dev/null && echo "TCP port 25 open" || echo "TCP port 25 close" 下面的代码片段，你可以利用 bash 循环找出已打开的端口：echo "Scanning TCP ports..." for p in {1..1023} do (echo >/dev/tcp/localhost/$p) >/dev/null 2>&1 && echo "$p open" done 示例输出：Scanning TCP ports... 22 open 53 open 80 open 139 open 445 open 631 open 下面的示例中，你的 bash 脚本将像 HTTP 客户端一样工作：#!/bin/bash exec 3<> /dev/tcp/${1:-www.cyberciti.biz}/80 printf "GET / HTTP/1.0 " >&3 printf "Accept: text/html, text/plain " >&3 printf "Accept-Language: en " >&3 printf "User-Agent: nixCraft_BashScript v.%s " "${BASH_VERSION}" >&3 printf " " >&3 while read LINE <&3 do # do something on $LINE # or send $LINE to grep or awk for grabbing data # or simply display back data with echo command echo $LINE done 参见 bash 手册获取更多信息：man bash关于 GUI 工具和 cron 任务的注意事项如果你 使用 crontab 来启动你的脚本，你需要使用 export DISPLAY=[用户机器]:0 命令请求本地显示或输出服务。举个例子，使用 zenity 工具调用 /home/vivek/scripts/monitor.stock.sh：@hourly DISPLAY=:0.0 /home/vivek/scripts/monitor.stock.sh 你有喜欢的可以增加 shell 脚本趣味的 UNIX 工具么？请在下面的评论区分享它吧。关于作者本文作者是 nixCraft 创始人、一个老练的系统管理员、Linux 操作系统和 UNIX shell 编程培训师。他服务来自全球的客户和不同的行业，包括 IT 、教育、防务和空间探索、还有非营利组织。你可以在 Twitter，Facebook，Google+ 上面关注他。via: https://www.cyberciti.biz/tips/spice-up-your-unix-linux-shell-scripts.html作者：Vivek Gite 译者：pygmalion666 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
你可以通过配置 sudo 命令去嘲讽输入错误密码的用户。但是现在，当用户在 shell 输错命令时，就能嘲讽他了（滥用？）。你好 bash-insulter来自 Github 页面：当用户键入错误命令，随机嘲讽。它使用了一个 bash4.x. 版本的全新内置错误处理函数，叫 command_not_found_handle。安装键入下列 git 命令克隆一个仓库：git clone https://github.com/hkbakke/bash-insulter.git bash-insulter 示例输出：Cloning into 'bash-insulter'... remote: Counting objects: 52, done. remote: Compressing objects: 100% (49/49), done. remote: Total 52 (delta 12), reused 12 (delta 2), pack-reused 0 Unpacking objects: 100% (52/52), done. 用文本编辑器，比如说使用 vi，编辑你的 ~/.bashrc 或者 /etc/bash.bashrc 文件：$ vi ~/.bashrc 在其后追加这一行（具体了解请查看 if..else..fi 声明 和 source 命令）：if [ -f $HOME/bash-insulter/src/bash.command-not-found ]; then source $HOME/bash-insulter/src/bash.command-not-found fi 保存并关闭文件。重新登录，如果不想退出账号也可以手动运行它：$ . $HOME/bash-insulter/src/bash.command-not-found 如何使用它？尝试键入一些无效命令：$ ifconfigs $ dates 示例输出:自定义你需要编辑 $HOME/bash-insulter/src/bash.command-not-found：$ vi $HOME/bash-insulter/src/bash.command-not-found 示例代码：command_not_found_handle () { local INSULTS=( "Boooo!" "Don't you know anything?" "RTFM!" "Hahaha, n00b!" "Wow! That was impressively wrong!" "What are you doing??" "Pathetic" "...and this is the best you can do??" "The worst one today!" "n00b alert!" "Your application for reduced salary has been sent!" "lol" "u suk" "lol... plz" "plz uninstall" "And the Darwin Award goes to.... ${USER}!" "ERROR_INCOMPETENT_USER" "Incompetence is also competence" "Bad." "Fake it till you make it!" "What is this...? Amateur hour!?" "Come on! You can do it!" "Nice try." "What if... you type an actual command the next time!" "What if I told you... it is possible to type valid commands." "Y u no speak computer???" "This is not Windows" "Perhaps you should leave the command line alone..." "Please step away from the keyboard!" "error code: 1D10T" "ACHTUNG! ALLES TURISTEN UND NONTEKNISCHEN LOOKENPEEPERS! DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN. IST NICHT FÜR GEWERKEN BEI DUMMKOPFEN. DER RUBBERNECKEN SIGHTSEEREN KEEPEN DAS COTTONPICKEN HÄNDER IN DAS POCKETS MUSS. ZO RELAXEN UND WATSCHEN DER BLINKENLICHTEN." "Pro tip: type a valid command!" ) # 设置“随机”种子发生器 RANDOM=$(date +%s%N) VALUE=$((${RANDOM}%2)) if [[ ${VALUE} -lt 1 ]]; then printf "\n $(tput bold)$(tput setaf 1)$(shuf -n 1 -e "${INSULTS[@]}")$(tput sgr0)\n\n" fi echo "-bash: $1: command not found" # 无效命令，常规返回已存在的代码 return 127 } 赠品：sudo 嘲讽编辑 sudoers 文件：$ sudo visudo 追加下面这一行：Defaults insults 或者像下面尾行增加一句嘲讽语：Defaults !lecture,tty_tickets,!fqdn,insults 这是我的文件：Defaults env_reset Defaults mail_badpass Defaults secure_path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin" ## If set, sudo will insult users when they enter an incorrect password. ## Defaults insults # Host alias specification # User alias specification # Cmnd alias specification # User privilege specification root ALL = (ALL:ALL) ALL # Members of the admin group may gain root privileges % admin ALL = (ALL) ALL # Allow members of group sudo to execute any command % sudo ALL = (ALL:ALL) ALL # See sudoers(5) for more information on "#include" directives: #includedir /etc/sudoers.d 试一试：$ sudo -k # 清除缓存，从头开始 $ sudo ls /root/ $ sudo -i 样例对话：赠品：你好 slsl 或是 UNIX 经典捣蛋软件 游戏。当你错误的把 ls 输入成 sl，将会有一辆蒸汽机车穿过你的屏幕。$ sl via: https://www.cyberciti.biz/howto/insult-linux-unix-bash-user-when-typing-wrong-command/作者：Vivek Gite 译者：CYLeft 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
Q：我是一个新 Debian Linux 用户，我想为 Debian Linux 上运行的虚拟化环境（KVM）设置网桥。那么我该如何在 Debian Linux 9.x 服务器上的 /etc/network/interfaces 中设置桥接网络呢？如何你想为你的虚拟机分配 IP 地址并使其可从你的局域网访问，则需要设置网络桥接器。默认情况下，虚拟机使用 KVM 创建的专用网桥。但你需要手动设置接口，避免与网络管理员发生冲突。怎样安装 brctl输入以下 apt-get 命令：$ sudo apt install bridge-utils 怎样在 Debian Linux 上设置网桥你需要编辑 /etc/network/interface 文件。不过，我建议在 /etc/network/interface.d/ 目录下放置一个全新的配置。在 Debian Linux 配置网桥的过程如下：步骤 1 - 找出你的物理接口使用 ip 命令：$ ip -f inet a s 示例输出如下：2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 inet 192.168.2.23/24 brd 192.168.2.255 scope global eno1 valid_lft forever preferred_lft forever eno1 是我的物理网卡。步骤 2 - 更新 /etc/network/interface 文件确保只有 lo（loopback 在 /etc/network/interface 中处于活动状态）。（LCTT 译注：loopback 指本地环回接口，也称为回送地址）删除与 eno1 相关的任何配置。这是我使用 cat 命令 打印的配置文件：$ cat /etc/network/interface # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback 步骤 3 - 在 /etc/network/interfaces.d/br0 中配置网桥（br0）使用文本编辑器创建一个文本文件，比如 vi 命令：$ sudo vi /etc/network/interfaces.d/br0 在其中添加配置：## static ip config file for br0 ## auto br0 iface br0 inet static address 192.168.2.23 broadcast 192.168.2.255 netmask 255.255.255.0 gateway 192.168.2.254 # If the resolvconf package is installed, you should not edit # the resolv.conf configuration file manually. Set name server here #dns-nameservers 192.168.2.254 # If you have muliple interfaces such as eth0 and eth1 # bridge_ports eth0 eth1 bridge_ports eno1 bridge_stp off # disable Spanning Tree Protocol bridge_waitport 0 # no delay before a port becomes available bridge_fd 0 # no forwarding delay 如果你想使用 DHCP 来获得 IP 地址：## DHCP ip config file for br0 ## auto br0 # Bridge setup iface br0 inet dhcp bridge_ports eno1 在 vi/vim 中保存并关闭文件。步骤 4 - 重新启动网络服务在重新启动网络服务之前，请确保防火墙已关闭。防火墙可能会引用较老的接口，例如 eno1。一旦服务重新启动，你必须更新 br0 接口的防火墙规则。键入以下命令重新启动防火墙：$ sudo systemctl restart network-manager 确认服务已经重新启动：$ systemctl status network-manager 借助 ip 命令寻找新的 br0 接口和路由表：$ ip a s $ ip r $ ping -c 2 cyberciti.biz 示例输出：你可以使用 brctl 命令查看网桥有关信息：$ brctl show 显示当前网桥：$ bridge link 关于作者作者是 nixCraft 的创建者，也是经验丰富的系统管理员，DevOps 工程师以及 Linux 操作系统/ Unix shell 脚本的培训师。通过订阅 RSS/XML 流 或者 每周邮件推送获得关于 SysAdmin, Linux/Unix 和开源主题的最新教程。via: https://www.cyberciti.biz/faq/how-to-configuring-bridging-in-debian-linux/作者：Vivek GIte 译者：MjSeven 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出