Unicode 和 UTF-8 是什么关系?

绝大多数程序员都听说过 Unicode 和 UTF-8,但是清楚它们之间关系的人就不多了,关于这个问题,与其苍白的陈述它们的概念,不如举例子说明来得自然。

Unicode 和 UTF-8 是什么关系?
Unicode 和 UTF-8 是什么关系?

我前些天碰到一个需求:随机生成几个汉字。原本我便对编码之类的问题发怵,所以完全搞不清楚状况,无奈之下我便上网搜索了一个 PHP 版本的实现:

不过代码里的「19968」和「40869」是什么玩意?这又牵扯到 Unicode code points,为了更好的说明问题,我们需要把如上十进制转换成十六进制:

shell> php -r 'echo dechex(19968);'
4e00

shell> php -r 'echo dechex(40908);'
9fcc

在 Unicode 官方网站,我们能查到 Unihan Grid Index,其中 CJK Unified Ideographs 部分包含了大部分的汉字,其 code points 恰恰是从 U+4E00 到 U+9FCC!

单单上面一个例子还不足以说明问题,下面我们挑选一个「」字深入说明一下:

Unicode 和 UTF-8 是什么关系?
Unicode 和 UTF-8 是什么关系?

Unicode

因为我们编码是 UTF-8,所以就先看看「博」字的 UTF-8 编码是什么:

代码看上去有点冗长,实际上利用 pack/unpack 函数可以很简单的实现类似的逻辑:

shell> php -r 'var_dump(unpack("H6", "博"));'
array(1) {
  ["codes"]=>
  string(6) "e58d9a"
}

于是乎「博」字的 UTF-8 编码是「e58d9a」,再看怎么得到 unicode code point:

shell> php -r 'echo base_convert("e58d9a", 16, 2);'
11100101 10001101 10011010

如上拿到了「博」字的二进制表示,实际上其 unicode code point 就隐藏在这里。通常汉字用 UTF-8 表示时是三个字节,格式为「1110XXXX 10XXXXXX 10XXXXXX」,除掉标志位,把剩余对应位置上的数据抽取出来连接在一起,就得到了 Unicode code point,也就是「0101 001101 011010」,剩下的就简单了,把它从二进制转换成十六进制即可:

shell> php -r 'echo base_convert("0101001101011010", 2, 16);'
535a

需要说明的是,如果你仅仅看「博」字,会发现其 Unicode code point 和 UTF-16 是一样的,很容易据此认为它们是等同的概念,实际上这个结论仅仅在双字节(UCS-2)时才是成立的,一旦大于两个字节,就不成立了,有兴趣的可以参考相应的例子

到底 Unicode 和 UTF-8 是什么关系?一句话:Unicode 是字符集;UTF-8 是编码

LINUX 101: 让你的 SHELL 更强大

在我们的关于 shell 基础的指导下, 得到一个更灵活,功能更强大且多彩的命令行界面

为何要这样做?

  • 使得在 shell 提示符下过得更轻松,高效
  • 在失去连接后恢复先前的会话
  • Stop pushing around that fiddly rodent!
LINUX 101: 让你的 SHELL 更强大
LINUX 101: 让你的 SHELL 更强大

这是我的命令行提示符的设置。对于这个小的终端窗口来说,这或许有些长。但你可以根据你的喜好来调整它。

作为一个 Linux 用户, 你可能熟悉 shell (又名为命令行)。 或许你需要时不时的打开终端来完成那些不能在 GUI 下处理的必要任务,抑或是因为你处在一个将窗口铺满桌面的环境中,而 shell 是你与你的 linux 机器交互的主要方式。

在上面那些情况下,你可能正在使用你所使用的发行版本自带的 Bash 配置。 尽管对于大多数的任务而言,它足够好了,但它可以更加强大。 在本教程中,我们将向你展示如何使得你的 shell 提供更多有用信息、更加实用且更适合工作。 我们将对提示符进行自定义,让它比默认情况下提供更好的反馈,并向你展示如何使用炫酷的 tmux 工具来管理会话并同时运行多个程序。 并且,为了让眼睛舒服一点,我们还将关注配色方案。那么,进击吧,少女!

让提示符更美妙

大多数的发行版本配置有一个非常简单的提示符,它们大多向你展示了一些基本信息, 但提示符可以为你提供更多的内容。例如,在 Debian 7 下,默认的提示符是这样的:

mike@somebox:~$

