Merge pull request #11 from LCTT/master

更新
This commit is contained in:
Lv Feng 2016-09-22 21:23:35 -05:00 committed by GitHub
commit c307bf26e8
11 changed files with 918 additions and 474 deletions

View File

@ -0,0 +1,135 @@
你必须了解的基础的 Linux 网络命令
==================================================
![](https://itsfoss.com/wp-content/uploads/2016/06/Basic-Networking-Commands-Linux.jpg)
> 摘要:有抱负的 Linux 系统管理员和 Linux 狂热者必须知道的、最重要的、而且基础的 Linux 网络命令合集。
在 Its FOSS 我们并非每天都谈论 Linux 的“命令行方面”。基本上,我更专注于 Linux 的桌面端。但你们读者中的一些人在内部调查(仅面向 It's FOSS newsletter 订阅者)中指出,你们也想学些命令行技巧。速查表也受大部分读者所喜欢和支持。
为此,我编辑了一个 Linux 中基础网络命令的列表。它并不是一个教你如何使用这些命令的教程,而是一个命令合集和他们的简短解释。所以,如果你已经使用过这些命令,你可以用它来快速记住命令。
你可以把这个网页添加为书签以便快速查阅,或输出一个 PDF 版本以便离线使用。
当我还是通信系统工程专业的学生的时候我就有这个 Linux 网络命令的列表了。它帮助我在计算机网络课程获得了高分。希望它也能以同样的方式帮助你。
### Linux 基础网络命令列表
我在计算机网络课程上使用 FreeBSD不过这些 UNIX 命令应该也能在 Linux 上同样工作。
#### 连通性
- `ping <host>`:发送 ICMP echo 消息(一个包)到主机。这可能会不停地发送直到你按下 `Control-C`。Ping 的通意味着一个包从你的机器通过 ICMP 发送出去,并在 IP 层回显。Ping 告诉你另一个主机是否在运行。
- `telnet <host> [port]`:与主机在指定的端口通信。默认的 telnet 端口是 23。按 Control-] 以退出 telnet。其它一些常用的端口是
- 7 —— echo 端口
- 25 —— SMTP用于发送邮件
- 79 —— Finger (LCTT 译注:[维基百科 - Finger protocal](https://en.wikipedia.org/wiki/Finger_protocol),不过举例 Finger 恐怕不合时宜,倒不如试试 80提供该网络下其它用户的信息。
#### ARP
ARP 用于将 IP 地址转换为以太网地址。root 用户可以添加和删除 ARP 记录。当 ARP 记录被污染或者错误时删除它们会有用。root 显式添加的 ARP 记录是永久的 —— 代理设置的也是。ARP 表保存在内核中动态地被操作。ARP 记录会被缓存,通常在 20 分钟后失效并被删除。
- `arp -a`:打印 ARP 表。
- `arp -s <ip_address> <mac_address> [pub]`:添加一条记录到表中。
- `arp -a -d`:删除 ARP 表中的所有记录。
#### 路由
- `netstat -r`:打印路由表。路由表保存在内核中,用于 IP 层把包路由到非本地网络。
- `route add`route 命令用于向路由表添加静态(手动指定而非动态)路由路径。所有从该 PC 到那个 IP/子网的流量都会经由指定的网关 IP。它也可以用来设置一个默认路由。例如在 IP/子网处使用 0.0.0.0,就可以发送所有包到特定的网关。
- `routed`:控制动态路由的 BSD 守护程序。开机时启动。它运行 RIP 路由协议。只有 root 用户可用。没有 root 权限你不能运行它。
- `gated`gated 是另一个使用 RIP 协议的路由守护进程。它同时支持 OSPF、EGP 和 RIP 协议。只有 root 用户可用。
- `traceroute`:用于跟踪 IP 包的路由。它每次发送包时都把跳数加 1从而使得从源地址到目的地之间的所有网关都会返回消息。
- `netstat -rnf inet`:显示 IPv4 的路由表。
- `sysctl net.inet.ip.forwarding=1`:启用包转发(把主机变为路由器)。
- `route add|delete [-net|-host] <destination> <gateway>`:(如 `route add 192.168.20.0/24 192.168.30.4`)添加一条路由。
- `route flush`:删除所有路由。
- `route add -net 0.0.0.0 192.168.10.2`:添加一条默认路由。
- `routed -Pripv2 -Pno_rdisc -d [-s|-q]`:运行 routed 守护进程,使用 RIPv2 协议,不启用 ICMP 自动发现,在前台运行,供给模式或安静模式。
- `route add 224.0.0.0/4 127.0.0.1`为本地地址定义多播路由。LCTT 译注:原文存疑)
- `rtquery -n <host>`LCTT 译注:增加了 host 参数):查询指定主机上的 RIP 守护进程(手动更新路由表)。
#### 其它
- `nslookup`:向 DNS 服务器查询,将 IP 转为名称,或反之。例如,`nslookup facebook.com` 会给出 facebook.com 的 IP。
- `ftp <host> [port]`LCTT 译注:原文中 water 应是笔误):传输文件到指定主机。通常可以使用 登录名 "anonymous" , 密码 "guest" 来登录。
- `rlogin -l <host>`LCTT 译注:添加了 host 参数):使用类似 telnet 的虚拟终端登录到主机。
#### 重要文件
- `/etc/hosts`:域名到 IP 地址的映射。
- `/etc/networks`:网络名称到 IP 地址的映射。
- `/etc/protocols`:协议名称到协议编号的映射。
- `/etc/services`TCP/UDP 服务名称到端口号的映射。
#### 工具和网络性能分析
- `ifconfig <interface> <address> [up]`:启动接口。
- `ifconfig <interface> [down|delete]`:停止接口。
- `ethereal &`:在后台打开 `ethereal` 而非前台。
- `tcpdump -i -vvv`:抓取和分析包的工具。
- `netstat -w [seconds] -I [interface]`:显示网络设置和统计信息。
- `udpmt -p [port] -s [bytes] target_host`:发送 UDP 流量。
- `udptarget -p [port]`:接收 UDP 流量。
- `tcpmt -p [port] -s [bytes] target_host`:发送 TCP 流量。
- `tcptarget -p [port]`:接收 TCP 流量。
#### 交换机
- `ifconfig sl0 srcIP dstIP`:配置一个串行接口(在此前先执行 `slattach -l /dev/ttyd0`,此后执行 `sysctl net.inet.ip.forwarding=1`
- `telnet 192.168.0.254`:从子网中的一台主机访问交换机。
- `sh ru``show running-configuration`:查看当前配置。
- `configure terminal`:进入配置模式。
- `exit`退出当前模式。LCTT 译注:原文存疑)
#### VLAN
- `vlan n`:创建一个 ID 为 n 的 VLAN。
- `no vlan N`:删除 ID 为 n 的 VLAN。
- `untagged Y`:添加端口 Y 到 VLAN n。
- `ifconfig vlan0 create`:创建 vlan0 接口。
- `ifconfig vlan0 vlan_ID vlandev em0`:把 em0 加入到 vlan0 接口LCTT 译注:原文存疑),并设置标记为 ID。
- `ifconfig vlan0 [up]`:启用虚拟接口。
- `tagged Y`:为当前 VLAN 的端口 Y 添加标记帧支持。
#### UDP/TCP
- `socklab udp`:使用 UDP 协议运行 `socklab`
- `sock`:创建一个 UDP 套接字,等效于输入 `sock udp``bind`
- `sendto <Socket ID> <hostname> <port #>`:发送数据包。
- `recvfrom <Socket ID> <byte #>`:从套接字接收数据。
- `socklab tcp`:使用 TCP 协议运行 `socklab`
- `passive`:创建一个被动模式的套接字,等效于 `socklab``sock tcp``bind``listen`。
- `accept`:接受进来的连接(可以在发起进来的连接之前或之后执行)。
- `connect <hostname> <port #>`:等效于 `socklab``sock tcp``bind``connect`。
- `close`:关闭连接。
- `read <byte #>`:从套接字中读取 n 字节。
- `write`:(例如,`write ciao`、`write #10`)向套接字写入 "ciao" 或 10 个字节。
#### NAT/防火墙
- `rm /etc/resolv.conf`:禁止地址解析,保证你的过滤和防火墙规则正确工作。
- `ipnat -f file_name`:将过滤规则写入文件。
- `ipnat -l`:显示活动的规则列表。
- `ipnat -C -F`:重新初始化规则表。
- `map em0 192.168.1.0/24 -> 195.221.227.57/32 em0`:将 IP 地址映射到接口。
- `map em0 192.168.1.0/24 -> 195.221.227.57/32 portmap tcp/udp 20000:50000`:带端口号的映射。
- `ipf -f file_name`:将过滤规则写入文件。
- `ipf -F -a`:重置规则表。
- `ipfstat -I`:当与 -s 选项合用时列出活动的状态条目LCTT 译注:原文存疑)。
希望这份基础的 Linux 网络命令合集对你有用。欢迎各种问题和建议。
--------------------------------------------------------------------------------
via: https://itsfoss.com/basic-linux-networking-commands
作者:[Abhishek Prakash][a]
译者:[bianjp](https://github.com/bianjp)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[1]: https://drive.google.com/open?id=0By49_3Av9sT1cDdaZnh4cHB4aEk

View File

@ -0,0 +1,219 @@
Git 系列(六):如何搭建你自己的 Git 服务器
====================
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/bus-big-data.png?itok=sOQHDuID)
现在我们将要学习如何搭建 git 服务器,如何编写自定义的 Git 钩子来在特定的事件触发相应的动作(例如通知),或者是发布你的代码到一个站点。
直到现在,我们主要讨论的还是以一个使用者的身份与 Git 进行交互。这篇文章中我将讨论 Git 的管理,并且设计一个灵活的 Git 框架。你可能会觉得这听起来是 “高阶 Git 技术” 或者 “只有狂热粉才能阅读”的一句委婉的说法,但是事实是这里面的每个任务都不需要很深的知识或者其他特殊的训练,就能基本理解 Git 的工作原理,有可能需要一丁点关于 Linux 的知识。
### 共享 Git 服务器
创建你自己的共享 Git 服务器意外地简单,而且在很多情况下,遇到的这点麻烦是完全值得的。不仅仅是因为它保证你有权限查看自己的代码,它还可以通过扩展为 Git 的使用敞开了一扇大门,例如个人 Git 钩子、无限制的数据存储、和持续集成与分发CI & CD
如果你知道如何使用 Git 和 SSH那么你已经知道怎么创建一个 Git 服务器了。Git 的设计方式,就是让你在创建或者 clone 一个仓库的时候,就完成了一半服务器的搭建。然后允许用 SSH 访问仓库,而且任何有权限访问的人都可以使用你的仓库作为 clone 的新仓库的基础。
但是这是一个小的点对点环境ad-hoc。按照一些方案你可以创建一些带有同样的功能的设计优良的 Git 服务器,同时有更好的拓展性。
首要之事:确认你的用户们,现在的用户以及之后的用户都要考虑。如果你是唯一的用户那么没有任何改动的必要。但是如果你试图邀请其他的代码贡献者使用,那么你应该允许一个专门的分享系统用户给你的开发者们。
假定你有一个可用的服务器如果没有这不成问题Git 会帮忙解决CentOS 的 [树莓派 3][3] 是个不错的开始),然后第一步就是只允许使用 SSH 密钥认证的 SSH 登录。这比使用密码登录安全得多,因为这可以免于暴力破解,也可以通过直接删除用户密钥而禁用用户。
一旦你启用了 SSH 密钥认证,创建 `gituser` 用户。这是给你的所有授权的用户们的公共用户:
```
$ su -c 'adduser gituser'
```
然后切换到刚创建的 `gituser` 用户,创建一个 `~/.ssh` 的框架,并设置好合适的权限。这很重要,如果权限设置得太开放会使自己所保护的 SSH 没有意义。
```
$ su - gituser
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
```
`authorized_keys` 文件里包含所有你的开发者们的 SSH 公钥,你开放权限允许他们可以在你的 Git 项目上工作。他们必须创建他们自己的 SSH 密钥对然后把他们的公钥给你。复制公钥到 gituser 用户下的 `authorized_keys` 文件中。例如,为一个叫 Bob 的开发者,执行以下命令:
```
$ cat ~/path/to/id_rsa.bob.pub >> /home/gituser/.ssh/authorized_keys
```
只要开发者 Bob 有私钥并且把相对应的公钥给你Bob 就可以用 `gituser` 用户访问服务器。
但是,你并不是想让你的开发者们能使用服务器,即使只是以 `gituser` 的身份访问。你只是想给他们访问 Git 仓库的权限。因为这个特殊的原因Git 提供了一个限制的 shell准确的说是 `git-shell`。以 root 身份执行以下命令,把 `git-shell` 添加到你的系统中,然后设置成 `gituser` 用户的默认 shell。
```
# grep git-shell /etc/shells || su -c "echo `which git-shell` >> /etc/shells"
# su -c 'usermod -s git-shell gituser'
```
现在 `gituser` 用户只能使用 SSH 来 push 或者 pull Git 仓库,并且无法使用任何一个可以登录的 shell。你应该把你自己添加到和 `gituser` 一样的组中,在我们的样例服务器中这个组的名字也是 `gituser`
举个例子:
```
# usermod -a -G gituser seth
```
仅剩下的一步就是创建一个 Git 仓库。因为没有人能在服务器上直接与 Git 交互(也就是说,你之后不能 SSH 到服务器然后直接操作这个仓库),所以创建一个空的仓库 。如果你想使用这个放在服务器上的仓库来完成工作,你可以从它的所在处 `clone` 下来,然后在你的 home 目录下进行工作。
严格地讲你不是必须创建这个空的仓库它和一个正常的仓库一样工作。但是一个空的仓库没有工作分支working tree (也就是说,使用 `checkout` 并没有任何分支显示)。这很重要,因为不允许远程使用者们 `push` 到一个有效的分支上(如果你正在 `dev` 分支工作然后突然有人把一些变更 `push` 到你的工作分支,你会有怎么样的感受?)。因为一个空的仓库可以没有有效的分支,所以这不会成为一个问题。
你可以把这个仓库放到任何你想放的地方,只要你想要放开权限给用户和用户组,让他们可以在仓库下工作。千万不要保存目录到比如说一个用户的 home 目录下,因为那里有严格的权限限制。保存到一个常规的共享地址,例如 `/opt` 或者 `/usr/local/share`
以 root 身份创建一个空的仓库:
```
# git init --bare /opt/jupiter.git
# chown -R gituser:gituser /opt/jupiter.git
# chmod -R 770 /opt/jupiter.git
```
现在任何一个用户,只要他被认证为 `gituser` 或者在 `gituser` 组中,就可以从 jupiter.git 库中读取或者写入。在本地机器尝试以下操作:
```
$ git clone gituser@example.com:/opt/jupiter.git jupiter.clone
Cloning into 'jupiter.clone'...
Warning: you appear to have cloned an empty repository.
```
谨记:开发者们**一定**要把他们的 SSH 公钥加入到 `gituser` 用户下的 `authorized_keys` 文件里,或者说,如果他们有服务器上的用户(如果你给了他们用户),那么他们的用户必须属于 `gituser` 用户组。
### Git 钩子
运行你自己的 Git 服务器最赞的一件事之一就是可以使用 Git 钩子。Git 托管服务有时提供一个钩子类的接口,但是他们并不会给你真正的 Git 钩子来让你访问文件系统。Git 钩子是一个脚本,它将在一个 Git 过程的某些点运行;钩子可以运行在当一个仓库即将接收一个 commit 时、或者接受一个 commit 之后,或者即将接收一次 push 时,或者一次 push 之后等等。
这是一个简单的系统:任何放在 `.git/hooks` 目录下的脚本、使用标准的命名体系,就可按设计好的时间运行。一个脚本是否应该被运行取决于它的名字; `pre-push` 脚本在 `push` 之前运行,`post-receive` 脚本在接受 `commit` 之后运行等等。这或多或少的可以从名字上看出来。
脚本可以用任何语言写;如果在你的系统上有可以执行的脚本语言,例如输出 hello world ,那么你就可以这个语言来写 Git 钩子脚本。Git 默认带了一些例子,但是并不有启用。
想要动手试一个?这很简单。如果你没有现成的 Git 仓库,首先创建一个 Git 仓库:
```
$ mkdir jupiter
$ cd jupiter
$ git init .
```
然后写一个 “hello world” 的 Git 钩子。因为我为了支持老旧系统而使用 tsch所以我仍然用它作为我的脚本语言你可以自由的使用自己喜欢的语言BashPythonRubyPerlRustSwiftGo
```
$ echo "#\!/bin/tcsh" > .git/hooks/post-commit
$ echo "echo 'POST-COMMIT SCRIPT TRIGGERED'" >> ~/jupiter/.git/hooks/post-commit
$ chmod +x ~/jupiter/.git/hooks/post-commit
```
现在测试它的输出:
```
$ echo "hello world" > foo.txt
$ git add foo.txt
$ git commit -m 'first commit'
! POST-COMMIT SCRIPT TRIGGERED
[master (root-commit) c8678e0] first commit
1 file changed, 1 insertion(+)
create mode 100644 foo.txt
```
现在你已经实现了:你的第一个有功能的 Git 钩子。
### 有名的 push-to-web 钩子
Git 钩子最流行的用法就是自动 `push` 更改的代码到一个正在使用中的产品级 Web 服务器目录下。这是摆脱 FTP 的很好的方式,对于正在使用的产品保留完整的版本控制,整合并自动化内容的发布。
如果操作正确网站发布工作会像以前一样很好的完成而且在某种程度上很精准。Git 真的好棒。我不知道谁最初想到这个主意,但是我是从 Emacs 和 Git 方面的专家IBM 的 Bill von Hagen 那里第一次听到它的。他的文章包含关于这个过程的权威介绍:[Git 改变了分布式网页开发的游戏规则][1]。
### Git 变量
每一个 Git 钩子都有一系列不同的变量对应触发钩子的不同 Git 行为。你需不需要这些变量,主要取决于你写的程序。如果你只是需要一个当某人 push 代码时候的通用邮件通知,那么你就不需要什么特殊的东西,甚至也不需要编写额外的脚本,因为已经有现成的适合你的样例脚本。如果你想在邮件里查看 commit 信息和 commit 的作者,那么你的脚本就会变得相对麻烦些。
Git 钩子并不是被用户直接执行所以要弄清楚如何收集可能会混淆的重要信息。事实上Git 钩子脚本类似于其他的脚本,像 BASH、Python、C++ 等等一样从标准输入读取参数。不同的是,我们不会给它提供这个输入,所以,你在使用的时候,需要知道可能的输入参数。
在写 Git 钩子之前,看一下 Git 在你的项目目录下 `.git/hooks` 目录中提供的一些例子。举个例子,在这个 `pre-push.sample` 文件里,注释部分说明了如下内容:
```
# $1 -- 即将 push 的远程仓库的名字
# $2 -- 即将 push 的远程仓库的 URL
# 如果 push 的时候,并没有一个命名的远程仓库,那么这两个参数将会一样。
#
# 提交的信息将以下列形式按行发送给标准输入
# <local ref> <local sha1> <remote ref> <remote sha1>
```
并不是所有的例子都是这么清晰,而且关于钩子获取变量的文档依旧缺乏(除非你去读 Git 的源码)。但是,如果你有疑问,你可以从线上[其他用户的尝试中][2]学习,或者你只是写一些基本的脚本,比如 `echo $1, $2, $3` 等等。
### 分支检测示例
我发现,对于生产环境来说有一个共同的需求,就是需要一个只有在特定分支被修改之后,才会触发事件的钩子。以下就是如何跟踪分支的示例。
首先Git 钩子本身是不受版本控制的。 Git 并不会跟踪它自己的钩子,因为对于钩子来说,它是 Git 的一部分而不是你仓库的一部分。所以Git 钩子可以监控你的 Git 服务器上的一个空仓库的 commit 记录和 push 记录,而不是你本地仓库的一部分。
我们来写一个 `post-receive`(也就是说,在 `commit` 被接受之后触发)钩子。第一步就是需要确定分支名:
```
#!/bin/tcsh
foreach arg ( $< )
set argv = ( $arg )
set refname = $1
end
```
这个 for 循环用来读入第一个参数 `$1` ,然后循环用第二个参数 `$2` 去覆盖它,然后用第三个参数 `$3` 再这样。在 Bash 中有一个更好的方法,使用 `read` 命令,并且把值放入数组里。但是,这里是 tcsh并且变量的顺序可以预测的所以这个方法也是可行的。
当我们有了 commit 记录的 `refname`,我们就能使用 Git 去找到这个分支的供人看的名字:
```
set branch = `git rev-parse --symbolic --abbrev-ref $refname`
echo $branch #DEBUG
```
然后把这个分支名和我们想要触发的事件的分支名关键字进行比较:
```
if ( "$branch" == "master" ) then
echo "Branch detected: master"
git \
--work-tree=/path/to/where/you/want/to/copy/stuff/to \
checkout -f $branch || echo "master fail"
else if ( "$branch" == "dev" ) then
echo "Branch detected: dev"
Git \
--work-tree=/path/to/where/you/want/to/copy/stuff/to \
checkout -f $branch || echo "dev fail"
else
echo "Your push was successful."
echo "Private branch detected. No action triggered."
endif
```
给这个脚本分配可执行权限:
```
$ chmod +x ~/jupiter/.git/hooks/post-receive
```
现在,当一个用户提交到服务器的 master 分支,那些代码就会被复制到一个生产环境的目录,提交到 dev 分支则会被复制到另外的地方,其他分支将不会触发这些操作。
同时,创造一个 `pre-commit` 脚本也很简单。比如,判断一个用户是否在他们不该 `push` 的分支上 `push` 代码,或者对 commit 信息进行解析等等。
Git 钩子也可以变得复杂,而且它们因为 Git 的工作流的抽象层次不同而变得难以理解,但是它们确实是一个强大的系统,让你能够在你的 Git 基础设施上针对所有的行为进行对应的操作。如果你是一个 Git 重度用户,或者一个全职 Git 管理员,那么 Git 钩子是值得学习的,只有当你熟悉这个过程,你才能真正掌握它。
在我们这个系列下一篇也是最后一篇文章中,我们将会学习如何使用 Git 来管理非文本的二进制数据,比如音频和图片。
--------------------------------------------------------------------------------
via: https://opensource.com/life/16/8/how-construct-your-own-git-server-part-6
作者:[Seth Kenlon][a]
译者:[maywanting](https://github.com/maywanting)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[1]: http://www.ibm.com/developerworks/library/wa-git/
[2]: https://www.analysisandsolutions.com/code/git-hooks-summary-cheat-sheet.htm
[3]: https://wiki.centos.org/SpecialInterestGroup/AltArch/Arm32/RaspberryPi3

View File

@ -0,0 +1,58 @@
在 WordPress 下如何通过 Markdown 来提高工作效率
=================
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/markdown-wordpress-featured-2.jpg)
Markdown 是一种简单的标记语言,旨在帮助你花费更小的代价来格式化纯文本文档。在 WordPress 下你可以使用 HTML 或者可视化编辑器来格式化你的文档,但是使用 markdown 可以让格式化文档变得更加容易而且你随时可以导出成很多种格式包括但不限于HTML。
WordPress 没有原生的 markdown 的支持,但是,如果你希望的话,在你的网站上有多种插件可以添加这种功能。
在这个教程中,我将会演示如何使用流行的 WP-Markdown 插件为 WordPress 网站添加 markdown 支持。
### 安装
导航到 “Plugins -> Add New”然后在提供的搜索框中输入 “[wp-markdown][1]” 就可以直接安装。插件应该会出现在列表中的第一个。单击 “Install Now” 进行安装。
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/08/markdown-wordpress-install-plugin-1.png)
### 配置
当你已经安装了这个插件并且激活它之后,导航到 “Settings -> Writing” 并向下滚动,直到 markdown 选项。
你可以启用文章、页面和评论中对于 markdown 的支持。如果你刚刚开始学习 markdown 语法的话,那么你也可以在文章编辑器或者评论的地方启用一个帮助栏,这可以使你更方便一些。
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/markdown-wordpress-configuration.png)
如果在你的博客文章中包括代码片段的话,那么启用 “Prettify syntax highlighter” 将会让你的代码片段自动语法高亮。
一旦对于你的选择感觉满意的话,那么就单击 “Save Changes” 来保存你的设置吧。
### 使用 Markdown 来写你的文章
当你在自己网站中启用了 markdown 的支持,你就可以立马开始使用了。
通过 “Posts -> Add New” 创建一篇新的文章。你将会注意到默认的可视化及纯文本编辑器已经被 markdown 编辑器所替代。
如果你在配置选项中没有启用 markdown 的帮助栏,你将不会看到 markdown 格式化后的实时预览。然而,只要你的语法是正确的,当你保存或者发布文章的时候,你的 markdown 就会转换成正确的 HTML。
然而,如果你是 markdown 的初学者的话,实时预览这一特征对你会很重要,只需要简单的回到刚才的设置中启用帮助栏选项,你就可以在你的文章底部看到一块漂亮的实时预览区域。另外,你也可以在顶部看到很多按钮,它们将帮助你在文章中快速的插入 markdown 格式。
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/08/markdown-wordpress-create-post.png)
### 结语
正如你所看到的那样,在 WordPress 网站上添加 markdown 支持确实容易,你将只需要花费几分钟的时间就可以了。如果对于 markdown 你全然不知的话,或许你也可以查看我们的 [markdown 备忘录][2],它将对于 markdown 语法提供一个全面的参考。
--------------------------------------------------------------------------------
via: https://www.maketecheasier.com/use-markdown-in-wordpress/
作者:[Ayo Isaiah][a]
译者:[yangmingming](https://github.com/yangmingming)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.maketecheasier.com/author/ayoisaiah/
[1]: https://wordpress.org/plugins/wp-markdown/
[2]: https://www.maketecheasier.com/productive-with-markdown-cheatsheet/

View File

@ -0,0 +1,54 @@
TaskwarriorLinux 下一个很棒的命令行 TODO 工具
==============
Taskwarrior 是 Ubuntu/Linux 下一个简单而直接的基于命令行的 TODO 工具。这个开源软件是我曾用过的最简单的[基于命令行的工具][4]之一。Taskwarrior 可以帮助你更好地组织你自己,而不用安装笨重的新工具——这有时丧失了 TODO 工具的目的。
![](https://2.bp.blogspot.com/-pQnRlOUNIxk/V9cuc3ytsBI/AAAAAAAAKHs/yYxyiAk4PwMIE0HTxlrm6arWOAPcBRRywCLcB/s1600/taskwarrior-todo-app.png)
### Taskwarrior一个基于简单的基于命令行帮助完成任务的TODO工具
Taskwarrior是一个开源、跨平台、基于命令行的 TODO 工具,它帮你在终端中管理你的 to-do 列表。这个工具让你可以轻松地添加任务、展示列表、移除任务。而且,在你的默认仓库中就有,不用安装新的 PPA。在 Ubuntu 16.04 LTS 或者相似的发行版中。在终端中按照如下步骤安装 Taskwarrior。
```
sudo apt-get install task
```
简单的用如下:
```
$ task add Read a book
Created task 1.
$ task add priority:H Pay the bills
Created task 2.
```
我使用上面截图中的同样一个例子。是的你可以设置优先级H、L 或者 M。并且你可以使用task或者task next命令来查看你最新创建的 to-do 列表。比如:
```
$ task next
ID Age P Description Urg
-- --- - -------------------------------- ----
2 10s H Pay the bills 6
1 20s Read a book 0
```
完成之后,你可以使用 task 1 done 或者 task 2 done 来清除列表。[可以在这里][1]找到更加全面的命令和使用案例。同样Taskwarrior 是跨平台的,这意味着不管怎样,你都可以找到一个[满足你需求][2]的版本。如果你需要的话,这里甚至有[一个安卓版][3]。祝您用得开心!
--------------------------------------------------------------------------------
via: http://www.techdrivein.com/2016/09/taskwarrior-command-line-todo-app-linux.html
作者:[Manuel Jose][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: http://www.techdrivein.com/2016/09/taskwarrior-command-line-todo-app-linux.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+techdrivein+%28Tech+Drive-in%29
[1]: https://taskwarrior.org/docs/
[2]: https://taskwarrior.org/download/
[3]: https://taskwarrior.org/news/news.20160225.html
[4]: http://www.techdrivein.com/search/label/Terminal

View File

@ -0,0 +1,314 @@
# How to Build Your First Slack Bot with Python
[Bots](https://www.fullstackpython.com/bots.html) are a useful way to interact with chat services such as [Slack](https://slack.com/). If you have never built a bot before, this post provides an easy starter tutorial for combining the [Slack API](https://api.slack.com/) with Python to create your first bot.
We will walk through setting up your development environment, obtaining a Slack API bot token and coding our simple bot in Python.
### Tools We Need
Our bot, which we will name "StarterBot", requires Python and the Slack API. To run our Python code we need:
* Either [Python 2 or 3](https://www.fullstackpython.com/python-2-or-3.html)
* [pip](https://pip.pypa.io/en/stable/) and [virtualenv](https://virtualenv.pypa.io/en/stable/) to handle Python [application dependencies](https://www.fullstackpython.com/application-dependencies.html)
* [Free Slack account](https://slack.com/) with a team on which you have API access or sign up for the [Slack Developer Hangout team](http://dev4slack.xoxco.com/)
* Official Python [slackclient](https://github.com/slackhq/python-slackclient) code library built by the Slack team
* [Slack API testing token](https://api.slack.com/tokens)
It is also useful to have the [Slack API docs](https://api.slack.com/) handy while you're building this tutorial.
All the code for this tutorial is available open source under the MIT license in the [slack-starterbot](https://github.com/mattmakai/slack-starterbot) public repository.
### Establishing Our Environment
We now know what tools we need for our project so let's get our development environment set up. Go to the terminal (or Command Prompt on Windows) and change into the directory where you want to store this project. Within that directory, create a new virtualenv to isolate our application dependencies from other Python projects.
```
virtualenv starterbot
```
Activate the virtualenv:
```
source starterbot/bin/activate
```
Your prompt should now look like the one in this screenshot.
![Command prompt with starterbot's virtualenv activated.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/virtualenv-activate.png)
The official slackclient API helper library built by Slack can send and receive messages from a Slack channel. Install the slackclient library with the pip command:
```
pip install slackclient
```
When pip is finished you should see output like this and you'll be back at the prompt.
![Output from using the pip install slackclient command with a virtualenv activated.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/pip-install-slackclient.png)
We also need to obtain an access token for our Slack team so our bot can use it to connect to the Slack API.
### Slack Real Time Messaging (RTM) API
Slack grants programmatic access to their messaging channels via a [web API](https://www.fullstackpython.com/application-programming-interfaces.html). Go to the[Slack web API page](https://api.slack.com/) and sign up to create your own Slack team. You can also sign into an existing account where you have administrative privileges.
![Use the sign in button on the top right corner of the Slack API page.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/sign-in-slack.png)
After you have signed in go to the [Bot Users page](https://api.slack.com/bot-users).
![Custom bot users webpage.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/custom-bot-users.png)
Name your bot "starterbot" then click the “Add bot integration” button.
![Add a bot integration named starterbot.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot.jpg)
The page will reload and you will see a newly-generated access token. You can also change the logo to a custom design. For example, I gave this bot the Full Stack Python logo.
![Copy and paste the access token for your new Slack bot.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/slack-token.png)
Click the "Save Integration" button at the bottom of the page. Your bot is now ready to connect to Slack's API.
A common practice for Python developers is to export secret tokens as environment variables. Export the Slack token with the name SLACK_BOT_TOKEN:
```
export SLACK_BOT_TOKEN='your slack token pasted here'
```
Nice, now we are authorized to use the Slack API as a bot.
There is one more piece of information we need to build our bot: our bot's ID. Next we will write a short script to obtain that ID from the Slack API.
### Obtaining Our Bots ID
It is finally time to write some Python code! We'll get warmed up by coding a short Python script to obtain StarterBot's ID. The ID varies based on the Slack team.
We need the ID because it allows our application to determine if messages parsed from the Slack RTM are directed at StarterBot. Our script also tests that our SLACK_BOT_TOKENenvironment variable is properly set.
Create a new file named print_bot_id.py and fill it with the following code.
```
import os
from slackclient import SlackClient
BOT_NAME = 'starterbot'
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
if __name__ == "__main__":
api_call = slack_client.api_call("users.list")
if api_call.get('ok'):
# retrieve all users so we can find our bot
users = api_call.get('members')
for user in users:
if 'name' in user and user.get('name') == BOT_NAME:
print("Bot ID for '" + user['name'] + "' is " + user.get('id'))
else:
print("could not find bot user with the name " + BOT_NAME)
```
Our code imports the SlackClient and instantiates it with our SLACK_BOT_TOKEN, which we set as an environment variable. When the script is executed by the python command we call the Slack API to list all Slack users and get the ID for the one that matches the name "starterbot".
We only need to run this script once to obtain our bots ID.
```
python print_bot_id.py
```
The script prints a single line of output when it is run that provides us with our bot's ID.
![Use the Python script to print the Slack bot's ID in your Slack team.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/printed-bot-id.png)
Copy the unique ID that your script prints out. Export the ID as an environment variable named BOT_ID.
```
(starterbot)$ export BOT_ID='bot id returned by script'
```
The script only needs to be run once to get the bot ID. We can now use that ID in our Python application that will run StarterBot.
### Coding Our StarterBot
We've got everything we need to write the StarterBot code. Create a new file namedstarterbot.py and include the following code in it.
```
import os
import time
from slackclient import SlackClient
```
The os and SlackClient imports will look familiar because we used them in theprint_bot_id.py program.
With our dependencies imported we can use them to obtain the environment variable values and then instantiate the Slack client.
```
# starterbot's ID as an environment variable
BOT_ID = os.environ.get("BOT_ID")
# constants
AT_BOT = "<@" + BOT_ID + ">:"
EXAMPLE_COMMAND = "do"
# instantiate Slack & Twilio clients
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
```
The code instantiates the SlackClient client with our SLACK_BOT_TOKEN exported as an environment variable.
```
if __name__ == "__main__":
READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
if slack_client.rtm_connect():
print("StarterBot connected and running!")
while True:
command, channel = parse_slack_output(slack_client.rtm_read())
if command and channel:
handle_command(command, channel)
time.sleep(READ_WEBSOCKET_DELAY)
else:
print("Connection failed. Invalid Slack token or bot ID?")
```
The Slack client connects to the Slack RTM API WebSocket then constantly loops while parsing messages from the firehose. If any of those messages are directed at StarterBot, a function named handle_command determines what to do.
Next add two new functions to parse Slack output and handle commands.
```
def handle_command(command, channel):
"""
Receives commands directed at the bot and determines if they
are valid commands. If so, then acts on the commands. If not,
returns back what it needs for clarification.
"""
response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \
"* command with numbers, delimited by spaces."
if command.startswith(EXAMPLE_COMMAND):
response = "Sure...write some more code then I can do that!"
slack_client.api_call("chat.postMessage", channel=channel,
text=response, as_user=True)
def parse_slack_output(slack_rtm_output):
"""
The Slack Real Time Messaging API is an events firehose.
this parsing function returns None unless a message is
directed at the Bot, based on its ID.
"""
output_list = slack_rtm_output
if output_list and len(output_list) > 0:
for output in output_list:
if output and 'text' in output and AT_BOT in output['text']:
# return text after the @ mention, whitespace removed
return output['text'].split(AT_BOT)[1].strip().lower(), \
output['channel']
return None, None
```
The parse_slack_output function takes messages from Slack and determines if they are directed at our StarterBot. Messages that start with a direct command to our bot ID are then handled by our code - which is currently just posts a message back in the Slack channel telling the user to write some more Python code!
Here is how the entire program should look when it's all put together (you can also [view the file in GitHub](https://github.com/mattmakai/slack-starterbot/blob/master/starterbot.py)):
```
import os
import time
from slackclient import SlackClient
# starterbot's ID as an environment variable
BOT_ID = os.environ.get("BOT_ID")
# constants
AT_BOT = "<@" + BOT_ID + ">:"
EXAMPLE_COMMAND = "do"
# instantiate Slack & Twilio clients
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
def handle_command(command, channel):
"""
Receives commands directed at the bot and determines if they
are valid commands. If so, then acts on the commands. If not,
returns back what it needs for clarification.
"""
response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \
"* command with numbers, delimited by spaces."
if command.startswith(EXAMPLE_COMMAND):
response = "Sure...write some more code then I can do that!"
slack_client.api_call("chat.postMessage", channel=channel,
text=response, as_user=True)
def parse_slack_output(slack_rtm_output):
"""
The Slack Real Time Messaging API is an events firehose.
this parsing function returns None unless a message is
directed at the Bot, based on its ID.
"""
output_list = slack_rtm_output
if output_list and len(output_list) > 0:
for output in output_list:
if output and 'text' in output and AT_BOT in output['text']:
# return text after the @ mention, whitespace removed
return output['text'].split(AT_BOT)[1].strip().lower(), \
output['channel']
return None, None
if __name__ == "__main__":
READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
if slack_client.rtm_connect():
print("StarterBot connected and running!")
while True:
command, channel = parse_slack_output(slack_client.rtm_read())
if command and channel:
handle_command(command, channel)
time.sleep(READ_WEBSOCKET_DELAY)
else:
print("Connection failed. Invalid Slack token or bot ID?")
```
Now that all of our code is in place we can run our StarterBot on the command line with the python starterbot.py command.
![Console output when the StarterBot is running and connected to the API.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/starterbot-running.png)
In Slack, create a new channel and invite StarterBot or invite it to an existing channel.
![In the Slack user interface create a new channel and invite StarterBot.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/create-channel.png)
Now start giving StarterBot commands in your channel.
![Give StarterBot commands in your Slack channel.](https://www.fullstackpython.com/source/static/img/160604-simple-python-slack-bot/working-starterbot.png)
There is one modification you may want to make if you're running into issues getting a response from the bot. As it is written above in this tutorial, the lineAT_BOT = "<@" + BOT_ID + ">:" requires a colon after the "@starter" (or whatever you named your particular bot). Remove the : from the end of the AT_BOT string. The Slack clients seem to add a colon after an @ mention but it seems somewhat inconsistent.
### Wrapping Up
Alright, now you've got a simple StarterBot with a bunch of places in the code you can add whatever features you want to build.
There is a whole lot more that could be done using the Slack RTM API and Python. Check out these posts to learn what you could do:
* Attach a persistent [relational database](https://www.fullstackpython.com/databases.html) or [NoSQL back-end](https://www.fullstackpython.com/no-sql-datastore.html) such as [PostgreSQL](https://www.fullstackpython.com/postgresql.html),[MySQL](https://www.fullstackpython.com/mysql.html) or [SQLite](https://www.fullstackpython.com/sqlite.html) to save and retrieve user data
* Add another channel to interact with the bot [via SMS](https://www.twilio.com/blog/2016/05/build-sms-slack-bot-python.html) or [phone calls](https://www.twilio.com/blog/2016/05/add-phone-calling-slack-python.html)
* [Integrate other web APIs](https://www.fullstackpython.com/api-integration.html) such as [GitHub](https://developer.github.com/v3/), [Twilio](https://www.twilio.com/docs) or [api.ai](https://docs.api.ai/)
Questions? Contact me via Twitter [@fullstackpython](https://twitter.com/fullstackpython) or [@mattmakai](https://twitter.com/mattmakai). I'm also on GitHub with the username [mattmakai](https://github.com/mattmakai).
Something wrong with this post? Fork [this page's source on GitHub](https://github.com/mattmakai/fullstackpython.com/blob/gh-pages/source/content/posts/160604-build-first-slack-bot-python.markdown).
--------------------------------------------------------------------------------
via: https://www.fullstackpython.com/blog/build-first-slack-bot-python.html
作者: [Matt Makai][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出aa
[a]: https://www.fullstackpython.com/about-author.html

View File

@ -0,0 +1,137 @@
Part III - How to apply Advanced Mathematical Processing Effects on Audio files with Octave 4.0 on Ubuntu
=====
The third part of our Digital Audio processing tutorial series covers the signal Modulation, we explain how to apply Amplitude Modulation, Tremolo Effect, and Frequency Variation.
### Modulation
#### Amplitude Modulation
As its name implies, this effect varies the amplitude of a sinusoid according to the message to be transmitted. A sine wave is called a carrier because it carries the information. This type of modulation is used in some commercial broadcasting and transmission citizen bands (AM).
#### Why use the Amplitude Modulation?
**Modulation Radiation.**
If the communication channel is a free space, then antennas are required to radiate and receive the signal. It requires an efficient electromagnetic radiation antenna whose dimensions are of the same order of magnitude as the wavelength of the signal being radiated. Many signals, including audio components, have often 100 Hz or less. For these signals, it would be necessary to build antennas about 300 km in length if the signal were to be radiated directly. If signal modulation is used to print the message on a high-frequency carrier, let's say 100 MHz, then the antenna needs to have a length of over a meter (transverse length) only.
**Concentration modulation or multi-channeling.**
If more than one signal uses a single channel, modulation can be used for transferring different signals to different spectral positions allowing the receiver to select the desired signal. Applications that use concentration ("multiplexing") include telemetry data, stereo FM radio and long-distance telephony.
**Modulation to Overcome Limitations on equipment.**
The performance of signal processing devices such as filters and amplifiers, and the ease with which these devices can be constructed, depends on the situation of the signal in the frequency domain and the relationship between the higher frequency and low signal. Modulation can be used to transfer the signal to a position in the frequency domain where design requirements are met easier. The modulation can also be used to convert a "broadband signal" (a signal for which the ratio between the highest and lowest frequency is large) into a sign of "narrow band".
**Audio Effects**
Many audio effects use amplitude modulation due to the striking and ease with which it can handle such signals. We can name a few such as tremolo, chorus, flanger, etc. This utility is where we focus in this tutorial series.
### Tremolo effect
The tremolo effect is one of the simplest applications of amplitude modulation, to achieve this effect, we have to vary (multiply) the audio signal by a periodic signal, either sinusoidal or otherwise.
```
>> tremolo='tremolo.ogg';
>> fs=44100;
>> t=0:1/fs:10;
>> wo=2*pi*440*t;
>> wa=2*pi*1.2*t;
>> audiowrite(tremolo, cos(wa).*cos(wo),fs);
```
[![Tremolo](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolo.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolo.png)
This will generate a sinusoid-shaped signal which effect is like a 'tremolo'.
[![Tremolo Shape](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremoloshape.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremoloshape.png)
### Tremolo on real Audio Files
Now we will show the tremolo effect in the real world, First, we use a file previously recorded by a male voice saying 'A'. The plot for this signal is the following:
```
>> [y,fs]=audioread('A.ogg');
>> plot(y);
```
[![Vocal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/avocalmale.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/avocalmale.png)
Now we have to create an enveloping sinusoidal signal with the following parameters:
```
Amplitude = 1
Frequency= 1.5Hz
Phase = 0
```
```
>> t=0:1/fs:4.99999999;
>> t=t(:);
>> w=2*pi*1.5*t;
>> q=cos(w);
>> plot(q);
```
Note: when we create an array of values of the time, by default, this is created in the form of columns, ie, 1x220500 values. To multiply this set of values must transpose it in rows (220500x1). This is the t=t(:) command
[![Sinusodial](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/sinusoidal.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/sinusoidal.png)
We will create a second ogg file which contains the resulting modulated signal:
```
>> tremolo='tremolo.ogg';
>> audiowrite(tremolo, q.*y,fs);
```
[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremsignal1.png)[![Tremolo Signal](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/tremolsignal1.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/tremolsignal1.png)
### Frequency Variation
We can vary the frequency to obtain quite interesting musical effects such as distortion, sound effects for movies and games among others.
#### Effect of sinusoidal frequency modulation
This is the code where the sinusoidal modulation frequency is shown, according to equation:
```
Y=Ac*Cos(wo*Cos(wo/k))
```
Where:
```
Ac = Amplitude
wo = fundamental frequency
k = scalar divisor
```
```
>> fm='fm.ogg';
>> fs=44100;
>> t=0:1/fs:10;
>> w=2*pi*442*t;
>> audiowrite(fm, cos(cos(w/1500).*w), fs);
>> [y,fs]=audioread('fm.ogg');
>> figure (); plot (y);
```
The plot of the signal is:
[![](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/fmod.png)](https://www.howtoforge.com/images/ubuntu-octave-audio-processing-part-3/big/fmod.png)
You can use almost any type of periodic function as the frequency modulator. For this example, we only used a sine function here. Please feel free to experiment with changing the frequencies of the functions, mixing with other functions or change, even, the type of function.
--------------------------------------------------------------------------------
via: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/
作者:[David Duarte][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.howtoforge.com/tutorial/ubuntu-octave-audio-processing-part-3/

View File

@ -1,3 +1,4 @@
yangmingming Translating
What is copyleft?
=============

View File

@ -1,140 +0,0 @@
你必须了解的 Linux 基础网络命令
==================================================
![](https://itsfoss.com/wp-content/uploads/2016/06/Basic-Networking-Commands-Linux.jpg)
摘要:有抱负的 Linux 系统管理员和 Linux 狂热者必须知道的最重要而且基础的 Linux 网络命令合集。
在 Its FOSS 我们并非每天都谈论 Linux 的“命令行方面”。基本上,我更专注于 Linux 的桌面端。但你们读者中的一些人在内部调查(仅面向 It's FOSS newsletter 订阅者)中指出,你们也想学些命令行技巧。速查表也受大部分读者所喜欢和支持。
为此,我编辑了一个 Linux 中基础网络命令的列表。它并不是一个教你如何使用这些命令的教程,而是一个命令合集和他们的简短解释。所以,如果你已经使用过这些命令,你可以用它来快速记住命令。
你可以把这个网页添加为书签以便快速查阅,或下载这些命令的 PDF 版本以便离线使用。
当我还是通信系统工程专业的学生的时候我就有这个 Linux 网络命令的列表了。它帮助我在计算机网络课程获得了高分。希望它也能以同样的方式帮助你。
> 独家内容:[下载 Linux 网络命令速查表][1] 以便将来查阅。你可以打印或保存它以便离线查看。
### Linux 基础网络命令列表
我在计算机网络课程上使用 FreeBSD不过这些 UNIX 命令应该也能在 Linux 上同样工作。
#### 连通性
- __ping <host\>__:发送 ICMP echo 消息(一个包)到主机。这可能会不停地发送直到你按下 Control-C。Ping 通意味着一个包从你的机器通过 ICMP 发送出去,并在 IP 层回显。Ping 告诉你另一个主机是否在运行。
- __telnet <host\> [port]__:与主机在指定的端口通信。默认的 telnet 端口是 23。其它一些常用的端口是
7 —— echo 端口
25 —— SMTP用于发送邮件
79 —— Finger译注[维基百科 - Finger protocal](https://en.wikipedia.org/wiki/Finger_protocol)),提供该网络下其它用户的信息
按 Control-] 以退出 telnet。
#### ARP
ARP 用于将 IP 地址转换为以太网地址。Root 用户可以添加和删除 ARP 记录。当 ARP 记录被污染或者错误时删除他们会有用。Root 显式添加的 ARP 记录是永久的 —— 代理设置的也是。ARP 表保存在内核中动态地被操作。ARP 记录会被缓存,通常在 20 分钟后失效并被删除。
- __arp -a__:打印 ARP 表
- __arp -s <ip_address\> <mac_address\> [pub]__:添加一条记录到表中
- __arp -a -d__:删除 ARP 表中的所有记录
#### 路由
- __netstat -r__:打印路由表。路由表保存在内核中,用于 IP 层路由包到非本地网络。
- __route add__route 命令用于向路由表添加静态(手动输入而非动态)路由路径。所有从该 PC 到那个 IP/子网的流量都会经由指定的网关 IP。它也可以用来设置一个默认路由。例如在 IP/子网处使用 0.0.0.0,就可以发送所有包到特定的网关。
- __routed__:控制动态路由的 BSD 守护程序。开机时启动。它运行 RIP 路由协议。只有 root 用户可用。没有 root 权限你不能运行它。
- __gated__gated 是另一个使用 RIP 的路由守护进程。它同时支持 OSPF、EGP 和 RIP 协议。只有 root 用户可用。
- __traceroute__:用于跟踪 IP 包的路由。它每次发送包时都把跳数加 1从而使得从源地址到目的地之间的所有网关都会返回消息。
- __netstat -rnf inet__:显示 IPv4 的路由表
- __sysctl net.inet.ip.forwarding=1__:启用包转发(把主机变为路由器)
- __route add|delete [-net|-host] <destination\> <gateway\>__:(如 `route add 192.168.20.0/24 192.168.30.4`)添加一条路由
- __route flush__:删除所有路由
- __route add -net 0.0.0.0 192.168.10.2__:添加一条默认路由
- __routed -Pripv2 -Pno_rdisc -d [-s|-q]__:运行 routed 守护进程,使用 RIPv2 协议,不启用 ICMP 自动发现,在前台运行,供给模式或安静模式。
- __route add 224.0.0.0/4 127.0.0.1__:定义 RIPv2 使用的路由(译注:翻译存疑)
- __rtquery -n <host\>__(译注:增加了 host 参数):查询指定主机上的 RIP 守护进程(手动更新路由表)
#### 其它
- __nslookup__:向 DNS 服务器查询,将 IP 转为名称,或反之。例如,`nslookup facebook.com` 会给出 facebook.com 的 IP。
- __ftp <host\> [port]__(译注:原文中 water 应是笔误):传输文件到指定主机。通常可以使用 login="anonymous" , p/w="guest" 登录。
- __rlogin -l <host\>__(译注:添加了 host 参数):使用类似 telnet 的虚拟终端登录到主机
#### 重要文件
- __/etc/hosts__域名到 IP 地址的映射
- __/etc/networks__网络名称到 IP 地址的映射
- __/etc/protocols__协议名称到协议编号的映射
- __/etc/services__TCP/UDP 服务名称到端口号的映射
#### 工具和网络性能分析
- __ifconfig <interface\> <address\> [up]__:启动接口
- __ifconfig <interface\> [down|delete]__:停止接口
- __ethereal &__:在后台打开 `ethereal` 而非前台
- __tcpdump -i -vvv__:抓取和分析包的工具
- __netstat -w [seconds] -I [interface]__:显示网络设置和统计信息
- __udpmt -p [port] -s [bytes] target_host__:发送 UDP 流量
- __udptarget -p [port]__:接收 UDP 流量
- __tcpmt -p [port] -s [bytes] target_host__:发送 TCP 流量
- __tcptarget -p [port]__:接收 TCP 流量
#### 交换机
- __ifconfig sl0 srcIP dstIP__:配置一个序列接口(在此前先执行 `slattach -l /dev/ttyd0`,此后执行 `sysctl net.inet.ip.forwarding=1`
- __telnet 192.168.0.254__:从子网中的一台主机访问交换机
- __sh ru____show running-configuration__:查看当前配置
- __configure terminal__:进入配置模式
- __exit__:进入低级配置模式(译注:翻译存疑)
#### VLAN
- __vlan n__:创建一个 ID 为 n 的 VLAN
- __no vlan N__:删除 ID 为 n 的 VLAN
- __untagged Y__:添加端口 Y 到 VLAN n
- __ifconfig vlan0 create__:创建 vlan0 接口
- __ifconfig vlan0 vlan ID vlandev em0__:连接 vlan0 接口到 em0 之上(译注:翻译存疑),并设置标记为 ID
- __ifconfig vlan0 [up]__:启用虚拟接口
- __tagged Y__:为当前 VLAN 的端口 Y 添加标记帧支持
#### UDP/TCP
- __socklab udp__:使用 UDP 协议运行 `socklab`
- __sock__:创建一个 UDP 套接字,等效于输入 `sock udp``bind`
- __sendto <Socket ID\> <hostname\> <port #\>__:发送数据包
- __recvfrom <Socket ID\> <byte #\>__:从套接字接收数据
- __socklab tcp__:使用 TCP 协议运行 `socklab`
- __passive__:创建一个被动模式的套接字,等效于 `socklab``sock tcp``bind``listen`
- __accept__:接受进来的连接(可以在发起进来的连接之前或之后执行)
- __connect <hostname\> <port #\>__:等效于 `socklab``sock tcp``bind``connect`
- __close__:关闭连接
- __read <byte #\>__:从套接字中读取 n 字节
- __write__:(例如,`write ciao`、`write #10`)向套接字写入 "ciao" 或 10 个字节
#### NAT/防火墙
- __rm /etc/resolv.conf__:禁止地址解析,保证你的过滤和防火墙规则正确工作
- __ipnat -f file_name__:将过滤规则写入文件
- __ipnat -l__:显示活动的规则列表
- __ipnat -C -F__:重新初始化规则表
- __map em0 192.168.1.0/24 -> 195.221.227.57/32 em0__:将 IP 地址映射到接口
- __map em0 192.168.1.0/24 -> 195.221.227.57/32 portmap tcp/udp 20000:50000__:带端口号的映射
- __ipf -f file_name__:将过滤规则写入文件
- __ipf -F -a__:重置规则表
- __ipfstat -I__:在过滤的包上允许访问某些信息(译注:翻译存疑),也包括活动的过滤规则
希望这份基础的 Linux 网络命令合集对你有用。问题和建议总是受欢迎的。
--------------------------------------------------------------------------------
via: https://itsfoss.com/basic-linux-networking-commands
作者:[Abhishek Prakash][a]
译者:[bianjp](https://github.com/bianjp)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://itsfoss.com/author/abhishek/
[1]: https://drive.google.com/open?id=0By49_3Av9sT1cDdaZnh4cHB4aEk

View File

@ -1,222 +0,0 @@
如何搭建你自己的 Git 服务器
====================
![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/bus-big-data.png?itok=sOQHDuID)
现在我们将要学习如何搭建 git 服务器,如何编写自定义的 Git 钩子来在特定的事件触发相应的动作(例如通知),或者是发布你的代码到一个站点。
直到现在,作为一个使用者注意力还是被 Git 影响。这篇文章中我将讨论 Git 的管理,并且设计一个灵活的 Git 框架。你可能会觉得这听起来是 “高阶 Git 技术” 或者 “只有狂热粉才能阅读”的一句委婉的说法,但是事实是这里面的每个任务都不需要很深的知识或者其他特殊的训练,就能立刻理解 Git 的工作原理,有可能需要一丁点关于 Linux 的知识
### 共享 Git 服务器
创建你自己的共享 Git 服务器意外地简单,而且遇到各方面的问题时都很值得。不仅仅是因为它保证你有权限查看自己的代码,它还对于利用扩展来维持 Git 的通信敞开了一扇大门,例如个人 Git 钩子,无限制的数据存储,和持续的整合与发布
如果你知道如何使用 Git 和 SSH那么你已经知道怎么创建一个 Git 服务器了。Git 的设计方式,就是让你在创建或者 clone 一个仓库的时候,就完成了一半服务器的搭建。然后允许用 SSH 访问仓库,而且任何有权限访问的人都可以使用你的仓库,作为 clone 的新仓库的基础。
但是,这是一个小的自组织。按照一些计划你可以以同样的效果创建一些设计优良的 Git 服务器,同时有更好的拓展性。
首要之事:确认你的用户们,现在的用户以及之后的用户都要考虑。如果你是唯一的用户那么没有任何改动的必要。但是如果你试图邀请其他的代码贡献者,那么你应该允许一个专门的分享系统用户给你的开发者们。
假定你有一个可用的服务器如果没有这不成问题Git 会帮忙解决CentOS 的 Raspberry Pi 3 是个不错的开始),然后第一步就是只允许使用 SSH 密钥认证的 SSH 登录。
一旦你启用了 SSH 密钥认证,创建 gituser 用户。这是给你的所有确认的开发者们的公共用户。
```
$ su -c 'adduser gituser'
```
然后切换到刚创建的 gituser 用户,创建一个 `~/.ssh` 的框架,并设置好合适的权限。这很重要,如果权限设置得太开放会使自己受保护的 SSH 默认失败。
```
$ su - gituser
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
```
`authorized_keys` 文件里包含所有你的开发者们的 SSH 公钥,你开放权限允许他们可以在你的 Git 项目上工作。他们必须创建他们自己的 SSH 密钥对然后把他们的公钥给你。复制公钥到 gituser 用户下的 `authorized_keys` 文件中。例如,为一个叫 Bob 的开发者,执行以下命令:
```
$ cat ~/path/to/id_rsa.bob.pub >> \
/home/gituser/.ssh/authorized_keys
```
只要开发者 Bob 有私钥并且把相对应的公钥给你Bob 就可以用 gituser 用户访问服务器。
但是,你并不是想让你的开发者们能使用服务器,即使只是以 gituser 的身份访问。你只是想给他们访问 Git 仓库的权限。因为这个特殊的原因Git 提供了一个限制的 shell准确的说是 git-shell。以 root 身份执行以下命令,把 git-shell 添加到你的系统中,然后设置成 gituser 用户默认的shell。
```
# grep git-shell /etc/shells || su -c \
"echo `which git-shell` >> /etc/shells"
# su -c 'usermod -s git-shell gituser'
```
现在 gituser 用户只能使用 SSH 来 push 或者 pull Git 仓库,并且无法使用任何一个可以登录的 shell。你应该把你自己添加到和 gituser 一样的组中,在我们的样例服务器中仍是这个组的名字仍是 gituser。
举个例子:
```
# usermod -a -G gituser seth
```
仅剩下的一步就是创建一个 Git 仓库。因为没有人能在服务器上与 Git 交互(也就是说,你之后不能 SSH 到服务器然后直接操作这个仓库),创一个最原始的仓库 。如果你想使用位于服务器上的仓库来完成工作,你可以从它的所在处 clone 下来然后直接在你的 home 目录下工作。
说白了,你不需要让它变成一个空的仓库,你需要像工作在一个正常的仓库一样。但是,一个空的仓库没有 *working tree* (也就是说,使用 `checkout` 并没有任何分支显示)。这很重要,因为远程使用者们并不被允许 push 一个有效的分支(如果你正在 `dev` 分支工作然后突然有人把一些变更 push 到你的工作分支,你会有怎么样的感受?)。因为一个空的仓库可以没有有效的分支,这不会成为一个问题。
你可以把这个仓库放到任何你想放的地方,只要你想要放开权限给用户和用户组,让他们可以在仓库下工作。千万不要保存目录到例如一个用户的 home 目录下,因为有严格的权限控制。保存到一个常规的共享地址,例如 `/opt` 或者 `/usr/local/share`
以 root 身份创建一个空的仓库:
```
# git init --bare /opt/jupiter.git
# chown -R gituser:gituser /opt/jupiter.git
# chmod -R 770 /opt/jupiter.git
```
现在任何一个用户,只要他被认证为 gituser 或者在 gituser 组中,就可以从 jupiter.git 库中读取或者写入。在本地机器尝试以下操作。
```
$ git clone gituser@example.com:/opt/jupiter.git jupiter.clone
Cloning into 'jupiter.clone'...
Warning: you appear to have cloned an empty repository.
```
谨记:开发者们一定要把他们的 SSH 公钥加入到 gituser 用户下的 `authorized_keys` 文件里,或者说,如果他们有服务器上的用户(如果你给了他们用户),那么他们的用户必须属于 gituser 用户组。
### Git 钩子
将自己的 Git 服务器跑起来,很赞的一件事就是可以使用 Git 钩子。支持 Git 的设备有时提供一个类钩子接口,但是并没有给你真正的 Git 钩子来访问文件系统。Git 钩子是一个脚本,它将在一个 Git 过程的某些点运行;当一个仓库即将接收一个 commit或者接受一个 commit 之后,或者即将接收一次 push或者一次 push 之后等等
这是一个简单的系统:任何放在 `.git/hooks` 目录下的脚本,使用标准的命名体系,就可按设计好的时间运行。一个脚本是否应该被运行取决于它的名字; pre-push 脚本在 push 之前运行post-received 脚本在 push 之后运行post-receive 脚本在接受 commit 之后运行等等。
脚本可以用任何语言写;如果在你的系统上有可以执行的脚本语言,例如输出 hello world ,那么你就用这个语言来写 Git 钩子脚本。Git 默认会给出一些例子,但是并不能用。
想要动手试一个?这很简单。如果你没有现成的 Git 仓库,首先创建一个 Git 仓库:
```
$ mkdir jupiter
$ cd jupiter
$ git init .
```
然后写一个功能为输出 “hello world” 的 Git 钩子。因为我使用 tsch 作为传统系统的长期支持 shell所以我仍然用它作为我的脚本语言你可以自由的使用自己喜欢的语言BashPythonRubyPerlRustSwiftGo
```
$ echo "#\!/bin/tcsh" > .git/hooks/post-commit
$ echo "echo 'POST-COMMIT SCRIPT TRIGGERED'" >> \
~/jupiter/.git/hooks/post-commit
$ chmod +x ~/jupiter/.git/hooks/post-commit
```
现在测试它的输出:
```
$ echo "hello world" > foo.txt
$ git add foo.txt
$ git commit -m 'first commit'
! POST-COMMIT SCRIPT TRIGGERED
[master (root-commit) c8678e0] first commit
1 file changed, 1 insertion(+)
create mode 100644 foo.txt
```
然后你已经实现了:你的第一个有功能的 Git 钩子
### 有名的 push-to-web 钩子
Git 钩子最流行的用法就是自动 push 更改的代码到一个正在使用中的网络服务器目录下。这是摆脱 FTP 的很好的方式,对于正在使用的产品保留完整的版本控制,自动整合发布的内容
如果操作正确,在一直以来的网站发布维护中 Git 会完成的很好而且在某种程度上很精准。Git 真的好棒。我不知道谁最初想到这个主意,但是我第一次听到它是从 Emacs 和 Git 方面的专家IBM 的 Bill von Hagen。他的文章包含一系列明确的介绍[Git 改变了分布式网页开发的游戏规则][1]。
### Git 变量
每一个 Git 钩子都有一系列不同的变量对应触发钩子的不同 Git 行为。你需不需要这些变量,主要取决于你写的程序。如果你需要一个当某人 push 代码时候的通用邮件通知,那么你就不需要特殊化,并且甚至也不需要编写额外的脚本,因为已经有现成的适合你的脚本。如果你想在邮件里查看 commit 信息和 commit 的作者,那么你的脚本就会变得相对棘手些。
Git 钩子并不是被用户直接执行所以要弄清楚如何收集可能会误解的重要信息。事实上Git 钩子脚本就像其他的脚本一样,像 BASH, Python, C++ 等等,从标准输入读取参数。不同的是,我们不会给它提供这个输入,所以,你在使用的时候,需要知道可能的输入参数。
在写 Git 钩子之前,看一下 Git 在你的项目目录下 `.git/hooks` 目录中提供的一些例子。举个例子,在这个 `pre-push.sample` 文件里,注释部分说明了如下内容:
```
# $1 -- 即将 push 的远方仓库的名字
# $2 -- 即将 push 的远方仓库的 URL
# 如果 push 的时候,并没有一个命名的远方仓库,那么这两个参数将会一样。
#
# 对于这个表单的标准输入,
# 参数通过行的形式输入
# <local ref> <local sha1> <remote ref> <remote sha1>
```
并不是所有的例子都是这么清晰,而且关于钩子获取变量的文档依旧缺乏(除非你去读 Git 的源码)。但是,如果你有疑问,你可以从[其他用户的尝试中][2]学习,或者你只是写一些基本的脚本,比如 `echo $1, $2, $3` 等等。
### 分支检测示例
我发现,对于生产环境来说有一个共同的需求,就是需要一个只有在特定分支被修改之后,才会触发事件的钩子。以下就是如何跟踪分支的示例。
首先Git 钩子本身是不受版本控制的。 Git 并不会跟踪他自己的钩子,因为对于钩子来说,他是 Git 的一部分而不是你仓库的一部分。所以Git 钩子可以监控你的 Git 服务器上的 Git 仓库的 commit 记录和 push 记录,而不是你本地仓库的一部分。
我们来写一个 post-receive也就是说在 commit 被接受之后触发)钩子。第一步就是需要确定分支名:
```
#!/bin/tcsh
foreach arg ( $< )
set argv = ( $arg )
set refname = $1
end
```
这个 for 循环用来读入第一个参数 `arg($1)` 然后循环用第二个参数 `($2)` 去重写,然后用第三个参数 `($3)` 。在 Bash 中有一个更好的方法,使用 read 命令,并且把值放入数组里。但是,这里是 tcsh并且变量的顺序可以预测的所以这个方法也是可行的。
当我们有了 commit 记录的 refname我们就能使用 Git 去找到这个分支的人类能读的名字:
```
set branch = `git rev-parse --symbolic --abbrev-ref $refname`
echo $branch #DEBUG
```
然后把这个分支名和我们想要触发的事件的分支名关键字进行比较。
```
if ( "$branch" == "master" ) then
echo "Branch detected: master"
git \
--work-tree=/path/to/where/you/want/to/copy/stuff/to \
checkout -f $branch || echo "master fail"
else if ( "$branch" == "dev" ) then
echo "Branch detected: dev"
Git \
--work-tree=/path/to/where/you/want/to/copy/stuff/to \
checkout -f $branch || echo "dev fail"
else
echo "Your push was successful."
echo "Private branch detected. No action triggered."
endif
```
给这个脚本分配可执行权限:
```
$ chmod +x ~/jupiter/.git/hooks/post-receive
```
现在,当一个用户在服务器的 master 分支 commit 代码这个代码就会被复制到一个生产环境的目录dev 分支的一个 commit 记录也会被复制到其他地方,其他分支将不会触发这些操作。
同时,创造一个 pre-commit 脚本也很简单。比如,判断一个用户是否在他们不该 push 的分支上 push 代码,或者对 commit 信息进行解析等等。
Git 钩子也可以变得复杂,而且他们因为 Git 的工作流的抽象层次不同而变得难以理解,但是他们确实是一个强大的系统,让你能够在你的 Git 基础设施上针对所有的行为进行对应的操作。如果你是一个 Git 重度用户,或者一个全职 Git 管理员,那么 Git 钩子是值得学习的。
在我们这个系列之后和最后的文章,我们将会学习如何使用 Git 来管理非文本的二进制数据,比如音频和图片。
--------------------------------------------------------------------------------
via: https://opensource.com/life/16/8/how-construct-your-own-git-server-part-6
作者:[Seth Kenlon][a]
译者:[maywanting](https://github.com/maywanting)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/seth
[1]: http://www.ibm.com/developerworks/library/wa-git/
[2]: https://www.analysisandsolutions.com/code/git-hooks-summary-cheat-sheet.htm

View File

@ -1,58 +0,0 @@
在 WordPress 下如何通过 Markdown 来提高工作效率
====
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/markdown-wordpress-featured-2.jpg)
Markdown 是一种简单的标记语言,旨在帮助你花费更小的代价来格式化纯文本文档。在 WordPress 下你可以使用 HTML 或者 Visual Editor 来格式化你的文档,但是使用 markdown 可以让格式化文档变得更加容易而且你随时可以导出成很多种格式包括但不限于HTML。
WordPress 没有进行本地 markdown 的支持,但是,如果你希望的话,在你的网站上有多种插件可以添加这种功能。
在这个教程中,我将会演示如何使用流行的 WP-Markdown 插件来添加 WordPress 网站对于 markdown 的支持。
### 安装
通过选择导航栏中的 “Plugins -> Add New”然后在提供的搜索框中输入 “[wp-markdown][1]” 就可以直接安装。插件应该会出现在列表中的第一个。单击 “Install Now” 进行安装。
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/08/markdown-wordpress-install-plugin-1.png)
### 配置
一旦你已经安装了这个插件并且激活它之后,菜单中导航到 “Settings -> Writing” 并向下滚动,直到 markdown 选项。
你可以启用文章、页面和评论中对于 markdown 的支持。如果你只是学习 markdown 的语法,那么你也可以在文章编辑器或者评论地方启用一个帮助栏。
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/09/markdown-wordpress-configuration.png)
如果在你的博客文章中也包括代码片段的话,那么启用 “Prettify syntax highlighter” 将会让你的代码片段自动语法高亮。
一旦对于你的选择感觉满意的话,那么就单击 “Save Changes” 来保存你的设置吧。
### 使用 Markdown 来写你的文章
一旦你在自己网站中启用了 markdown 的支持,你就可以立马开始使用了。
通过 “Posts -> Add New” 创建一篇新的文章。你将会注意到默认的视觉和纯文本编辑器已经被 markdown 编辑器所替代。
如果你在配置选项中没有启用 markdown 的帮助栏,你将不会看到 markdown 格式化后的实时预览。然而,只要你的语法是正确的,当你保存或者发布文章的时候,你的 markdown 就会转换成正确的 HTML。
然而,如果你是 markdown 的初学者的话,实时预览这一特征对你会很重要,只需要简单的回到刚才的设置中启用帮助栏选项,你就可以在你的文章底部得到一片不错的实时预览的区域。另外,你也可以在顶部看到很多按钮,它们将帮助你在文章中快速的插入 markdown 元素。如果人们使用它的话,这将是一个潜在的惊人的设置。你可以调整单个应用程序通知的优先级。这将让你自己选择在通知栏看到的东西。
![](https://maketecheasier-2d0f.kxcdn.com/assets/uploads/2016/08/markdown-wordpress-create-post.png)
### 结语
正如你所看到的那样,在 WordPress 网站上添加 markdown 支持是真的容易,你将只需要花费几分钟的时间就可以了。如果对于 markdown 你全然不知的话,或许你也可以查看我们的 [markdown 备忘录][2],它将对于 markdown 语法提供一个全面的参考。
--------------------------------------------------------------------------------
via: https://www.maketecheasier.com/use-markdown-in-wordpress/?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+maketecheasier
作者:[Ayo Isaiah][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://www.maketecheasier.com/author/ayoisaiah/
[1]: https://wordpress.org/plugins/wp-markdown/
[2]: https://www.maketecheasier.com/productive-with-markdown-cheatsheet/

View File

@ -1,54 +0,0 @@
TaskwarriorLinux下一个很棒的命令行TODO工具
====
Taskwarrior是Ubuntu/Linux下一个简单直接的基于命令行的TODO工具。这个开源软件是我曾用过的最简单的[基于命令行的工具][4]之一。Taskwarrior帮助你更好地组织你自己而不用安装笨重的新工具这有时破坏了TODO工具的目的。
![](https://2.bp.blogspot.com/-pQnRlOUNIxk/V9cuc3ytsBI/AAAAAAAAKHs/yYxyiAk4PwMIE0HTxlrm6arWOAPcBRRywCLcB/s1600/taskwarrior-todo-app.png)
### Taskwarrior一个基于简单的基于命令行帮助完成任务的TODO工具
Taskwarrior是一个开源、跨平台、基于命令行的TODO工具它帮你在终端中管理你的to-do列表。这个工具让你可以轻松地添加任务、展示列表、移除任务。同时在你的默认仓库中就由不用安装新的PPA。在 Ubuntu 16.04 LTS或者相似的发行版中。在终端中按照如下步骤安装Taskwarrior。
```
sudo apt-get install task
```
一个简单的使用如下:
```
$ task add Read a book
Created task 1.
$ task add priority:H Pay the bills
Created task 2.
```
我使用上面截图中的同样一个例子。是的你可以设置优先级H、L或者M。并且你可以使用task或者task next命令来查看你最新创建的to-do列表。比如
```
$ task next
ID Age P Description Urg
-- --- - -------------------------------- ----
2 10s H Pay the bills 6
1 20s Read a book 0
```
完成之后你可以使用task 1 done或者task 2 done来清除列表。[可以在这里][1]找到更加全面的命令和使用案例。同样Taskwarrior是跨平台的这意味着不管怎样你都可以找到一个[满足你需求][2]的版本。如果你需要的话,这里甚至有[一个安卓版][3]。用得开心!
--------------------------------------------------------------------------------
via: http://www.techdrivein.com/2016/09/taskwarrior-command-line-todo-app-linux.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+techdrivein+%28Tech+Drive-in%29
作者:[Manuel Jose ][a]
译者:[geekpi](https://github.com/geekpi)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: http://www.techdrivein.com/2016/09/taskwarrior-command-line-todo-app-linux.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+techdrivein+%28Tech+Drive-in%29
[1]: https://taskwarrior.org/docs/
[2]: https://taskwarrior.org/download/
[3]: https://taskwarrior.org/news/news.20160225.html
[4]: http://www.techdrivein.com/search/label/Terminal