快速操作Linux终端命令行的快捷键列表

快速操作Linux终端命令行的快捷键列表

操作组合键 说明 注释(自己猜想)
移动光标:
Ctrl + a 光标回到命令行首 a = ahead
Ctrl + e 光标回到命令行尾 e = end
Ctrl + b 光标向行首移动一个字符 b = backwards
Ctrl + f 光标向行尾移动一个字符 f = forwards
Alt + b 光标向行首移动一个单词
Alt + f 光标向行尾移动一个单词
删除命令:
Ctrl + w 向行首删除一个单词 w = word
Alt + d 向行尾删除一个单词 d = delete
Ctrl + k 删除光标处到行尾的字符
Ctrl + u 删除整个命令行文本字符
Ctrl + h 向行首删除一个字符 h = head
Ctrl + d 向行尾删除一个字符 d = delete
查找历史命令:
Ctrl + p 上一个使用的历史命令 p = previous
Ctrl + n 下一个使用的历史命令 n = next
Ctrl + r 快速检索历史命令 r = retrieve
其它:
Ctrl + i 相当于Tab键,命令、文件名自动补全
Ctrl + m 相当Enter键,执行命令
Ctrl + o 相当于Ctrl + m
Ctrl + t 交换光标所在字符和其前的字符
Ctrl + y 粘贴Ctrl+u,Ctrl+k,Ctrl+w删除的文本
Ctrl + s 使终端发呆,静止,可以使快速输出的终端屏幕停下来
Ctrl + q 退出Ctrl+s引起的发呆
Ctrl + z 使正在运行在终端的任务,运行于后台 可用fg恢复
Ctrl + c 中断终端中正在执行的任务
Ctrl + d 在空命令行的情况下可以退出终端 和上面的同命令但不同结果

MySQL插入Emoji提示 HY000 1366 Incorrect string value 错误

==本文前提:mysql Ver 14.14 Distrib 5.7.14, for Linux (x86_64) using EditLine wrapper==

  • 问题描述:在获取微信粉丝信息入库时线上环境产生了错误,而在本地开发时是成功的,线上环境提示nickname字段设置了错误字符串值,如下图:
    MySQL错误提示
  1. 出现这个问题,我明白是有用户的nickname里面含有Emoji导致的.

  2. 经过查找资料,我知晓在Emoji字符有一个特殊的地方,在存储时,需要用到4个字节。MySQL中常用的utf8字符集的utf8_general_ci这个collate最大只支持3个字节。所以为了支持能够存储Emoji,需要修改为utf8mb4字符集;于是用到了这篇文章里提到的方法,不管是修改/etc/my.cnf文件配置,还是在MySQL Client里修改全局配置,错误仍然出现.

    在查询相关资料时,还知道了一个信息,my.cnf中的default_character_set设置只影响mysql命令连接服务器时的连接字符集,不会对使用libmysqlclient库的应用程序产生任何作用,就是说会影响客户端链接时命令执行时的字符集,不影响我使用php脚本里的使用!鸟哥相关文章

  3. 后来我意识到一个问题,会不会是MySQL的sql_mode造成的问题,之前在做数据库迁移也出现过各种不兼容的问题.
    于是,我查看了一下线上MySQL的sql_mode的设置,因为sql_mode是有默认值的,所以在/etc/my.cnf里并没有显性写出,所以只能使用命令select @@sql_mode;在MySQL的客户端里查看,线上环境如下:
    默认的sql_mode

  4. 本地环境的如下:
    本地的sql_mode

  5. 修改/etc/my.conf文件,在mysqld部分增加sql_mode的配置,再次运行程序后成功,修改配置后内容如下图:
    修改后内容

  6. 去MySQL官网查看了5.7版本的Server SQL Modes模块这部分的文档,有这么一句话:

    The default SQL mode in MySQL 5.7 includes these modes: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION.