上面的提示符展示出了用户、主机名、当前目录和账户类型符号(假如你切换到 root 账户, $ 会变为 #)。 那这些信息是在哪里存储的呢? 答案是:在 PS1 环境变量中。 假如你键入 echo $PS1, 你将会在这个命令的输出字符串的最后有如下的字符:

u@h:w$

这看起来有一些丑陋,并在瞥见它的第一眼时,你可能会开始尖叫,认为它是令人恐惧的正则表达式,但我们不打算用这些复杂的字符来煎熬我们的大脑。这不是正则表达式,这里的斜杠是转义序列,它告诉提示符进行一些特别的处理。 例如,上面的 u 部分,告诉提示符展示用户名, 而 w 则展示工作路径.

下面是一些你可以在提示符中用到的字符的列表:

  • d 当前的日期
  • h 主机名
  • n 代表换行的字符
  • A 当前的时间 (HH:MM)
  • u 当前的用户
  • w (小写) 整个工作路径的全称
  • W (大写) 工作路径的简短名称
  • $ 一个提示符号,对于 root 用户为 # 号
  • ! 当前命令在 shell 历史记录中的序号

下面解释 wW 选项的区别: 对于前者,你将看到你所在的工作路径的完整地址,(例如 /usr/local/bin),而对于后者, 它则只显示 bin 这一部分。

现在,我们该怎样改变提示符呢? 你需要更改 PS1 环境变量的内容,试试下面这个:

export PS1="I am u and it is A $"

现在,你的提示符将会像下面这样:

I am mike and it is 11:26 $

从这个例子出发,你就可以按照你的想法来试验一下上面列出的其他转义序列。 但等等 – 当你登出后,你的这些努力都将消失,因为在你每次打开终端时,PS1 环境变量的值都会被重置。解决这个问题的最简单方式是打开 .bashrc 配置文件(在你的家目录下) 并在这个文件的最下方添加上完整的 export 命令。在每次你启动一个新的 shell 会话时,这个 .bashrc 会被 Bash 读取, 所以你的加强的提示符就可以一直出现。你还可以使用额外的颜色来装扮提示符。刚开始,这将有点棘手,因为你必须使用一些相当奇怪的转义序列,但结果是非常漂亮的。 将下面的字符添加到你的 PS1字符串中的某个位置,最终这将把文本变为红色:

[e[31m]

你可以将这里的 31 更改为其他的数字来获得不同的颜色:

  • 30 黑色
  • 32 绿色
  • 33 黄色
  • 34 蓝色
  • 35 洋红色
  • 36 青色
  • 37 白色

所以,让我们使用先前看到的转义序列和颜色来创造一个提示符,以此来结束这一小节的内容。深吸一口气,弯曲你的手指,然后键入下面这只“野兽”:

export PS1="(!) [e[31m] [A] [e[32m]u@h [e[34m]w [e[30m]$"

上面的命令提供了一个 Bash 命令历史序号、当前的时间、彩色的用户或主机名组合、以及工作路径。假如你“野心勃勃”,利用一些惊人的组合,你还可以更改提示符的背景色和前景色。非常有用的 Arch wiki 有一个关于颜色代码的完整列表:http://tinyurl.com/3gvz4ec

Shell 精要

假如你是一个彻底的 Linux 新手并第一次阅读这份杂志,或许你会发觉阅读这些教程有些吃力。 所以这里有一些基础知识来让你熟悉一些 shell。 通常在你的菜单中, shell 指的是 Terminal、 XTerm 或 Konsole, 当你启动它后, 最为实用的命令有这些:

ls (列出文件名); cp one.txt two.txt (复制文件); rm file.txt (移除文件); mv old.txt new.txt (移动或重命名文件);

cd /some/directory (改变目录); cd .. (回到上级目录); ./program (在当前目录下运行一个程序); ls > list.txt (重定向输出到一个文件)。

几乎每个命令都有一个手册页用来解释其选项(例如 man ls – 按 Q 来退出)。在那里,你可以知晓命令的选项,这样你就知道 ls -la 展示一个详细的列表,其中也列出了隐藏文件, 并且在键入一个文件或目录的名字的一部分后, 可以使用 Tab 键来自动补全。

Tmux: 针对 shell 的窗口管理器

在文本模式的环境中使用一个窗口管理器 – 这听起来有点不可思议, 是吧? 然而,你应该记得当 Web 浏览器第一次实现分页浏览的时候吧? 在当时, 这是在可用性上的一个重大进步,它减少了桌面任务栏的杂乱无章和繁多的窗口列表。 对于你的浏览器来说,你只需要一个按钮便可以在浏览器中切换到你打开的每个单独网站, 而不是针对每个网站都有一个任务栏或导航图标。 这个功能非常有意义。

若有时你同时运行着几个虚拟终端,你便会遇到相似的情况; 在这些终端之间跳转,或每次在任务栏或窗口列表中找到你所需要的那一个终端,都可能会让你觉得麻烦。 拥有一个文本模式的窗口管理器不仅可以让你像在同一个终端窗口中运行多个 shell 会话,而且你甚至还可以将这些窗口排列在一起。

另外,这样还有另一个好处:可以将这些窗口进行分离和重新连接。想要看看这是如何运行的最好方式是自己尝试一下。在一个终端窗口中,输入 screen (在大多数发行版本中,它已经默认安装了或者可以在软件包仓库中找到)。 某些欢迎的文字将会出现 – 只需敲击 Enter 键这些文字就会消失。 现在运行一个交互式的文本模式的程序,例如 nano, 并关闭这个终端窗口。

在一个正常的 shell 对话中, 关闭窗口将会终止所有在该终端中运行的进程 – 所以刚才的 Nano 编辑对话也就被终止了, 但对于 screen 来说,并不是这样的。打开一个新的终端并输入如下命令:

screen -r

瞧,你刚开打开的 Nano 会话又回来了!

当刚才你运行 screen 时, 它会创建了一个新的独立的 shell 会话, 它不与某个特定的终端窗口绑定在一起,所以可以在后面被分离并重新连接(即 -r 选项)。

当你正使用 SSH 去连接另一台机器并做着某些工作时, 但并不想因为一个脆弱的连接而影响你的进度,这个方法尤其有用。假如你在一个 screen 会话中做着某些工作,并且你的连接突然中断了(或者你的笔记本没电了,又或者你的电脑报废了——不是这么悲催吧),你只需重新连接或给电脑充电或重新买一台电脑,接着运行 screen -r 来重新连接到远程的电脑,并在刚才掉线的地方接着开始。

现在,我们都一直在讨论 GNU 的 screen,但这个小节的标题提到的是 tmux。 实质上, tmux (terminal multiplexer) 就像是 screen 的一个进阶版本,带有许多有用的额外功能,所以现在我们开始关注 tmux。 某些发行版本默认包含了 tmux; 在其他的发行版本上,通常只需要一个 apt-get、 yum installpacman -S 命令便可以安装它。

一旦你安装了它过后,键入 tmux 来启动它。接着你将注意到,在终端窗口的底部有一条绿色的信息栏,它非常像传统的窗口管理器中的任务栏: 上面显示着一个运行着的程序的列表、机器的主机名、当前时间和日期。 现在运行一个程序,同样以 Nano 为例, 敲击 Ctrl+B 后接着按 C 键, 这将在 tmux 会话中创建一个新的窗口,你便可以在终端的底部的任务栏中看到如下的信息:

0:nano- 1:bash*

每一个窗口都有一个数字,当前呈现的程序被一个星号所标记。 Ctrl+B 是与 tmux 交互的标准方式, 所以若你敲击这个按键组合并带上一个窗口序号, 那么就会切换到对应的那个窗口。你也可以使用 Ctrl+B 再加上 N 或 P 来分别切换到下一个或上一个窗口 – 或者使用 Ctrl+B 加上 L 来在最近使用的两个窗口之间来进行切换(有点类似于桌面中的经典的 Alt+Tab 组合键的效果)。 若需要知道窗口列表,使用 Ctrl+B 再加上 W。

目前为止,一切都还好:现在你可以在一个单独的终端窗口中运行多个程序,避免混乱(尤其是当你经常与同一个远程主机保持多个 SSH 连接时)。 当想同时看两个程序又该怎么办呢?

针对这种情况, 可以使用 tmux 中的窗格。 敲击 Ctrl+B 再加上 % , 则当前窗口将分为两个部分:一个在左一个在右。你可以使用 Ctrl+B 再加上 O 来在这两个部分之间切换。 这尤其在你想同时看两个东西时非常实用, – 例如一个窗格看指导手册,另一个窗格里用编辑器看一个配置文件。

有时,你想对一个单独的窗格进行缩放,而这需要一定的技巧。 首先你需要敲击 Ctrl+B 再加上一个 :(冒号),这将使得位于底部的 tmux 栏变为深橙色。 现在,你进入了命令模式,在这里你可以输入命令来操作 tmux。 输入 resize-pane -R 来使当前窗格向右移动一个字符的间距, 或使用 -L 来向左移动。 对于一个简单的操作,这些命令似乎有些长,但请注意,在 tmux 的命令模式(前面提到的一个分号开始的模式)下,可以使用 Tab 键来补全命令。 另外需要提及的是, tmux 同样也有一个命令历史记录,所以若你想重复刚才的缩放操作,可以先敲击 Ctrl+B 再跟上一个分号,并使用向上的箭头来取回刚才输入的命令。

最后,让我们看一下分离和重新连接 – 即我们刚才介绍的 screen 的特色功能。 在 tmux 中,敲击 Ctrl+B 再加上 D 来从当前的终端窗口中分离当前的 tmux 会话。这使得这个会话的一切工作都在后台中运行、使用 tmux a 可以再重新连接到刚才的会话。但若你同时有多个 tmux 会话在运行时,又该怎么办呢? 我们可以使用下面的命令来列出它们:

tmux ls

这个命令将为每个会话分配一个序号; 假如你想重新连接到会话 1, 可以使用 tmux a -t 1. tmux 是可以高度定制的,你可以自定义按键绑定并更改配色方案, 所以一旦你适应了它的主要功能,请钻研指导手册以了解更多的内容。

LINUX 101: 让你的 SHELL 更强大
LINUX 101: 让你的 SHELL 更强大

上图中, tmux 开启了两个窗格: 左边是 Vim 正在编辑一个配置文件,而右边则展示着指导手册页。

Zsh: 另一个 shell

选择是好的,但标准同样重要。 你要知道几乎每个主流的 Linux 发行版本都默认使用 Bash shell – 尽管还存在其他的 shell。 Bash 为你提供了一个 shell 能够给你提供的几乎任何功能,包括命令历史记录,文件名补全和许多脚本编程的能力。它成熟、可靠并文档丰富 – 但它不是你唯一的选择。

许多高级用户热衷于 Zsh, 即 Z shell。 这是 Bash 的一个替代品并提供了 Bash 的几乎所有功能,另外还提供了一些额外的功能。 例如, 在 Zsh 中,你输入 ls ,并敲击 Tab 键可以得到 ls 可用的各种不同选项的一个大致描述。 而不需要再打开 man page 了!

Zsh 还支持其他强大的自动补全功能: 例如,输入 cd /u/lo/bi 再敲击 Tab 键, 则完整的路径名 /usr/local/bin 就会出现(这里假设没有其他的路径包含 u, lobi 等字符)。 或者只输入 cd 再跟上 Tab 键,则你将看到着色后的路径名的列表 – 这比 Bash 给出的简单的结果好看得多。

Zsh 在大多数的主要发行版本上都可以得到了; 安装它后并输入 zsh 便可启动它。 要将你的默认 shell 从 Bash 改为 Zsh, 可以使用 chsh 命令。 若需了解更多的信息,请访问 www.zsh.org

“未来”的终端

你或许会好奇为什么包含你的命令行提示符的应用被叫做终端。 这需要追溯到 Unix 的早期, 那时人们一般工作在一个多用户的机器上,这个巨大的电脑主机将占据一座建筑中的一个房间, 人们通过某些线路,使用屏幕和键盘来连接到这个主机, 这些终端机通常被称为“哑终端”, 因为它们不能靠自己做任何重要的执行任务 – 它们只展示通过线路从主机传来的信息,并输送回从键盘的敲击中得到的输入信息。

今天,我们在自己的机器上执行几乎所有的实际操作,所以我们的电脑不是传统意义下的终端,这就是为什么诸如 XTerm、 Gnome Terminal、 Konsole 等程序被称为“终端模拟器” 的原因 – 他们提供了同昔日的物理终端一样的功能。事实上,在许多方面它们并没有改变多少。诚然,现在我们有了反锯齿字体,更好的颜色和点击网址的能力,但总的来说,几十年来我们一直以同样的方式在工作。

所以某些程序员正尝试改变这个状况。 Terminology (http://tinyurl.com/osopjv9), 它来自于超级时髦的 Enlightenment 窗口管理器背后的团队,旨在让终端步入到 21 世纪,例如带有在线媒体显示功能。你可以在一个充满图片的目录里输入 ls 命令,便可以看到它们的缩略图,或甚至可以直接在你的终端里播放视频。 这使得一个终端有点类似于一个文件管理器,意味着你可以快速地检查媒体文件的内容而不必用另一个应用来打开它们。

接着还有 Xiki (www.xiki.org),它自身的描述为“命令的革新”。它就像是一个传统的 shell、一个 GUI 和一个 wiki 之间的过渡;你可以在任何地方输入命令,并在后面将它们的输出存储为笔记以作为参考,并可以创建非常强大的自定义命令。用几句话是很能描述它的,所以作者们已经创作了一个视频来展示它的潜力是多么的巨大(请看 Xiki 网站的截屏视频部分)。

并且 Xiki 绝不是那种在几个月之内就消亡的昙花一现的项目,作者们成功地进行了一次 Kickstarter 众筹,在七月底已募集到超过 $84,000。 是的,你没有看错 – $84K 来支持一个终端模拟器。这可能是最不寻常的集资活动了,因为某些疯狂的家伙已经决定开始创办它们自己的 Linux 杂志 ……

下一代终端

许多命令行和基于文本的程序在功能上与它们的 GUI 程序是相同的,并且常常更加快速和高效。我们的推荐有: Irssi (IRC 客户端); Mutt (mail 客户端); rTorrent (BitTorrent); Ranger (文件管理器); htop (进程监视器)。 若给定在终端的限制下来进行 Web 浏览, Elinks 确实做的很好,并且对于阅读那些以文字为主的网站例如 Wikipedia 来说。它非常实用。

微调配色方案

在《Linux Voice》杂志社中,我们并不迷恋那些养眼的东西,但当你每天花费几个小时盯着屏幕看东西时,我们确实认识到美学的重要性。我们中的许多人都喜欢调整我们的桌面和窗口管理器来达到完美的效果,调整阴影效果、摆弄不同的配色方案,直到我们 100% 的满意(然后出于习惯,摆弄更多的东西)。

但我们倾向于忽视终端窗口,它理应也获得我们的喜爱,并且在 http://ciembor.github.io/4bit 你将看到一个极其棒的配色方案设计器,对于所有受欢迎的终端模拟器(XTerm, Gnome Terminal, Konsole 和 Xfce4 Terminal 等都是支持的应用。),它可以输出其设定。移动滑块直到你看到配色方案最佳, 然后点击位于该页面右上角的 得到方案 按钮。

相似的,假如你在一个文本编辑器,如 Vim 或 Emacs 上花费了很多的时间,使用一个精心设计的调色板也是非常值得的。 Solarized http://ethanschoonover.com/solarized 是一个卓越的方案,它不仅漂亮,而且因追求最大的可用性而设计,在其背后有着大量的研究和测试。


via: http://www.linuxvoice.com/linux-101-power-up-your-shell-8/

作者:Ben Everard 译者:FSSlc 校对:wxy

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

来源:https://linux.cn/article-5910-1.html

在 Linux 命令行中使用和执行 PHP 代码(一)

PHP是一个开源服务器端脚本语言,最初这三个字母代表的是“Personal Home Page”,而现在则代表的是“PHP:Hypertext Preprocessor”,它是个递归首字母缩写。它是一个跨平台脚本语言,深受C、C++和Java的影响。

在 Linux 命令行中使用和执行 PHP 代码(一)
在 Linux 命令行中使用和执行 PHP 代码(一)

在 Linux 命令行中运行 PHP 代码

PHP的语法和C、Java以及带有一些PHP特性的Perl变成语言中的语法十分相似,它当下大约正被2.6亿个网站所使用,当前最新的稳定版本是PHP版本5.6.10。

PHP是HTML的嵌入脚本,它便于开发人员快速写出动态生成的页面。PHP主要用于服务器端(而Javascript则用于客户端)以通过HTTP生成动态网页,然而,当你知道可以在Linux终端中不需要网页浏览器来执行PHP时,你或许会大为惊讶。

本文将阐述PHP脚本语言的命令行方面。

1. 在安装完PHP和Apache2后,我们需要安装PHP命令行解释器。

# apt-get install php5-cli          [Debian 及类似系统]
# yum install php-cli               [CentOS 及类似系统]

接下来我们通常要做的是,在/var/www/html(这是 Apache2 在大多数发行版中的工作目录)这个位置创建一个内容为 ,名为 infophp.php 的文件来测试(PHP是否安装正确),执行以下命令即可。

# echo '' > /var/www/html/infophp.php

然后,将浏览器访问 http://127.0.0.1/infophp.php ,这将会在网络浏览器中打开该文件。

在 Linux 命令行中使用和执行 PHP 代码(一)
在 Linux 命令行中使用和执行 PHP 代码(一)

检查PHP信息

不需要任何浏览器,在Linux终端中也可以获得相同的结果。在Linux命令行中执行/var/www/html/infophp.php,如:

# php -f /var/www/html/infophp.php
在 Linux 命令行中使用和执行 PHP 代码(一)
在 Linux 命令行中使用和执行 PHP 代码(一)

从命令行检查PHP信息

由于输出结果太大,我们可以通过管道将上述输出结果输送给 less 命令,这样就可以一次输出一屏了,命令如下:

# php -f /var/www/html/infophp.php | less
在 Linux 命令行中使用和执行 PHP 代码(一)
在 Linux 命令行中使用和执行 PHP 代码(一)

检查所有PHP信息

这里,‘-f‘选项解析并执行命令后跟随的文件。

2. 我们可以直接在Linux命令行使用phpinfo()这个十分有价值的调试工具而不需要从文件来调用,只需执行以下命令:

# php -r 'phpinfo();'
在 Linux 命令行中使用和执行 PHP 代码(一)
在 Linux 命令行中使用和执行 PHP 代码(一)

PHP调试工具

这里,‘-r‘ 选项会让PHP代码在Linux终端中不带<>标记直接执行。

3. 以交互模式运行PHP并做一些数学运算。这里,‘-a‘ 选项用于以交互模式运行PHP。

# php -a

Interactive shell

php > echo 2+3;
5
php > echo 9-6;
3
php > echo 5*4;
20
php > echo 12/3;
4
php > echo 12/5;
2.4
php > echo 2+3-1;
4
php > echo 2+3-1*3;
2
php > exit

输入 ‘exit‘ 或者按下 ‘ctrl+c‘ 来关闭PHP交互模式。

在 Linux 命令行中使用和执行 PHP 代码(一)
在 Linux 命令行中使用和执行 PHP 代码(一)

启用PHP交互模式

4. 你可以仅仅将PHP脚本作为shell脚本来运行。首先,创建在你当前工作目录中创建一个PHP样例脚本。

# echo -e '#!/usr/bin/phpn' > phpscript.php

注意,我们在该PHP脚本的第一行使用#!/usr/bin/php,就像在shell脚本中那样(/bin/bash)。第一行的#!/usr/bin/php告诉Linux命令行用 PHP 解释器来解析该脚本文件。

其次,让该脚本可执行:

# chmod 755 phpscript.php

接着来运行它,

# ./phpscript.php

5. 你可以完全靠自己通过交互shell来创建简单函数,这你一定会被惊到了。下面是循序渐进的指南。

开启PHP交互模式。

# php -a

创建一个函数,将它命名为 addition。同时,声明两个变量 $a$b

php > function addition ($a, $b)

使用花括号来在其间为该函数定义规则。

php > {

定义规则。这里,该规则讲的是添加这两个变量。

php { echo $a + $b;

所有规则定义完毕,通过闭合花括号来封装规则。

php {}

测试函数,添加数字4和3,命令如下:

php > var_dump (addition(4,3));

样例输出

7NULL

你可以运行以下代码来执行该函数,你可以测试不同的值,你想来多少次都行。将里头的 a 和 b 替换成你自己的值。

php > var_dump (addition(a,b));

php > var_dump (addition(9,3.3));

样例输出

12.3NULL
在 Linux 命令行中使用和执行 PHP 代码(一)
在 Linux 命令行中使用和执行 PHP 代码(一)

创建PHP函数

你可以一直运行该函数,直至退出交互模式(ctrl+z)。同时,你也应该注意到了,上面输出结果中返回的数据类型为 NULL。这个问题可以通过要求 php 交互 shell用 return 代替 echo 返回结果来修复。

只需要在上面的函数的中 ‘echo‘ 声明用 ‘return‘ 来替换

替换

php { echo $a + $b;

php { return $a + $b;

剩下的东西和原理仍然一样。

这里是一个样例,在该样例的输出结果中返回了正确的数据类型。

在 Linux 命令行中使用和执行 PHP 代码(一)
在 Linux 命令行中使用和执行 PHP 代码(一)

PHP函数

永远都记住,用户定义的函数不会从一个shell会话保留到下一个shell会话,因此,一旦你退出交互shell,它就会丢失了。

希望你喜欢此次教程。保持连线,你会获得更多此类文章。保持关注,保持健康。请在下面的评论中为我们提供有价值的反馈。点赞并分享,帮助我们扩散。

还请阅读: 12个Linux终端中有用的的PHP命令行用法——第二部分


via: http://www.tecmint.com/run-php-codes-from-linux-commandline/

作者:Avishek Kumar 译者:GOLinux 校对:wxy

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

来源:https://linux.cn/article-5906-1.html

Linux:在Ubuntu 15.04中安装Ruby on Rails

本篇我们会学习如何用rbenv在Ubuntu 15.04中安装Ruby on Rails。我们选择Ubuntu作为操作系统是因为Ubuntu是Linux发行版中自带很多包和完整文档的操作系统,因此我认为这是正确的选择。如果你还没有安装最新的Ubuntu,你可以从下载iso文件开始。

安装 Ruby

我们要做的第一件事是更新Ubuntu包并且为Ruby安装一些依赖。

sudo apt-get update
sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev

有三种方法来安装Ruby:rbenv、rvm和从源码安装。每种都有各自的好处,但是近来开发者们更倾向使用rbenv而不是rvm和源码来安装。我们将安装最新的Ruby版本,2.2.2。

用rbenv来安装只有简单的两步。第一步安装rbenv,接着是ruby-build:

cd
git clone git://github.com/sstephenson/rbenv.git .rbenv
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL

git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL

git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash

rbenv install 2.2.2
rbenv global 2.2.2
ruby -v

我们需要安装Bundler,但是我们要在安装之前告诉rubygems不要为每个包安装本地文档。

echo "gem: --no-ri --no-rdoc" > ~/.gemrc
gem install bundler

配置 GIT

配置git之前,你要创建一个github账号,你可以注册一个github 账号。我们需要git作为版本控制系统,因此我们要设置它来匹配github账号。

用户的github账号来替换下面的NameEmail address

git config --global color.ui true
git config --global user.name "YOUR NAME"
git config --global user.email "YOUR@EMAIL.com"
ssh-keygen -t rsa -C "YOUR@EMAIL.com"

接下来用新生成的ssh key添加到github账号中。这样你需要复制下面命令的输出并粘贴在Github的设置页面里面

cat ~/.ssh/id_rsa.pub

如果你做完了,检查是否已经成功。

ssh -T git@github.com

你应该得到下面这样的信息。

Hi excid3! You've successfully authenticated, but GitHub does not provide shell access.

安装 Rails

我们需要安装像NodeJS这样的javascript运行时环境,因为近来Rails的依赖越来越多了。这样我们可以合并和压缩你的javascript,从而提供一个更快的生产环境。

我们需要添加PPA来安装nodeJS。

sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs

如果在更新时遇到了问题,你可以试试这个命令:

# Note the new setup script name for Node.js v0.12
curl -sL https://deb.nodesource.com/setup_0.12 | sudo bash -

# Then install with:
sudo apt-get install -y nodejs

下一步,用这个命令安装 rails:

gem install rails -v 4.2.1

因为我们正在使用rbenv,用下面的命令来让rails的执行程序可以使用。

rbenv rehash

要确保rails已经正确安装,你可以运行rails -v,显示如下:

rails -v
# Rails 4.2.1

如果你得到的是不同的结果可能是环境没有设置正确。

设置 MySQL

或许你已经熟悉MySQL了,你可以从Ubuntu的仓库中安装MySQL的客户端与服务端。你可以在安装时设置root用户密码。这个信息将来会进入你rails程序的database.yml文件中。用下面的命令来安装mysql。

sudo apt-get install mysql-server mysql-client libmysqlclient-dev

安装libmysqlclient-dev用于mysql2 gem的编译;在设置rails程序时,rails通过它来连接mysql。

最后一步

让我们尝试创建你的第一个rails程序:

# 使用 MySQL 数据库
rails new myapp -d mysql

# 进入到应用目录
cd myapp
# 创建数据库
rake db:create
rails server

访问http://localhost:3000来访问你的新网站。现在你的电脑上已经可以构建rails程序了。

Linux:在Ubuntu 15.04中安装Ruby on Rails
Linux:在Ubuntu 15.04中安装Ruby on Rails

如果你在创建数据库时遇到了“Access denied for user ‘root’@’localhost’ (Using password: NO)”这个错误信息,你需要更新你的config/database.yml文件来匹配数据库的用户名密码

# 编辑配置文件夹中的 database.yml
nano config/database.yml

接着填入MySql root用户的密码。

Linux:在Ubuntu 15.04中安装Ruby on Rails
Linux:在Ubuntu 15.04中安装Ruby on Rails

退出 (Ctrl+X)并保存。

总结

Rails是用Ruby写的, 也是随着rails一起使用的编程语言。在Ubuntu 15.04中Ruby on Rails可以用rbenv、 rvm和源码的方式来安装。本篇我们使用的是rbenv方式并用了MySQL作为数据库。有任何的问题或建议,请在评论栏指出。


via: http://linoxide.com/ubuntu-how-to/installing-ruby-rails-using-rbenv-ubuntu-15-04/

作者:Obet 译者:geekpi 校对:wxy

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

来源:https://linux.cn/article-5813-1.html

Linux:Node.js 命令行程序开发教程

一种编程语言是否易用,很大程度上,取决于开发命令行程序的能力。

Node.js 作为目前最热门的开发工具之一,怎样使用它开发命令行程序,是 Web 开发者应该掌握的技能。

Linux:Node.js 命令行程序开发教程
Linux:Node.js 命令行程序开发教程

最近,Npm的网志有一组系列文章,我觉得写得非常好。下面就是我在它的基础上扩展的教程,应该是目前最好的解决方案了。

一、可执行脚本

我们从最简单的讲起。

首先,使用 JavaScript 语言,写一个可执行脚本 hello 。

#!/usr/bin/env node
console.log('hello world');

然后,修改 hello 的权限。

$ chmod 755 hello

现在,hello 就可以执行了。

$ ./hello
hello world

如果想把 hello 前面的路径去除,可以将 hello 的路径加入环境变量 PATH。但是,另一种更好的做法,是在当前目录下新建 package.json ,写入下面的内容。

{
  "name": "hello",
  "bin": {
    "hello": "hello"
  }
}

然后执行 npm link 命令。

$ npm link

现在再执行 hello ,就不用输入路径了。

$ hello
hello world

二、命令行参数的原始写法

命令行参数可以用系统变量 process.argv 获取。

#!/usr/bin/env node
console.log('hello ', process.argv[2]);

执行时,直接在脚本文件后面,加上参数即可。

$ ./hello tom
hello tom

三、新建进程

脚本可以通过 child_process 模块新建子进程,从而执行 Unix 系统命令。

#!/usr/bin/env node
var name = process.argv[2];
var exec = require('child_process').exec;

var child = exec('echo hello ' + name, function(err, stdout, stderr) {
  if (err) throw err;
  console.log(stdout);
});

用法如下。

$ ./hello tom
hello tom

四、shelljs 模块

shelljs 模块重新包装了 child_process,调用系统命令更加方便。它需要安装后使用。

npm install --save shelljs

然后,改写脚本。

#!/usr/bin/env node
var name = process.argv[2];
var shell = require("shelljs");

shell.exec("echo hello " + name);

上面代码是 shelljs 的本地模式,即通过 exec 方法执行 shell 命令。此外还有全局模式,允许直接在脚本中写 shell 命令。

require('shelljs/global');

if (!which('git')) {
  echo('Sorry, this script requires git');
  exit(1);
}

mkdir('-p', 'out/Release');
cp('-R', 'stuff/*', 'out/Release');

cd('lib');
ls('*.js').forEach(function(file) {
  sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
  sed('-i', /.*REMOVE_THIS_LINE.*n/, '', file);
  sed('-i', /.*REPLACE_LINE_WITH_MACRO.*n/, cat('macro.js'), file);
});
cd('..');

if (exec('git commit -am "Auto-commit"').code !== 0) {
  echo('Error: Git commit failed');
  exit(1);
}

五、yargs 模块

shelljs 只解决了如何调用 shell 命令,而 yargs 模块能够解决如何处理命令行参数。它也需要安装。

$ npm install --save yargs

yargs 模块提供 argv 对象,用来读取命令行参数。请看改写后的 hello 。

#!/usr/bin/env node
var argv = require('yargs').argv;

console.log('hello ', argv.name);

使用时,下面两种用法都可以。

$ hello --name=tom
hello tom

$ hello --name tom
hello tom

如果将 argv.name 改成 argv.n,就可以使用一个字母的短参数形式了。

$ hello -n tom
hello tom

可以使用 alias 方法,指定 name 是 n 的别名。

#!/usr/bin/env node
var argv = require('yargs')
  .alias('n', 'name')
  .argv;

console.log('hello ', argv.n);

这样一来,短参数和长参数就都可以使用了。

$ hello -n tom
hello tom
$ hello --name tom
hello tom

argv 对象有一个下划线(_)属性,可以获取非连词线开头的参数。

#!/usr/bin/env node
var argv = require('yargs').argv;

console.log('hello ', argv.n);
console.log(argv._);

用法如下。

$ hello A -n tom B C
hello  tom
[ 'A', 'B', 'C' ]

六、命令行参数的配置

yargs 模块还提供3个方法,用来配置命令行参数。

  • demand:是否必选
  • default:默认值
  • describe:提示
#!/usr/bin/env node
var argv = require('yargs')
  .demand(['n'])
  .default({n: 'tom'})
  .describe({n: 'your name'})
  .argv;

console.log('hello ', argv.n);

上面代码指定 n 参数不可省略,默认值为 tom,并给出一行提示。

options 方法允许将所有这些配置写进一个对象。

#!/usr/bin/env node
var argv = require('yargs')
  .option('n', {
    alias : 'name',
    demand: true,
    default: 'tom',
    describe: 'your name',
    type: 'string'
  })
  .argv;

console.log('hello ', argv.n);

有时,某些参数不需要值,只起到一个开关作用,这时可以用 boolean 方法指定这些参数返回布尔值。

#!/usr/bin/env node
var argv = require('yargs')
  .boolean(['n'])
  .argv;

console.log('hello ', argv.n);

上面代码中,参数 n 总是返回一个布尔值,用法如下。

$ hello
hello  false
$ hello -n
hello  true
$ hello -n tom
hello  true

boolean 方法也可以作为属性,写入 option 对象。

#!/usr/bin/env node
var argv = require('yargs')
  .option('n', {
    boolean: true
  })
  .argv;

console.log('hello ', argv.n);

七、帮助信息

yargs 模块提供以下方法,生成帮助信息。

  • usage:用法格式
  • example:提供例子
  • help:显示帮助信息
  • epilog:出现在帮助信息的结尾
#!/usr/bin/env node
var argv = require('yargs')
  .option('f', {
    alias : 'name',
    demand: true,
    default: 'tom',
    describe: 'your name',
    type: 'string'
  })
  .usage('Usage: hello [options]')
  .example('hello -n tom', 'say hello to Tom')
  .help('h')
  .alias('h', 'help')
  .epilog('copyright 2015')
  .argv;

console.log('hello ', argv.n);

执行结果如下。

$ hello -h

Usage: hello [options]

Options:
  -f, --name  your name [string] [required] [default: "tom"]
  -h, --help  Show help [boolean]

Examples:
  hello -n tom  say hello to Tom

copyright 2015

八、子命令

yargs 模块还允许通过 command 方法,设置 Git 风格的子命令。

#!/usr/bin/env node
var argv = require('yargs')
  .command("morning", "good morning", function (yargs) {
    console.log("Good Morning");
  })
  .command("evening", "good evening", function (yargs) {
    console.log("Good Evening");
  })
  .argv;

console.log('hello ', argv.n);

用法如下。

$ hello morning -n tom
Good Morning
hello tom

可以将这个功能与 shellojs 模块结合起来。

#!/usr/bin/env node
require('shelljs/global');
var argv = require('yargs')
  .command("morning", "good morning", function (yargs) {
    echo("Good Morning");
  })
  .command("evening", "good evening", function (yargs) {
    echo("Good Evening");
  })
  .argv;

console.log('hello ', argv.n);

每个子命令往往有自己的参数,这时就需要在回调函数中单独指定。回调函数中,要先用 reset 方法重置 yargs 对象。

#!/usr/bin/env node
require('shelljs/global');
var argv = require('yargs')
  .command("morning", "good morning", function (yargs) {
    echo("Good Morning");
    var argv = yargs.reset()
      .option("m", {
        alias: "message",
        description: "provide any sentence"
      })
      .help("h")
      .alias("h", "help")
      .argv;

    echo(argv.m);
  })
  .argv;

用法如下。

$ hello morning -m "Are you hungry?"
Good Morning
Are you hungry?

九、其他事项

(1)返回值

根据 Unix 传统,程序执行成功返回 0,否则返回 1 。

if (err) {
  process.exit(1);
} else {
  process.exit(0);
}

(2)重定向

Unix 允许程序之间使用管道重定向数据。

$ ps aux | grep 'node'

脚本可以通过监听标准输入的data 事件,获取重定向的数据。

process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(data) {
  process.stdout.write(data);
});

下面是用法:

$ echo 'foo' | ./hello
hello foo

(3)系统信号

操作系统可以向执行中的进程发送信号,process 对象能够监听信号事件。

process.on('SIGINT', function () {
  console.log('Got a SIGINT');
  process.exit(0);
});

发送信号的方法如下。

$ kill -s SIGINT [process_id]

来源:http://www.ruanyifeng.com/blog/2015/05/command-line-with-node.html

Linux:经典的 Fork 炸弹解析

Linux:经典的 Fork 炸弹解析
Linux:经典的 Fork 炸弹解析

Jaromil在2002年设计了最为精简的一个Linux Fork炸弹,整个代码只有13个字符,在shell中运行后几秒后系统就会宕机:

:(){:|:&};:

这样看起来不是很好理解,我们可以更改下格式:

:()
{
	:|:&
};
:

更好理解一点的话就是这样:

bomb()
{
	bomb|bomb&
};
bomb

因为shell中函数可以省略

1
function

关键字,所以上面的十三个字符是功能是定义一个函数与调用这个函数,函数的名称为

1
:

,主要的核心代码是

1
:|:&

,可以看出这是一个函数本身的递归调用,通过

1
&

实现在后台开启新进程运行,通过管道实现进程呈几何形式增长,最后再通过

1
:

来调用函数引爆炸弹.因此,几秒钟系统就会因为处理不过来太多的进程而死机,解决的唯一办法就是重启。

Bomb一下

秉着不作不死的心态,我们也来运行一下,于是我将矛头指向云主机,,我使用了国内的一个2G内存的云主机,首先在本地开启两个终端,在一个终端连接云主机后运行炸弹,几秒后再尝试用另外一个终端登录,效果可以看下面Gif图:

Linux:经典的 Fork 炸弹解析
Linux:经典的 Fork 炸弹解析

看,运行一段时间后直接报出了

1
-bash: fork: Cannot allocate memory

,说明内存不足了。并且我在二号终端上尝试连接也没有任何反应。因为是虚拟的云主机,所以我只能通过主机服务商的后台来给主机断电重启。然后才能重新登录:

Linux:经典的 Fork 炸弹解析
Linux:经典的 Fork 炸弹解析

炸弹危害

Fork炸弹带来的后果就是耗尽服务器资源,使服务器不能正常的对外提供服务,也就是常说的DoS(Denial of Service)。与传统1v1、通过不断向服务器发送请求造成服务器崩溃不同,Fork炸弹有种坐山观虎斗,不费一兵一卒斩敌人于马下的感觉。更吓人的是这个函数是不需要root权限就可以运行的。看到网上有帖子说某些人将个性签名改为Fork炸弹,结果果真有好奇之人中枪,试想如果中枪的人是在公司服务器上运行的话,oh,!

预防方式

当然,Fork炸弹没有那么可怕,用其它语言也可以分分钟写出来一个,例如,python版:

import os
 	while True:
 	os.fork()

Fork炸弹的本质无非就是靠创建进程来抢占系统资源,在Linux中,我们可以通过

1
ulimit

命令来限制用户的某些行为,运行

1
ulimit -a

可以查看我们能做哪些限制:

ubuntu@10-10-57-151:~$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7782
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7782
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

可以看到,

1
-u

参数可以限制用户创建进程数,因此,我们可以使用

1
ulimit -u 20

来允许用户最多创建20个进程。这样就可以预防bomb炸弹。但这样是不彻底的,关闭终端后这个命令就失效了。我们可以通过修改

1
/etc/security/limits.conf

文件来进行更深层次的预防,在文件里添加如下一行(ubuntu需更换为你的用户名):

ubuntu - nproc 20

这样,退出后重新登录,就会发现最大进程数已经更改为20了,

Linux:经典的 Fork 炸弹解析
Linux:经典的 Fork 炸弹解析

这个时候我们再次运行炸弹就不会报内存不足了,而是提示

1
-bash: fork: retry: No child processes

,说明Linux限制了炸弹创建线程。

参考

http://en.wikipedia.org/wiki/Fork_bomb

来源:http://blog.saymagic.cn/2015/03/25/fork-bomb.html

Linux:命令行艺术

Linux:命令行艺术
Linux:命令行艺术

流畅地使用命令行是一个常被忽略的技能,或被认为是神秘的奥义。但是,它会以明显而微妙的方式改善你作为工程师的灵活度和生产力。这是我在 Linux 上工作时发现的有用的命令行使用小窍门和笔记的精粹。有些小窍门是很基础的,而有些是相当地特别、复杂、或者晦涩难懂。这篇文章不长,但是如果你可以使用并记得这里的所有内容,那么你就懂得很多了。

其中大部分最初出现Quora上,但是考虑到兴趣所在,似乎更应该放到 Github 上,这里的人比我更能提出改进建议。如果你看到一个错误,或者更好的某种东西,请提交问题或 PR!(当然,提交前请看看必读小节和已有的 PR/Issue。)

必读

范围:

  • 本文是针对初学者和专业人员的,选题目标是覆盖面广(全都很重要)、有针对性(大多数情况下都给出具体实例)而简洁(避免不必要内容以及你能在其它地方轻松找到的离题的内容)。每个小窍门在某种情形下都很必需的,或者能比替代品大大节省时间。
  • 这是为 Linux 写的。绝大部分条目都可以同样应用到 MacOS(或者甚至 Cygwin)。
  • 主要针对交互式 Bash,尽管大多数小窍门也可以应用到其它 shell,以及常规 Bash 脚本。
  • 包括了“标准的”UNIX 命令以及那些需要安装的软件包(它们很重要,值得安装)。

注意:

  • 为了能在一篇文章内展示尽量多的东西,一些具体的信息会被放到引用页里。你可以使用 Google 来获得进一步的内容。(如果需要的话,)你可以使用 apt-get/
    1
    yum

    /

    1
    dnf

    /

    1
    pacman

    /

    1
    pip

    /

    1
    2
    3
    4
    5
    6
    7
    brew</b1>来安装这些新的程序。</li>
    <li>使用 <a href="http://explainshell.com/">Explainshell</a> 来获取命令、参数、管道等内容的解释。</li>
    </ul>
    <h2 id="toc_2">基础</h2>
    <ul>
    <li>
    <p>学习基本 Bash 技能。实际上,键入<b1>man bash

    ,然后至少浏览一遍所有内容;它很容易理解,没那么长。其它 shell 也不错,但是 Bash 很强大,而且到处都可以找到(如果在你自己的笔记本上学习 zsh、fish 之类,会在很多情形下受到限制,比如使用现存的服务器时)。

  • 至少学好一种基于文本的编辑器。理想的一个是 Vim(

    1
    vi

    ),因为在终端中编辑时随时都能找到它(即使大多数时候你在使用 Emacs、一个大型的 IDE、或一个现代的时髦编辑器)。

  • 学习怎样使用

    1
    2
    3
    4
    5
    6
    7
    man</b1>来阅读文档(好奇的话,用 <b1>man man</b1>来列出分区号,比如 1 是常规命令,5 是文件描述,8 用于管理员)。用 <b1>apropos</b1>找到帮助页。了解哪些命令不是可执行程序,而是 Bash 内置的,你可以用 <b1>help</b1>和 <b1>help -d</b1>得到帮助。</p>
    </li>
    <li>
    <p>学习使用 <b1>></b1>和 <b1><</b1>来进行输出和输入重定向,以及使用 <b1>|</b1>来管道重定向,学习关于 stdout 和 stderr 的东西。</p>
    </li>
    <li>
    <p>学习 <b1>*

    (也许还有

    1
    ?</b1>和 <b1>{

    1
    2
    3
    4
    }</b1>)文件通配扩展和应用,以及双引号 <b1>"</b1>和单引号 <b1>'</b1>之间的区别。(更多内容请参看下面关于变量扩展部分)。</p>
    </li>
    <li>
    <p>熟悉 Bash 作业管理:<b1>&

    ctrl-zctrl-c

    1
    jobs

    1
    fg

    1
    bg

    1
    2
    3
    4
    kill</b1>等等。</p>
    </li>
    <li>
    <p>掌握<b1>ssh

    ,以及通过

    1
    ssh-agent

    1
    2
    3
    4
    ssh-add</b1>等进行无密码验证的基础技能。</p>
    </li>
    <li>
    <p>基本的文件管理:<b1>ls</b1>和 <b1>ls -l

    (特别是,知道

    1
    ls -l

    各个列的意义),

    1
    less

    1
    head

    1
    tail</b1>和 <b1>tail -f

    (或者更好的

    1
    less +F

    ),

    1
    ln</b1>和 <b1>ln -s

    (知道硬链接和软链接的区别,以及硬链接相对于软链接的优势),

    1
    chown

    1
    chmod

    1
    du

    (用于查看磁盘使用率的快速摘要:

    1
    du -sk *

    )。文件系统管理:

    1
    df

    1
    mount

    1
    fdisk

    1
    mkfs

    1
    lsblk

  • 基本的网络管理:

    1
    ip</b1>或 <b1>ifconfig

    1
    dig

  • 熟知正则表达式,以及各种使用

    1
    grep

    /

    1
    egrep

    的选项。

    1
    -i

    1
    -o

    1
    2
    3
    4
    -A</b1>和 <b1>-B</b1>选项值得掌握。</p>
    </li>
    <li>
    <p>学会使用 <b1>apt-get

    1
    yum</b1>,<b1>dnf</b1>或 <b1>pacman

    (这取决于你的发行版)来查找并安装软件包。确保你可以用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    pip</b1>来安装基于 Python 的命令行工具(下面的一些东西可以很容易地通过 <b1>pip</b1>安装)。</p>
    </li>
    </ul>
    <h2 id="toc_3">日常使用</h2>
    <ul>
    <li>
    <p>在Bash中,使用 <strong>tab</strong> 补完参数,使用 <strong>ctrl-r</strong> 来搜索命令历史。</p>
    </li>
    <li>
    <p>在Bash中,使用 <strong>ctrl-w</strong> 来删除最后的单词,使用 <strong>ctrl-u</strong> 来删除整行,返回行首。使用 <strong>alt-b</strong> 和 <strong>alt-f</strong> 来逐词移动,使用 <strong>ctrl-k</strong> 来清除到行尾的内容,以及使用 <strong>ctrl-l</strong> 清屏。参见 man readline 来查看 Bash 中所有默认的键盘绑定,有很多。例如,<strong>alt-.</strong> 可以循环显示先前的参数,而<strong>alt-</strong> 扩展通配。(LCTT 译注:关于 Bash 下的快捷键,可以参阅: <a href="https://linux.cn/article-5660-1.html">https://linux.cn/article-5660-1.html</a> )</p>
    </li>
    <li>
    <p>另外,如果你喜欢 vi 风格的键盘绑定,可以使用 set -o vi。</p>
    </li>
    <li>
    <p>要查看最近用过的命令,请使用 history 。 有许多缩写形式,比如 !$(上次的参数)和!!(上次的命令),虽然使用 ctrl-r 和 alt-. 更容易些。(LCTT 译注:关于历史扩展功能,可以参阅: <a href="https://linux.cn/article-5658-1.html">https://linux.cn/article-5658-1.html</a> )</p>
    </li>
    <li>
    <p>返回先前的工作目录: cd -</p>
    </li>
    <li>
    <p>如果你命令输入到一半,但是改变主意了,可以敲 <strong>alt-#</strong> 来添加一个 # 到开头,然后将该命令作为注释输入(或者使用快捷键 <strong>ctrl-a</strong>, <strong>#</strong>,<strong>enter</strong> 输入)。然后,你可以在后面通过命令历史来回到该命令。</p>
    </li>
    <li>
    <p>使用 xargs(或 parallel),它很强大。注意,你可以控制每行(-L)执行多少个项目,以及并行执行(-P)。如果你不确定它是否会做正确的事情,可以首先使用 xargs echo。同时,使用 -I{} 也很方便。样例:</p>
    <pre class="prettyprint ">  find . -name '*.py' | xargs grep some_function
      cat hosts | xargs -I{} ssh root@{} hostname
    </pre>
    </li>
    <li>
    <p>pstree -p 对于显示进程树很有帮助。</p>
    </li>
    <li>
    <p>使用 pgrep 和 pkill 来按名称查找进程或给指定名称的进程发送信号(-f 很有帮助)。</p>
    </li>
    <li>
    <p>掌握各种可以发送给进程的信号。例如,要挂起进程,可以使用 kill -STOP [pid]。完整的列表可以查阅 man 7 signal。</p>
    </li>
    <li>
    <p>如果你想要一个后台进程一直保持运行,使用 nohup 或 disown。</p>
    </li>
    <li>
    <p>通过 netstat -lntp 或 ss -plat 检查哪些进程在监听(用于 TCP,对 UDP 使用 -u 替代 -t)。</p>
    </li>
    <li>
    <p>lsof来查看打开的套接字和文件。</p>
    </li>
    <li>
    <p>在 Bash 脚本中,使用 set -x 调试脚本输出。尽可能使用严格模式。使用 set -e 在遇到错误时退出。也可以使用 set -o pipefail,对错误进行严格处理(虽然该话题有点微妙)。对于更复杂的脚本,也可以使用 trap。</p>
    </li>
    <li>
    <p>在 Bash 脚本中,子 shell(写在括号中的)是组合命令的便利的方式。一个常见的例子是临时移动到一个不同的工作目录,如:</p>
    <pre class="prettyprint ">  # 在当前目录做些事
      (cd /some/other/dir; other-command)
      # 继续回到原目录
    </pre>
    </li>
    <li>
    <p>注意,在 Bash 中有大量的各种各样的变量扩展。检查一个变量是否存在:${name:?error message}。例如,如果一个Bash脚本要求一个单一参数,只需写 input_file=${1:?usage: $0 input_file}。算术扩展:i=$(( (i + 1) % 5 ))。序列: {1..10}。修剪字符串:${var%suffix} 和 ${var#prefix}。例如,if var=foo.pdf ,那么 echo ${var%.pdf}.txt 会输出 foo.txt。</p>
    </li>
    <li>
    <p>命令的输出可以通过 <(some command) 作为一个文件来处理。例如,将本地的 /etc/hosts 和远程的比较:</p>
    <pre class="prettyprint ">  diff /etc/hosts <(ssh somehost cat /etc/hosts)
    </pre>
    </li>
    <li>
    <p>了解 Bash 中的&ldquo;嵌入文档&rdquo;,就像在 cat <<eof ... 中。</p>
    </li>
    <li>
    <p>在 Bash 中,通过:some-command >logfile 2>&1 同时重定向标准输出和标准错误。通常,要确保某个命令不再为标准输入打开文件句柄,而是将它捆绑到你所在的终端,添加 </dev/null 是个不错的做法。</p>
    </li>
    <li>
    <p>man ascii 可以得到一个不错的ASCII表,带有十六进制和十进制值两种格式。对于常规编码信息,man unicode,man utf-8 和 man latin1 将很有帮助。</p>
    </li>
    <li>
    <p>使用 screen 或 tmux 来复用屏幕,这对于远程 ssh 会话尤为有用,使用它们来分离并重连到会话。另一个只用于保持会话的最小可选方案是 dtach。</p>
    </li>
    <li>
    <p>在 ssh 中,知道如何使用 -L 或 -D(偶尔也用-R)来打开端口通道是很有用的,如从一台远程服务器访问网站时。</p>
    </li>
    <li>
    <p>为你的 ssh 配置进行优化很有用;例如,这个 ~/.ssh/config 包含了可以避免在特定网络环境中连接被断掉的情况的设置、使用压缩(这对于通过低带宽连接使用 scp 很有用),以及使用一个本地控制文件来开启到同一台服务器的多通道:</p>
    <pre class="prettyprint ">  TCPKeepAlive=yes
      ServerAliveInterval=15
      ServerAliveCountMax=6
      Compression=yes
      ControlMaster auto
      ControlPath /tmp/%r@%h:%p
      ControlPersist yes
    </pre>
    </li>
    <li>
    <p>其它一些与 ssh 相关的选项对会影响到安全,请小心开启,如各个子网或主机,或者在信任的网络中:StrictHostKeyChecking=no, ForwardAgent=yes</p>
    </li>
    <li>
    <p>要获得八进制格式的文件的权限,这对于系统配置很有用而用 ls 又没法查看,而且也很容易搞得一团糟,可以使用像这样的东西:</p>
    <pre class="prettyprint ">  stat -c '%A %a %n' /etc/timezone
    </pre>
    </li>
    <li>
    <p>对于从另一个命令的输出结果中交互选择值,可以使用<a href="https://github.com/mooz/percol">percol</a>。</p>
    </li>
    <li>
    <p>对于基于另一个命令(如git)输出的文件交互,可以使用fpp (<a href="https://github.com/facebook/PathPicker">路径选择器</a>)。</p>
    </li>
    <li>
    <p>要为当前目录(及子目录)中的所有文件构建一个简单的 Web 服务器,让网络中的任何人都可以获取,可以使用: python -m SimpleHTTPServer 7777 (使用端口 7777 和 Python 2)。</p>
    </li>
    </ul>
    <h2 id="toc_4">处理文件和数据</h2>
    <ul>
    <li>
    <p>要在当前目录中按名称定位文件,find . -iname '*something*'(或者相类似的)。要按名称查找任何地方的文件,使用 locate something(但请记住,updatedb 可能还没有索引最近创建的文件)。</p>
    </li>
    <li>
    <p>对于源代码或数据文件进行的常规搜索(要比 grep -r 更高级),使用 <a href="https://github.com/ggreer/the_silver_searcher">ag</a>。</p>
    </li>
    <li>
    <p>要将 HTML 转成文本:lynx -dump -stdin。</p>
    </li>
    <li>
    <p>对于 Markdown、HTML,以及各种类型的文档转换,可以试试 <a href="http://pandoc.org/">pandoc</a>。</p>
    </li>
    <li>
    <p>如果你必须处理 XML,xmlstarlet 虽然有点老旧,但是很好用。</p>
    </li>
    <li>
    <p>对于 JSON,使用jq。</p>
    </li>
    <li>
    <p>对于 Excel 或 CSV 文件,<a href="https://github.com/onyxfish/csvkit">csvkit</a> 提供了 in2csv,csvcut,csvjoin,csvgrep 等工具。</p>
    </li>
    <li>
    <p>对于亚马逊 S3 ,<a href="https://github.com/s3tools/s3cmd">s3cmd</a> 会很方便,而 <a href="https://github.com/bloomreach/s4cmd">s4cmd</a> 则更快速。亚马逊的 <a href="https://github.com/aws/aws-cli">aws</a> 则是其它 AWS 相关任务的必备。</p>
    </li>
    <li>
    <p>掌握 sort 和 uniq,包括 uniq 的 -u 和 -d 选项&mdash;&mdash;参见下面的单行程序。</p>
    </li>
    <li>
    <p>掌握 cut,paste 和 join,它们用于处理文本文件。很多人会使用 cut,但常常忘了 join。</p>
    </li>
    <li>
    <p>了解 tee,它会将 stdin 同时复制到一个文件和 stdout,如 ls -al | tee file.txt。</p>
    </li>
    <li>
    <p>知道 locale 会以微妙的方式对命令行工具产生大量的影响,包括排序的顺序(整理)以及性能。大多数安装好的 Linux 会设置 LANG 或其它 locale 环境变量为本地设置,比如像 US English。但是,你要明白,如果改变了本地环境,那么排序也将改变。而且 i18n 过程会让排序或其它命令的运行慢<em>好多倍</em>。在某些情形中(如像下面那样的设置操作或唯一性操作),你可以安全地整个忽略缓慢的 i18n 过程,然后使用传统的基于字节的排序顺序 export LC_ALL=C。</p>
    </li>
    <li>
    <p>了解基本的改动数据的 awk 和 sed 技能。例如,计算某个文本文件第三列所有数字的和:awk '{ x += $3 } END { print x }'。这可能比 Python 的同等操作要快3倍,而且要短3倍。</p>
    </li>
    <li>
    <p>在一个或多个文件中,替换所有出现在特定地方的某个字符串:</p>
    <pre class="prettyprint ">  perl -pi.bak -e 's/old-string/new-string/g' my-files-*.txt
    </pre>
    </li>
    <li>
    <p>要立即根据某个模式对大量文件重命名,使用 rename。对于复杂的重命名,<a href="https://github.com/jlevy/repren">repren</a> 可以帮助你达成。</p>
    <pre class="prettyprint ">  # 恢复备份文件 foo.bak -> foo:
      rename 's/.bak$//' *.bak
      # 完整的文件名、目录名 foo -> bar:
      repren --full --preserve-case --from foo --to bar .
    </pre>
    </li>
    <li>
    <p>使用 shuf 来从某个文件中打乱或随机选择行。</p>
    </li>
    <li>
    <p>了解 sort 的选项。知道这些键是怎么工作的(-t和-k)。特别是,注意你需要写-k1,1来只通过第一个字段排序;-k1意味着根据整行排序。</p>
    </li>
    <li>
    <p>稳定排序(sort -s)会很有用。例如,要首先按字段2排序,然后再按字段1排序,你可以使用 sort -k1,1 | sort -s -k2,2</p>
    </li>
    <li>
    <p>如果你曾经需要在 Bash 命令行中写一个水平制表符(如,用于 -t 参数的排序),按<strong>ctrl-v</strong> <strong>[Tab]</strong>,或者写$'t'(后面的更好,因为你可以复制/粘贴)。</p>
    </li>
    <li>
    <p>对源代码进行补丁的标准工具是 diff 和 patch。 用 diffstat 来统计 diff 情况。注意 diff -r 可以用于整个目录,所以可以用 diff -r tree1 tree2 | diffstat 来统计(两个目录的)差异。</p>
    </li>
    <li>
    <p>对于二进制文件,使用 hd 进行简单十六进制转储,以及 bvi 用于二进制编辑。</p>
    </li>
    <li>
    <p>还是用于二进制文件,strings(加上 grep 等)可以让你找出一点文本。</p>
    </li>
    <li>
    <p>对于二进制文件的差异(delta 压缩),可以使用 xdelta3。</p>
    </li>
    <li>
    <p>要转换文本编码,试试 iconv 吧,或者对于更高级的用途使用 uconv;它支持一些高级的 Unicode 的东西。例如,这个命令可以转换为小写并移除所有重音符号(通过扩展和丢弃):</p>
    <pre class="prettyprint ">  uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ' < input.txt > output.txt
    </pre>
    </li>
    <li>
    <p>要将文件分割成几个部分,来看看 split(按大小分割)和 csplit(按格式分割)吧。</p>
    </li>
    <li>
    <p>使用 zless,zmore,zcat 和 zgrep 来操作压缩文件。</p>
    </li>
    </ul>
    <h2 id="toc_5">系统调试</h2>
    <ul>
    <li>
    <p>对于 Web 调试,<b1>curl</b1>和 <b1>curl -I</b1>很方便灵活,或者也可以使用它们的同行 <b1>wget

    ,或者更现代的

    1
    httpie

  • 要了解磁盘、CPU、网络的状态,使用

    1
    iostat

    1
    netstat

    1
    top

    (或更好的

    1
    htop

    )和(特别是)

    1
    dstat

    。它们对于快速获知系统中发生的状况很好用。

  • 对于更深层次的系统总览,可以使用

    1
    glances

    。它会在一个终端窗口中为你呈现几个系统层次的统计数据,对于快速检查各个子系统很有帮助。

  • 要了解内存状态,可以运行

    1
    free</b1>和 <b1>vmstat

    ,看懂它们的输出结果吧。特别是,要知道“cached”值是Linux内核为文件缓存所占有的内存,因此,要有效地统计“free”值。

  • Java 系统调试是一件截然不同的事,但是对于 Oracle 系统以及其它一些 JVM 而言,不过是一个简单的小把戏,你可以运行

    1
    kill -3 <pid>

    ,然后一个完整的堆栈追踪和内存堆的摘要(包括常规的垃圾收集细节,这很有用)将被转储到stderr/logs。

  • 使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    mtr</b1>作路由追踪更好,可以识别网络问题。</p>
    </li>
    <li>
    <p>对于查看磁盘满载的原因,<b1>ncdu</b1>会比常规命令如 <b1>du -sh *</b1>更节省时间。</p>
    </li>
    <li>
    <p>要查找占用带宽的套接字和进程,试试 <b1>iftop</b1>或 <b1>nethogs</b1>吧。</p>
    </li>
    <li>
    <p>(Apache附带的)<b1>ab

    工具对于临时应急检查网络服务器性能很有帮助。对于更复杂的负载测试,可以试试

    1
    siege

  • 对于更仔细的网络调试,可以用

    1
    wireshark

    1
    tshark</b1>或 <b1>ngrep

  • 掌握

    1
    strace</b1>和 <b1>ltrace

    。如果某个程序失败、挂起或崩溃,而你又不知道原因,或者如果你想要获得性能的大概信息,这些工具会很有帮助。注意,分析选项(

    1
    -c

    )和使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    -p</b1>关联运行进程。</p>
    </li>
    <li>
    <p>掌握 <b1>ldd</b1>来查看共享库等。</p>
    </li>
    <li>
    <p>知道如何使用 <b1>gdb</b1>来连接到一个运行着的进程并获取其堆栈追踪信息。</p>
    </li>
    <li>
    <p>使用 <b1>/proc

    。当调试当前的问题时,它有时候出奇地有帮助。样例:

    1
    /proc/cpuinfo

    1
    /proc/xxx/cwd

    1
    /proc/xxx/exe

    1
    /proc/xxx/fd/

    1
    /proc/xxx/smaps

  • 当调试过去某个东西为何出错时,

    1
    2
    3
    4
    sar</b1>会非常有帮助。它显示了 CPU、内存、网络等的历史统计数据。</p>
    </li>
    <li>
    <p>对于更深层的系统和性能分析,看看 <b1>stap</b1>(<a href="https://sourceware.org/systemtap/wiki">SystemTap</a>),<a href="http://en.wikipedia.org/wiki/Perf_(Linux"><code>perf

    ) 和

    1
    sysdig

    吧。

  • 确认是正在使用的 Linux 发行版版本(支持大多数发行版):

    1
    lsb_release -a

  • 每当某个东西的行为异常时(可能是硬件或者驱动器问题),使用

    1
    dmesg

单行程序

这是将命令连成一行的一些样例:

  • 有时候通过 sort/uniq 对文本文件做交集、并集和差集运算时,这个例子会相当有帮助。假定 a 和 b 是已经进行了唯一性处理的文本文件。这会很快,而且可以处理任意大小的文件,总计可达数千兆字节。(Sort不受内存限制,不过如果 /tmp 放在一个很小的根分区的话,你可能需要使用 -T 选项。)也可参见上面关于LC_ALL的注解和 -u 选项(参见下面例子更清晰)。
    sh cat a b | sort | uniq > c # c 是 a 和 b 的并集
    cat a b | sort | uniq -d > c # c 是 a 和 b 的交集
    cat a b b | sort | uniq -u > c # c 是 a 减去 b 的差集
  • 使用 grep . * 来可视化查看一个目录中的所有文件的所有内容,例如,对于放满配置文件的目录: /sys, /proc, /etc。

  • 对某个文本文件的第三列中所有数据进行求和(该例子可能比同等功能的Python要快3倍,而且代码也少于其3倍):

      awk '{ x += $3 } END { print x }' myfile
    
  • 如果想要查看某个文件树的大小/日期,该例子就像一个递归ls -l,但是比ls -lR要更容易读懂:

      find . -type f -ls
    
  • 只要可以,请使用 xargs 或 parallel。注意,你可以控制每行(-L)执行多少个项目,以及并行执行(-P)。如果你不确定它是否会做正确的事情,可以首先使用 xargs echo。同时,使用 -I{} 也很方便。样例:

      find . -name '*.py' | xargs grep some_function
      cat hosts | xargs -I{} ssh root@{} hostname
    
  • 比如说,你有一个文本文件,如 Web 服务器的日志,在某些行中出现了某个特定的值,如 URL 中出现的 acct_id 参数。如果你想要统计有多少个 acct_id 的请求:

    cat access.log | egrep -o 'acct_id=[0-9]+' | cut -d= -f2 | sort | uniq -c | sort -rn
    
  • 运行该函数来获得来自本文的随机提示(解析Markdown并从中提取某个项目):

    function taocl() {
        curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md |
          pandoc -f markdown -t html |
          xmlstarlet fo --html --dropdtd |
          xmlstarlet sel -t -v "(html/body/ul/li[count(p)>0])[$RANDOM mod last()+1]" |
          xmlstarlet unesc | fmt -80
      }
    

晦涩难懂,但却有用

  • expr:实施算术或布林操作,或者求正则表达式的值

  • 1
    m4

    :简单的宏处理器

  • 1
    yes

    :大量打印一个字符串

  • 1
    cal

    :漂亮的日历

  • 1
    env

    :(以特定的环境变量设置)运行一个命令(脚本中很有用)

  • 1
    look

    :查找以某个字符串开头的英文单词(或文件中的行)

  • 1
    cut</b1>和 <b1>paste</b1>以及 <b1>join

    :数据处理

  • 1
    fmt

    :格式化文本段落

  • 1
    pr

    :格式化文本为页/列

  • 1
    fold

    :文本折行

  • 1
    column

    :格式化文本为列或表

  • 1
    expand</b1>和 <b1>unexpand

    :在制表符和空格间转换

  • 1
    nl

    :添加行号

  • 1
    seq

    :打印数字

  • 1
    bc

    :计算器

  • 1
    factor

    :分解质因子

  • 1
    gpg

    :加密并为文件签名

  • 1
    toe

    :terminfo 条目表

  • 1
    nc

    :网络调试和数据传输

  • 1
    socat

    :套接字中继和 tcp 端口转发(类似

    1
    netcat

  • 1
    slurm

    :网络流量可视化

  • 1
    dd

    :在文件或设备间移动数据

  • 1
    file

    :识别文件类型

  • 1
    tree

    :以树形显示目录及子目录;类似

    1
    ls

    ,但是是递归的。

  • 1
    stat

    :文件信息

  • 1
    tac

    :逆序打印文件

  • 1
    shuf

    :从文件中随机选择行

  • 1
    comm

    :逐行对比分类排序的文件

  • 1
    hd

    1
    bvi

    :转储或编辑二进制文件

  • 1
    strings

    :从二进制文件提取文本

  • 1
    tr

    :字符转译或处理

  • 1
    iconv

    1
    uconv

    :文本编码转换

  • 1
    split

    1
    csplit

    :分割文件

  • 1
    units

    :单位转换和计算;将每双周(fortnigh)一浪(浪,furlong,长度单位,约201米)转换为每瞬(blink)一缇(缇,twip,一种和屏幕无关的长度单位)(参见: /usr/share/units/definitions.units)(LCTT 译注:这都是神马单位啊!)

  • 1
    7z

    :高比率文件压缩

  • 1
    ldd

    :动态库信息

  • 1
    nm

    :目标文件的符号

  • 1
    ab

    :Web 服务器基准测试

  • 1
    strace

    :系统调用调试

  • 1
    mtr

    :用于网络调试的更好的路由追踪软件

  • 1
    cssh

    :可视化并发 shell

  • 1
    rsync

    :通过 SSH 同步文件和文件夹

  • 1
    wireshark</b1>和 <b1>tshark

    :抓包和网络调试

  • 1
    ngrep

    :从网络层摘取信息

  • 1
    host</b1>和 <b1>dig

    :DNS查询

  • 1
    lsof

    :处理文件描述符和套接字信息

  • 1
    dstat

    :有用的系统统计数据

  • 1
    glances

    :高级,多个子系统概览

  • 1
    iostat

    :CPU和磁盘使用率统计

  • 1
    htop

    :top的改进版

  • 1
    last

    :登录历史

  • 1
    w

    :谁登录进来了

  • 1
    id

    :用户/组身份信息

  • 1
    sar

    :历史系统统计数据

  • 1
    iftop

    1
    nethogs

    :按套接口或进程的网络使用率

  • 1
    ss

    :套接口统计数据

  • 1
    dmesg

    :启动和系统错误信息

  • 1
    hdparm

    :SATA/ATA 磁盘操作/改善性能

  • 1
    lsb_release

    :Linux 发行版信息

  • 1
    lsblk

    :列出块设备,以树形展示你的磁盘和分区

  • 1
    lshw

    :硬件信息

  • 1
    fortune

    1
    ddate</b1>和 <code>sl

    :嗯,好吧,它取决于你是否认为蒸汽机车和 Zippy 引用“有用”

更多资源

免责声明

除了非常小的任务外,其它都写出了代码供大家阅读。伴随力量而来的是责任。事实是,你在Bash中做的,并不意味着是你所应该做的!;)


via: https://github.com/jlevy/the-art-of-command-line

作者:jlevy 译者:GOLinux 校对:wxy

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

来源:https://linux.cn/article-5703-1.html

Linux:如何进行MySQL数据库表的故障检测

      表的故障检测和修正的一般过程如下:  ◆ 检查出错的表。如果该表检查通过,则完成任务,否则必须修复出错的数据库表。   ◆ 在开始修复之前对表文件进行拷贝,以保证数据的安全。   ◆ 开始修复数据库表。   ◆ 如果修复失败,从数据库的备份或更新日志中恢复数据。   在使用myisamchk或isamchk检查或修复表之前,应该首先注意:   ◆ 建立数据库备份和使用更新日志,以防修复失败,丢失数据。   ◆ 仔细阅读本章内容以后再进行操作,尤其是不应该在阅读“避免与MySQL服务器交互作用”之前进行操作。因为,在你没有足够的知识之前贸然操作,可能会引起严重的后果。   ◆ 如果你在Unix平台上对表进行维护时,应该首先注册到专用的帐户 mysql,以避免对表读写访问产生所有权的问题,以及破坏数据库目录的所有权限。   数据库表的维护工具   MySQL的myisanchk和isamchk实用程序很类似,基本上它们具有同样的使用方法。它们之间的主要区别时所使用的表的类型。为了检查/修复MyISAM表(.MYI和.MYD),你应该使用myisamchk实用程序。为了检查/修复ISAM表(.ISM和.ISD),你应该使用isamchk实用程序。   ◆ 为了使用任一个使用程序,应指明你要检查或修复的表,myisamchk和isamchk的使用方法为:

    shell>myisamchk options tbl_name shell>isamchk options tbl_name

  如果你愿意,你可以在命令行命名几个表。  ◆ 你也能指定一个名字作为一个索引文件(用“ .MYI”或“.ISM”后缀),它允许你通过使用模式“*.MYI”或“.ISM”指定在一个目录所有的表。例如,如果你在一个数据库目录,你可以这样在目录下检查所有的表:

      shell> myisamchk *.MYI shell>isamchk *.ISM

  ◆ 如果你不在数据库目录下,你可指定目录的路径:

    shell> myisamchk options /path/to/database_dir/*.MYI shell> isamchk options /path/to/database_dir/*.ISM

  ◆ 你甚至可以通过为MySQL数据目录的路径指定一个通配符来作用于所有的数据库中的所有表:

      shell> myisamchk options /path/to/datadir/*/*.MYIshell> isamchk options /path/to/database_dir/*/*.ISM

  这个方法无法在windows平台下使用。  注意 不论是myisamchk还是isamchk都不对表所在的位置做任何判断,因此,应该或者在包含表文件的目录运行程序,或者指定表的路径名。这允许你将表文件拷贝到另一个目录中并用该拷贝进行操作。        检查数据库表   myisamchk和isamchk提供了表的检查方法,这些方法在彻底检查表的程度方面有差异。   标准的方法检查表   通常用标准的方法就足够了。对表使用标准的方法进行检查,不使用任何选项直接调用即可,或用-s或–silent选项的任何一个:   myisamchk tbl_name isamchk tbl_name   这能找出所有错误的99.99%。它不能找出的是仅仅涉及数据文件的损坏(这很不常见)。   完全彻底的数据检查   为了执行扩充检查,使用–extend-check或-e选项,这个选项检查数据:

      myisamchk -e tbl_name isamchk -e tbl_name

  它做一个完全彻底的数据检查(-e意思是“扩展检查”)。它对每一行做每个键的读检查以证实他们确实指向正确的行。这在一个有很多键的大表上可能花很长时间。myisamchk通常将在它发现第一个错误以后停止。如果你想要获得更多的信息,你能增加–verbose(-v)选项。这使得myisamchk或isamchk继续一直到最多20个错误。在一般使用中,一个简单的标准检查(没有除表名以外的参数)就足够了。  中等程度的检查   指定选项–medium-check或-m   myisamchk -m tbl_name   中等程度的检查不如扩展检查彻底,但速度快一些。其意义不大,较少使用。   如果对于–extend-check检查不报告错误,则可以肯定表是完好的。如果你仍然感觉表有问题,那原因肯定在其它地方。应重新检查人和好像有问题的查询以验证查询是正确书写的。如果你认为问题可能是MySQL服务器的原因,应该考虑整理一份故障报告或者升级到新的版本上。   可能有用的检查选项:   1.-i或—information 打印统计信息,例如:   myisamchk -e -i tbl_name   象前面的命令一样,但是-i选项告诉myisamchk还打印出一些统计信息。   2.-C, –check-only-changed   只检查上一次检查后被修改的表 该贴已经同步到 robin的微博

 

本文内容由 robin 提供

 

 已同步至 wxy的微博

Linux:Linux 中引号的那些事

引号

 

我们将把编写脚本的事情暂时搁在一边,然后来讨论一些,我们一直在用的,但是没有解释的东西。引号在这一节里面,我们会讲述引号。引号有两个作用:

  1. 控制字符替换 和
  2. 执行将单词包含在一起的功能

我们已经使用过引号。在我们的脚本里面,将文本信息赋值给常量的赋值操作就使用了引号:

在上面这个例子中,文本信息是被双引号包括住的。我们使用双引号的原因是—我们要把所有单词包括住,当作一个整体来对待。如果我们没有使用引号,那么bash解释器,就会将所有位于第一个单词后面的单词,解释为其他的命令(第一个单词被解释为命令)。

尝试一下运行下面的命令,看看有什么效果出来:

 

单引号和双引号 

shell解释器可以识别双引号和单引号。 下面的复制表达式效果是等价的:

然而,在双引号和单引号之间存在一个重要的差别。 单引号,在字符替换方面有限制。 正如我们在上一节所看到的内容一样,你可以将一个变量放在双引号里面,而shell解释器依然会对变量执行字符替换的操作。 

我们可以通过使用echo命令来查看这种效果: 

如果我们将上述的双引号改为单引号,那么,行为将会改变:

双引号并没有限制—以”$”开头的变量的字符替换,不过,它的确对通配符的扩展效果进行了限制。比如,下面这个例子:

引用单个字符 

还有另外一种引用字符你会碰到的。 它就是反斜杠。The backslash tells 反斜杠告诉shell解释器忽略反斜杠符后面的第一个字符。比如:

通过使用反斜杠符,shell解释器忽略了对”$”符号进行解释。既然shell已经忽略了”$”,那么,shell解释器也就不会对$HOSTNAME执行字符替换了。 下面,给出一个更有用例子:

 

正如你所看到的,通过使用反斜杠符号,我们可以将双引号包含在文本里面。

反斜杠的其他使用技巧

如果,你阅读过任何软件的使用手册,并且这手册是由GNU项目完成的,那么,你会发现,在软件的命令选项中,除了以一个下划线_加一个字母的形式出现之外,还有,以两个下划线加一个完整的单词的形式出现。例如,下面两个语句是等价的:

 

为什么在软件中,这两种形式都是支持的呢?短的那种形式,是专门为那些懒的输入员而设定的,而长的那种形式,是专门为写脚本而存在的。我有时候,是混合着使用上面的两种形式,然后,我发现采用长的命令选项有用,如果,我写了一个脚本,并且,我将在几个月后去阅读它。看到长的命令选项,有助于我理解这个命令选项是什么意思,从而省却我去查man手册的功夫。现在多敲几下键盘,会以后节省很多功夫。 这样,懒惰的原则就保持住了。

你有可能会疑虑,使用长的命令形式,会导致一个单独的命令变得很长。 为了与这个问题斗争,你可以使用反斜杠来让shell解释器忽略换行符号,正如下面的操作:

这样使用反斜杠,可以让我们将每行的内容包含在一个单独的命令中。让这个技巧可以应用,要注意的地方:换行,必须在反斜杠后面马上出现(也就是,在输入了反斜杠之后,就必须换行了)。 如果,你将一个空格符放置在反斜杠后面,那么,空格符号会被忽略,而不是换行符被忽略。反斜杠符,也可以被用于,将特殊的符号插入到文本。special characters into our text. 这些符号,被叫做—转移字符,下面就有一些转移字符:

转义字符 …………………..

名字

可能的用途

n

换行符

添加空白行在文本中

t

制表符

将水平制表符添加到文本中

a

提醒

让你的终端发出嘟嘟声。

\

反斜杠

插入一个反斜杠符

f

formfeed

Sending this to your printer ejects thepage

转移字符的应用很常见。非常常见转移字符,这个想法,首先出现在C语言里面。编程语言今天,shell解释程序,C++,perl,python,awk,tcl和其他程序语言都使用了转移字符这个概念。通过使用echo命令的-e选项,我们将展示上述转移字符的应用:

 

来自:http://article.yeeyan.org/view/90556/299613

Linux:10个工具让你的 shell 脚本更强大

很多人误以为shell脚本只能在命令行下使用。其实shell也可以调用一些GUI组件,例如菜单,警告框,进度条等等。你可以控制最终的输出,光标位置还有各种输出效果。下面我将介绍一些工具,帮助你创建强大的,互动的,用户友好的 Unix/Linux shell脚本。我在FreeBSD和Linux下测试过这些工具,不过其他UNIX系列的操作系统应该都支持的。 

1. notify-send 命令

这个命令可以让你通过通知进程发送一个桌面通知给用户。这可以用来向用户发送提示,或者显示一些信息而不用打断用户工作。你需要安装如下软件包: 

$ sudo apt-get install libnotify-bin

下面这个例子展示了如何从命令行向桌面发送一个简单的消息: 

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:指定超时的时间,毫秒
  •  -u low:设置是否紧急
  •  -i gtk-dialog-info:通知图标,你可以指定图标 -i /path/to/your-icon.png

2. 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

输出:  

3. setleds 命令 

这个命令可以让你控制键盘灯,例如打开数字键盘灯: 

setleds -D +num

关闭数字键盘灯: 

setleds -D -num
  •   -caps: 清除大写灯
  •   +caps:打开大写灯
  •   -scroll:清除滚动锁
  •   +scroll:打开滚动锁

4. zenity 命令

这个命令可以显示GTK+的对话框,然后返回用户的输入。你可以用这个命令在脚本中显示信息,并要求用户输入信息。下面这段代码就是域名的whois查询: 

#!/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

输出: Fig.04: zenity in Action 

5. kdialog 命令 

这个命令和zenity很想,只不过它是为KDE/QT应用准备的。使用方法如下: 

kdialog --dontagain myscript:nofilemsg --msgbox "File: '~/.backup/config' not found."

输出  你可以查看 shell scription with KDE Dialogs 来获取更多信息 

6. Dialog 

这个命令可以在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

 

7. logger 命令 

这个命令可以让你写入系统日志例如 /var/log/messages: 

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 

8. setterm 命令 

这个命令可以设置中断的属性。下面的例子是强制屏幕全黑15分钟,并且60分钟后把显示器设为待机状态: 

setterm -blank 15 -powersave powerdown -powerdown 60

下面这段命令可以在中断显示加下划线的文字: 

setterm -underline on;
echo "Add Your Important Message Here"
setterm -underline off

或者你可以关闭光标: 

setterm -cursor off

9. smbclient:

向 MS-Windows 系统发送消息 smbclient可以和 SMB/CIFS服务器通信。它可以向MS-Windows系统的指定用户发送消息: 

smbclient -M WinXPPro <

或者 

echo "${Message}" | smbclient -M salesguy2

10. Bash Socket 编程 

你可以在bash中开启一个socket链接,并且传输数据。Bash有两个特殊的设备文件: 

  •   /dev/tcp/host/port - 如果hostname,和port是合法的话,bash会尝试开启一个TCP连接。
  •   /dev/udp/host/port - 如果hostname和port是合法的话,bash会开启一个UDP连接。

  你可以利用这个技术来测试一台主机的端口是否是开启的,而不需要使用nmap或者port扫描器: 

# 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"

你可以 使用循环来查找开着的端口: 

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 下面的这个例子让你的脚本扮演HTTP客户端: 

#!/bin/bash
exec 3<> /dev/tcp/${1:-www.cyberciti.biz}/80

printf "GET / HTTP/1.0\r\n" >&3
printf "Accept: text/html, text/plain\r\n" >&3
printf "Accept-Language: en\r\n" >&3
printf "User-Agent: nixCraft_BashScript v.%s\r\n" "${BASH_VERSION}"   >&3
printf "\r\n" >&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

关于GUITools和Cronjob 

如果你使用cronjob来调用你的脚本的话,你要通过“ export DISPLAY=[user's machine]:0 ”命令来设置本地的 display/input 服务。例如调用 /home/vivek/scripts/monitor.stock.sh脚本,它使用了 zenity 工具: 

@hourly DISPLAY=:0.0 /home/vivek/scripts/monitor.stock.sh

所有的命令你都可以通过“man”来查询详细的使用方式。 

VIA http://www.oschina.net/question/28_39527