大意是,如果没有覆盖配置,那么你的5.7版本的MySQL的SQL mode默认配置就会是上面提到的那些,见3图的默认信息。在MySQL官网有对应每部分详细的说明,我怀疑是STRICT_TRANS_TABLES模式造成插入不成功,我没有测试,最后我只保留了NO_ENGINE_SUBSTITUTION.

NO_ENGINE_SUBSTITUTION:顾名思义,没有引擎时替换。详细来说就是,在创建或修改表时,当指定的数据表引擎不可用或是未编译时,会替换为MySQL默认设置的存储引擎.
> 1. 当此项未设置时,创建表和修改表在引擎不可用时它们的表现也不同。创建表时,如果引擎不可用,MySQL会选择默认的存储引擎,并产生一个警告,但表会创建成功;在修改表结构时,如果引擎不可用,也会产生警告,不同的是修改不会生效.
> 2. 当此项设置时,如果设置的存储引擎不可用,会产生一个错误,并且新建或是修改表都不会成功.

php-fpm里进程管理配置介绍

  • 强调一个观点,给自己的备忘录:
    > 关于开发时使用到的相关软件(php,nginx,php-fpm,mysql等)的使用信息,最好的方式是查看他们的文档和各自的配置信息.
当然没有一定的知识,可能看了也会云里雾里,在此给出自己对php-fpm配置文件的一些理解.
  • 首先,需要知道php-fpm配置文件所在的路径,使用命令ps -ef | grep php,如下图:
    本机
    远程服务器
  1. 可以看到在两台机器上,配置文件的路径不一样,上图的路径是/etc/php/5.6/fpm/php-fpm.conf,下图的路径是/etc/php-fpm.conf,而且php-fpm启动的进程数也不一样,master进程数都为1,worker进程数上图为3个,下图为5个.
  2. 配置文件路径不一样是因为软件安装时软件包里指定的路径不一样,但为什么启动的进程数也不一样呢?这就要看配置文件的详细内容了.
  • 打开php-fpm.conf,内容如下,详细信息请看注释:
;;;;;;;;;;;;;;;;;;;;;
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;

; All relative paths in this configuration file are relative to PHP's install
; prefix (/usr). This prefix can be dynamically changed by using the
; '-p' argument from the command line.

; Include one or more files. If glob(3) exists, it is used to include a bunch of
; files from a glob(3) pattern. This directive can be used everywhere in the
; file.
; Relative path can also be used. They will be prefixed by:
; - the global prefix if it's been set (-p argument)
; - /usr otherwise
; 可以看到,在文件的开始就又加载了另外一个目录下以 .conf 结尾的配置,关于进程运行方式和数量的配置就在这个目录下.
include=/etc/php/5.6/fpm/pool.d/*.conf

........ 以下内容省略,因为此次内容是关于php-fpm进程相关的配置,故只截取了部分内容 ........
  • 打开对应目录/etc/php/5.6/fpm/pool.d/,可以看到www.conf文件,打开文件,可以看到内容有很多,我只截取了与进程数相关的内容,大概从74行开始,不同机器,不同版本php-fpm,文件内容应该大同小异,详情请看注释
; Choose how the process manager will control the number of child processes.
; 注:以何种方式运行php-fpm,进而管理子进程数量,这里列出了三种可选方式:
; 静态模式(static),动态模式(dynamic),按需加载模式(ondemand).

; Possible Values:
; static - a fixed number (pm.max_children) of child processes;
; 注:静态模式,这种模式下,进程数是固定的,固定的个数就是参数 max_children 所设置的个数,此个数不可以动态调整,对于个人本地开发或是小站来说,此模式可以节约资源.

; dynamic - the number of child processes are set dynamically based on the
; following directives. With this process management, there will be
; always at least 1 children.
; 注:动态模式,这种模式下,进程数是会动态改变的,但最少必须保留一个进程,它的启始进程数和动态改变最大进程数受以下参数控制.
; pm.max_children - the maximum number of children that can
; be alive at the same time.
; 最大进程数:动态增加时,进程数的最大值,即使 php-fpm 进程数被使用完要报错了,进程数的总量也不会超过这个值的限定.
;
; pm.start_servers - the number of children created on startup.
; 启始进程数:望文生义即可.

; pm.min_spare_servers - the minimum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is less than this
; number then some children will be created.
; 最少保留进程数:望文生义即可,需要注意的时,即使没有请求需要处理,空闲的进程数少于这个设定值时,php-fpm的进程数还是会增加,这样就会浪费机器资源,要根据机器实际情况来调整.
;
; pm.max_spare_servers - the maximum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; 最大保留进程数:望文生义即可,需要注意的时,在没有请求需要处理,空闲的进程数大于这个设定值时,php-fpm的进程数会被kill掉.

; ondemand - no children are created at startup. Children will be forked when
; new requests will connect. The following parameter are used:
; 注:按需加载模式,服务启动时没有进程启动,但在请求到来时,会自动fork进程,这种模式下,进程数是会动态改变的,但最少必须保留一个进程,它的启始进程数和动态改变最大进程数受以下参数控制.
;
; pm.max_children - the maximum number of children that
; can be alive at the same time.
; 最大进程数:同上.
;
; pm.process_idle_timeout - The number of seconds after which
; an idle process will be killed.
; 进程空闲保留时间(秒):当进程空闲时,如果在设置的时间内没有被使用将会被kill掉.
; Note: This value is mandatory.
; 注:此参数不能缺省.
pm = dynamic

; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
; 注:非缺省值,含义见上.
pm.max_children = 5

; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
; 注:只能作用于动态模式,以动态模式运行时可为缺省值,缺省值为:最少保留进程数 + (最大保留进程数 - 最少保留进程数) / 2. 含义见上.
; 测试过,如果这个值随便填写重启php-fpm报错,但根据这个公式且不超过max_children,则没有问题,更详细需要进一步验证.
pm.start_servers = 2

; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
; 注:只能作用于动态模式,以动态模式运行时为非缺省值,含义见上.
pm.min_spare_servers = 1

; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
; 注:只能作用于动态模式,以动态模式运行时为非缺省值,含义见上.
pm.max_spare_servers = 3

; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s
; 注:只能作用于按需加载模式,缺省值为10s.
;pm.process_idle_timeout = 10s;
  • 总结:
  1. 以何种方式运行php-fpm,进而管理子进程数量,这里列出了三种可选方式:
    静态模式(static),动态模式(dynamic),按需加载模式(ondemand).

  2. 不同模式有不同参数控制进程数.

懂了配置参数的含义,就明白在不同的情况下要选择什么运行模式,以及为什么在查看进程数不同的机器上会有所不同了.

php-src源码目录说明

下面简单介绍一下PHP源码的目录结构。

  • 根目录: / 这个目录包含的东西比较多,主要包含一些说明文件以及设计方案。 其实项目中的这些README文件是非常值得阅读的例如:
    • /README.PHP4-TO-PHP5-THIN-CHANGES 这个文件就详细列举了PHP4和PHP5的一些差异。
    • 还有有一个比较重要的文件/CODING_STANDARDS,如果要想写PHP扩展的话,这个文件一定要阅读一下, 不管你个人的代码风格是什么样,怎么样使用缩进和花括号,既然来到了这样一个团体里就应该去适应这样的规范,这样在阅读代码或者别人阅读你的 代码是都会更轻松。
  • build 顾名思义,这里主要放置一些和源码编译相关的一些文件,比如开始构建之前的buildconf脚本等文件,还有一些检查环境的脚本等。
  • ext 官方扩展目录,包括了绝大多数PHP的函数的定义和实现,如array系列,pdo系列,spl系列等函数的实现,都在这个目录中。个人写的扩展在测试时也可以放到这个目录,方便测试和调试。
  • main 这里存放的就是PHP最为核心的文件了,主要实现PHP的基本设施,这里和Zend引擎不一样,Zend引擎主要实现语言最核心的语言运行环境。
  • Zend Zend引擎的实现目录,比如脚本的词法语法解析,opcode的执行以及扩展机制的实现等等。
  • pear “PHP 扩展与应用仓库”,包含PEAR的核心文件。
  • sapi 包含了各种服务器抽象层的代码,例如apache的mod_php,cgi,fastcgi以及fpm等等接口。
  • TSRM PHP的线程安全是构建在TSRM库之上的,PHP实现中常见的*G宏通常是对TSRM的封装,TSRM(Thread Safe Resource Manager)线程安全资源管理器。
  • tests PHP的测试脚本集合,包含PHP各项功能的测试文件
  • win32 这个目录主要包括Windows平台相关的一些实现,比如sokcet的实现在Windows下和*Nix平台就不太一样,同时也包括了Windows下编译PHP相关的脚本。

PHP的测试比较有意思,它使用PHP来测试PHP,测试php脚本在/run-tests.php,这个脚本读取tests目录中phpt文件。 读者可以打开这些看看,php定义了一套简单的规则来测试,例如以下的这个测试脚本/tests/basic/001.phpt:

--TEST--
Trivial "Hello World" test
--FILE--
<?php echo "Hello World"?>
--EXPECT--
Hello World

这段测试脚本很容易看懂,执行–FILE–下面的PHP文件,如果最终的输出是–EXPECT–所期望的结果则表示这个测试通过, 可能会有读者会想,如果测试的脚本不小心触发Fatal Error,或者抛出未被捕获的异常了,因为如果在同一个进程中执行, 测试就会停止,后面的测试也将无法执行,php中有很多将脚本隔离的方法比如: system(),exec()等函数,这样可以使用主测试进程服务调度被测脚本和检测测试结果,通过这些外部调用执行测试。 php测试使用了proc_open()函数, 这样就可以保证测试脚本和被测试脚本之间能隔离开。phpt文件的编写详细信息可参考 附录E phpt文件的编写。 如果你真的那么感兴趣,那么研究下$PHP_SRC/run-tests.php脚本的实现也是不错的选择。这个测试框架刚开始 由PHP的发明者Rasmus Lerdorf编写,后来进行了很多的改进。后面可能会引入并行测试的支持。

自我剖析

今天发生了一件事,和同事对某个功能的封装发生了一场小争论,他认为应该把这个功能封装成两个方法,以下是他的观点:

代码一旦出现岔路型变量,证明封装有问题(如这个里的 is_group_by);

对于使用者,这样的封装并没有透明化 “是否用 group by 逻辑” 对于之后的维护者,这类的方法势必两个分支会有不共用的逻辑,最终会导致一个大方法出现;

从两个角度考虑方便与否,一个是使用者,对于用参数还是用两个方法,使用者都需要知晓,使用者成本一样。对于可读性,多一个分岔路标变量会影响代码可读性,对于可维护性而言,分岔逻辑势必意味着大函数的出现;

  1. 永远不要断言未来,变的时候会去考虑改吗,这是一个明日复明日的问题,终有一个明日改不动了;
  2. is_group_by 可读性就好了吗.
而我的观点很简单:
  1. 不想新增新方法;
  2. 其它已经使用的地方不需要有改动.
在这记录一下我内心的想法:
  • 其实我是很赞同他的观点的,因为我内心是明白什么是好的设计,什么是差的设计。
  • 开始我也是那样想的,但由于要改动的地方太多,太麻烦,所以选择了简单的方式。
  • 以下这个想法不排除有推卸责任的嫌疑:你不能既让我在短时间里去实现业务逻辑,还要求一个很高的设计(搞什么,我现在写这篇稿子的时候,也开始觉得有推卸责任的嫌疑了)。
由今天的事引申
  • 不要在意别人在你背后说的话, 是真的不在意。

  • 除了上一条外,好的建议就要听。