Code Monkey home page Code Monkey logo

my-blog's People

Contributors

hehongwei44 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

my-blog's Issues

GitLab配置外部URL

In order for GitLab to display correct repository clone links to your users it needs to know the URL under which it is reached by your users, e.g. http://gitlab.example.com. Add or edit the following line in /etc/gitlab/gitlab.rb:

external_url "http://gitlab.example.com"

Run sudo gitlab-ctl reconfigure for the change to take effect.

这个参数的作用会影响仓库地址链接的显示,他的值显示如下图所示:

qq 20151024153058

默认会取计算机的名称,如果对外提供服务的话就要修改成IP地址或域名了。修改了这个属性后,要记得执行下面的命令来达到立即生效。

sudo gitlab-ctl reconfigure

PS:修改的参数在/etc/gitlab/gitlab.rb这个文件里

vim快捷键摘要

一般模式常用快捷键

移动光标的方法
h 或 向左箭头键(←) 光标向左移动一个字符
j 或 向下箭头键(↓) 光标向下移动一个字符
k 或 向上箭头键(↑) 光标向上移动一个字符
l 或 向右箭头键(→) 光标向右移动一个字符
如果你将右手放在键盘上的话,你会发现 hjkl 是排列在一起的,因此可以使用这四个按钮来移动光标。 如果想要进行多次移动的话,例如向下移动 30 行,可以使用 "30j" 或 "30↓" 的组合按键, 亦即加上想要进行的次数(数字)后,按下动作即可!
[Ctrl] + [f] 屏幕『向下』移动一页,相当于 [Page Down]按键 (常用)
[Ctrl] + [b] 屏幕『向上』移动一页,相当于 [Page Up] 按键 (常用)
[Ctrl] + [d] 屏幕『向下』移动半页
[Ctrl] + [u] 屏幕『向上』移动半页
+ 光标移动到非空格符的下一列
- 光标移动到非空格符的上一列
n<space> 那个 n 表示『数字』,例如 20 。按下数字后再按空格键,光标会向右移动这一行的 n 个字符。例如 20<space> 则光标会向后面移动 20 个字符距离。
0 或功能键[Home] 这是数字『 0 』:移动到这一行的最前面字符处 (常用)
$ 或功能键[End] 移动到这一行的最后面字符处(常用)
H 光标移动到这个屏幕的最上方那一行的第一个字符
M 光标移动到这个屏幕的**那一行的第一个字符
L 光标移动到这个屏幕的最下方那一行的第一个字符
G 移动到这个档案的最后一行(常用)
nG n 为数字。移动到这个档案的第 n 行。例如 20G 则会移动到这个档案的第 20 行(可配合 :set nu)
gg 移动到这个档案的第一行,相当于 1G 啊! (常用)
n<Enter> n 为数字。光标向下移动 n 行(常用)
搜寻与取代
/word 向光标之下寻找一个名称为 word 的字符串。例如要在档案内搜寻 vbird 这个字符串,就输入 /vbird 即可! (常用)
?word 向光标之上寻找一个字符串名称为 word 的字符串。
n 这个 n 是英文按键。代表『重复前一个搜寻的动作』。举例来说, 如果刚刚我们执行 /vbird 去向下搜寻 vbird 这个字符串,则按下 n 后,会向下继续搜寻下一个名称为 vbird 的字符串。如果是执行 ?vbird 的话,那么按下 n 则会向上继续搜寻名称为 vbird 的字符串!
N 这个 N 是英文按键。与 n 刚好相反,为『反向』进行前一个搜寻动作。 例如 /vbird 后,按下 N 则表示『向上』搜寻 vbird 。
使用 /word 配合 n 及 N 是非常有帮助的!可以让你重复的找到一些你搜寻的关键词!
:n1,n2s/word1/word2/g n1 与 n2 为数字。在第 n1 与 n2 行之间寻找 word1 这个字符串,并将该字符串取代为 word2 !举例来说,在 100 到 200 行之间搜寻 vbird 并取代为 VBIRD 则:
『:100,200s/vbird/VBIRD/g』。(常用)
:1,$s/word1/word2/g 从第一行到最后一行寻找 word1 字符串,并将该字符串取代为 word2 !(常用)
:1,$s/word1/word2/gc 从第一行到最后一行寻找 word1 字符串,并将该字符串取代为 word2 !且在取代前显示提示字符给用户确认 (confirm) 是否需要取代!(常用)
删除、复制与贴上
x, X 在一行字当中,x 为向后删除一个字符 (相当于 [del] 按键), X 为向前删除一个字符(相当于 [backspace] 亦即是退格键) (常用)
nx n 为数字,连续向后删除 n 个字符。举例来说,我要连续删除 10 个字符, 『10x』。
dd 删除游标所在的那一整列(常用)
ndd n 为数字。删除光标所在的向下 n 列,例如 20dd 则是删除 20 列 (常用)
d1G 删除光标所在到第一行的所有数据
dG 删除光标所在到最后一行的所有数据
d$ 删除游标所在处,到该行的最后一个字符
d0 那个是数字的 0 ,删除游标所在处,到该行的最前面一个字符
yy 复制游标所在的那一行(常用)
nyy n 为数字。复制光标所在的向下 n 列,例如 20yy 则是复制 20 列(常用)
y1G 复制游标所在列到第一列的所有数据
yG 复制游标所在列到最后一列的所有数据
y0 复制光标所在的那个字符到该行行首的所有数据
y$ 复制光标所在的那个字符到该行行尾的所有数据
p, P p 为将已复制的数据在光标下一行贴上,P 则为贴在游标上一行! 举例来说,我目前光标在第 20 行,且已经复制了 10 行数据。则按下 p 后, 那 10 行数据会贴在原本的 20 行之后,亦即由 21 行开始贴。但如果是按下 P 呢? 那么原本的第 20 行会被推到变成 30 行。 (常用)
J 将光标所在列与下一列的数据结合成同一列
c 重复删除多个数据,例如向下删除 10 行,[ 10cj ]
u 复原前一个动作。(常用)
[Ctrl]+r 重做上一个动作。(常用)
这个 u 与 [Ctrl]+r 是很常用的指令!一个是复原,另一个则是重做一次~ 利用这两个功能按键,你的编辑,嘿嘿!很快乐的啦!
. 不要怀疑!这就是小数点!意思是重复前一个动作的意思。 如果你想要重复删除、重复贴上等等动作,按下小数点『.』就好了! (常用)
## 一般模式切换到编辑模式的可用的按钮说明
进入插入或取代的编辑模式
i, I 进入插入模式(Insert mode):
i 为『从目前光标所在处插入』, I 为『在目前所在行的第一个非空格符处开始插入』。 (常用)
a, A 进入插入模式(Insert mode):
a 为『从目前光标所在的下一个字符处开始插入』, A 为『从光标所在行的最后一个字符处开始插入』。(常用)
o, O 进入插入模式(Insert mode):
这是英文字母 o 的大小写。o 为『在目前光标所在的下一行处插入新的一行』; O 为在目前光标所在处的上一行插入新的一行!(常用)
r, R 进入取代模式(Replace mode):
r 只会取代光标所在的那一个字符一次;R会一直取代光标所在的文字,直到按下 ESC 为止;(常用)
上面这些按键中,在 vi 画面的左下角处会出现『--INSERT--』或『--REPLACE--』的字样。 由名称就知道该动作了吧!!特别注意的是,我们上面也提过了,你想要在档案里面输入字符时, 一定要在左下角处看到 INSERT 或 REPLACE 才能输入喔!
[Esc] 退出编辑模式,回到一般模式中(常用)
## 一般模式切换到指令列模式的可用的按钮说明
指令列的储存、离开等指令
:w 将编辑的数据写入硬盘档案中(常用)
:w! 若文件属性为『只读』时,强制写入该档案。不过,到底能不能写入, 还是跟你对该档案的档案权限有关啊!
:q 离开 vi (常用)
:q! 若曾修改过档案,又不想储存,使用 ! 为强制离开不储存档案。
注意一下啊,那个惊叹号 (!) 在 vi 当中,常常具有『强制』的意思~
:wq 储存后离开,若为 :wq! 则为强制储存后离开 (常用)
ZZ 这是大写的 Z 喔!若档案没有更动,则不储存离开,若档案已经被更动过,则储存后离开!
:w [filename] 将编辑的数据储存成另一个档案(类似另存新档)
:r [filename] 在编辑的数据中,读入另一个档案的数据。亦即将 『filename』 这个档案内容加到游标所在行后面
:n1,n2 w [filename] 将 n1 到 n2 的内容储存成 filename 这个档案。
:! command 暂时离开 vi 到指令列模式下执行 command 的显示结果!例如
『:! ls /home』即可在 vi 当中察看 /home 底下以 ls 输出的档案信息!
vim 环境的变更
:set nu 显示行号,设定之后,会在每一行的前缀显示该行的行号
:set nonu 与 set nu 相反,为取消行号!

CentOS 打开mysql 3306端口

在CentOS系统中防火墙默认是阻止3306端口的,我们要是想访问mysql数据库,我们需要这个端口,命令如下:

1 /sbin/iptables -I INPUT -p tcp --dport 3306 -j ACCEPT

我们需要保存我们的操作,命令如下:

1  /etc/rc.d/init.d/iptables save

此时我们可以查看端口的状态,命令如下:

1 /etc/init.d/iptables status

当然如果你打开其他端口也一样,只需要把这个端口号换乘你需要的端口号即可,比如8080,80等常用端口。

linux命令userdel删除用户详解

作用

userdel命令来删除一个用户

用法

userdel [-r] [-f] 用户名

参数介绍

-r: 把用户的主目录一起删除

-f: 强制删除用户,即使该用户已经登录到系统

运用示例

# userdel -r demo

此命令删除用户demo在系统文件中(/etc/passwd, /etc/shadow, /etc/group)的记录,同时删除用户的主目录。

PS: 注意:这里如果用户还在登陆的话,会提示,用户正在登陆无法删除。此时可能需要先强制用户退出。操作步骤如下所示。

强制退出已经登陆用户

查看当前登陆用户的命令:

# w

会输入如下结果:

12:10:27 up 21:13,  1 user,  load average: 0.00, 0.01, 0.08
USER          TTY      FROM                 LOGIN@   IDLE   JCPU   PCPU WHAT
root            pts/0    ***.**.***.**    11:33    0.00s  0.08s  0.00s   w
tmp_3254  ps1       ***.**.***.**     11:33    0.00s  0.08s  0.00s   ls

这里知道了登陆用户的tty是ps1执行强制退出命令pkill:

强制退出

命令原型: pkill -kill -t [TTY]

代码如下:

# pkill -kill -t ps1

执行之后再执行名w 可以看到用户已经退出。

重复执行第二步的删除用户命令,删除成功。

CentOS 系统是怎样调用/etc/cron.hourly命令的?

最近想了解一下定时任务的执行过程,CentOS已经为用户自动增加了三个定时任务,分别是每天,每周,每月执行的/etc/cron.daily, /etc/cron.weekly /etc/cron.monthly。具体是通过命令run-parts执行的。Centos5的时候,这三个是写在/etc/crontab里的,但是CentOS6的时候,交由anacron来执行了,anacron是一个程序,一个命令而已,它是如何调用并执行那三个定时任务的,我就不说了,关键是理解/etc/anacrontab就行了。这里我也寻找了一下,是谁在调用anacron呢?,这个我已经找到了,是在/etc/cron.hourly/0anacron脚本文件中有调用,/usr/sbin/anacron -s这个命令.

Linux中变量内容的删除、替代与替换

变量设置方式 说明
$(变量#关键字) 若变量内容从头开始的数据符合“关键字”,则将符合的最短数据删除
$(变量##关键字) 若变量内容从头开始的数据符合“关键字”,则将符合的最长数据删除
$(变量%关键字) 若变量内容从尾向前的数据符合“关键字”,则将符合的最短数据删除
$(变量%%关键字) 若变量内容从尾向前的数据符合“关键字”,则将符合的最长数据删除
$(变量/旧字符串/新字符串) 若变量内容符合“旧字符串”,则第一个旧字符串会被新字符串替换
$(变量//旧字符串/新字符串) 若变量内容符合“旧字符串”,则全部旧字符串会被新字符串替换

javascript中字符串拼接的研究

最近在研究《javascript高级程序设计》中,有一段关于字符串特点的描述,原文大概如下:ECMAScript中的字符串是不可变的,也就是说,字符串一旦创建,他们的值就不能改变。要改变某个变量的保存的的字符串,首先要销毁原来的字符串,然后再用另外一个包含新值的字符串填充该变量,例如:

var lang = "Java";

lang = lang + "Script";

实现这个操作的过程如下:首先创建一个能容纳10个字符的新字符串,然后在这个字符串中填充“Java”和“Script”,最后一步是销毁原来的字符串“Java”和“Script”,因为这两个字符串已经没用了。但是在低版本的浏览器(如IE6)中,字符串拼接速度是很消耗一个性能的过程。

由此我就联想到了Java,在Java中的字符串机制也和js差不多(即创建了就不能改变,要改变只能销毁原来的值),但是Java有个StringBuffer解决了字符串不可变的问题,js且没有类似的方法。但是我们可以模拟这种缓冲机制。其原理是利用数组进行拼接,源代码如下:

function StringBuffer() {
    this.__strings__ = new Array();
}
StringBuffer.prototype.append = function (str) {
    this.__strings__.push(str);
    return this;    //方便链式操作
}
StringBuffer.prototype.toString = function () {
    return this.__strings__.join("");
}

/*测试*/
var buffer = new StringBuffer();
buffer.append("Hello ").append("javascript");

var result = buffer.toString();
alert(result); 

ps:gist地址如下:https://gist.github.com/hehongwei44/fe71f10e4d2d9295aeab

机制我们模拟出来了,但是这个方法和字符串拼接性能上有多少差别了,我们可以测试一下,测试代码如下:

var d1 = new Date();
var str = "";
for(var i = 0; i < 10000; i++){
    str += "text ";
}
var d2 = new Date();
document.write("测试一花费: " + (d2.getTime() - d1.getTime())/1000 + "秒"+"<br/>");

var oBuffer = new StringBuffer();
d3 = new Date();
for(var i = 0; i < 10000; i++){
    oBuffer.append("text ");
}
var sResult = oBuffer.toString();
d4 = new Date();
document.write("测试二花费: " + (d4.getTime() - d3.getTime())/1000 + "秒");

测试结果如下:(环境不同,测试结果可能不同):

1.在以1000次为基数的情况下,进行比较,两者执行都非常快(基本都是几毫秒)耗时都差不多,后者以前者相差不会超过10个毫秒。
2.在以10000次为基数的情况下,执行结果和上面差不多,但是前者在IE6下话费的事件较多。
3.在以100000次为基数的情况下,字符串拼接在IE6下,明显花的时间更多,其他浏览器相差不大,有的反而比StringBuffer更短。

结论

1.在拼接词数少于1000次的情况下,大胆的使用前者,一般我们也很少碰到拼接次数上千的情况。
2.其他浏览器对于拼接都没什么性能问题,主要是IE6,如果拼接次数上万或者十万的话,建议单独对IE6是用StringBuffer模拟。

带宽是什么

带宽是什么呢?

我们讲的宽带是指数据的发送速度。比如我们的百兆网卡,便是指网卡的最大发送速度为100Mbps,也就是网卡在1秒钟最多可以发出100Mb的数据。

100Mbps换算成常见的下载速度的话,换算公式为100Mbps/8 = 12.5MB/s。也就是说最快的下载速度可以达到12.5MB每秒。

顺便说一下,我们一般常说的比如100M带宽,全程应该是100Mbit/s,或者100Mbps,后边的“bit/s"经常省略。

linux命令useradd添加用户详解

在linux中增加用户我们使用useradd命令而删除用户直接使用userdel即可了,下面小编来给各位同学介绍一下在linux中添加与删除用户方法吧。

1.作用

useradd或adduser命令用来建立用户帐号和创建用户的起始目录,使用权限是超级用户。

2.格式

useradd [-d home] [-s shell] [-c comment] [-m [-k template]] [-f inactive] [-e expire ] [-p passwd] [-r] name

3.主要参数

 -c:加上备注文字,备注文字保存在passwd的备注栏中。

 -d:指定用户登入时的主目录,替换系统默认值/home/<用户名>

 -D:变更预设值。

 -e:指定账号的失效日期,日期格式为MM/DD/YY,例如06/30/12。缺省表示永久有效。

 -f:指定在密码过期后多少天即关闭该账号。如果为0账号立即被停用;如果为-1则账号一直可用。默认值为-1.

 -g:指定用户所属的群组。值可以使组名也可以是GID。用户组必须已经存在的,期默认值为100,即users。

 -G:指定用户所属的附加群组。

 -m:自动建立用户的登入目录。

 -M:不要自动建立用户的登入目录。

 -n:取消建立以用户名称为名的群组。

 -r:建立系统账号。

 -s:指定用户登入后所使用的shell。默认值为/bin/bash。

-u:指定用户ID号。该值在系统中必须是唯一的。0~499默认是保留给系统用户账号使用的,所以该值必须大于499。

4.说明

useradd可用来建立用户账号,它和adduser命令是相同的。账号建好之后,再用passwd设定账号的密码。使用useradd命令所建立的账号,实际上是保存在/etc/passwd文本文件中。

5.应用实例

应用实例-01

建立一个新用户账户testuser1,并设置UID为544,主目录为/usr/testuser1,属于users组:

# useradd -u 544 -d /usr/testuser1  -g users -m  testuser1

加-m 如果主目录不存在则自动创建

应用实例-02

使用管理员账号登陆系统,建立用户tmp_3452 密码3sdt5:Eawhg

[root@ptr228 ~]# adduser tmp_3452

修改密码命令:

[root@ptr228 ~]# passwd tmp_3452

在系统出现提示输入密码是输入密码:3sdt5:Eawhg 系统提示输入确认密码后再输入一次。OK添加成功。

应用实例-03

useradd批量添加用户

使用useradd时,如果后面不添加任何参数选项,例如:#sudo useradd test创建出来的用户将是默认“三无”用户:一无Home Directory,二无密码,三无系统Shell。

步骤如下:

1.建立用户名列表文件username.txt 
2.创建用户密码对应文件serc.txt,格式为username:password (注意文件的格式)

stu1:tt1
stu2:tt2
stu3:tt3
stu4:tt4
stu5:tt5
stu6:tt6  

3.批量添加的脚本文件aa.sh

##添加用户,并且在/home/ 下为用户生成用户目录。
cat < username.txt | xargs -n 1
useradd -m##批处理模式下更新密码
chpasswd < serc.txt##将上述的密码转换到密码文件和组文件
pwconv##结束验证信息
echo "OK 新建完成"(4)执行该脚本文件,查看执行过程
root@liu:/home/liu/Desktop/Dos# sh aa.sh

useradd命令,在执行没有出错的情况下,不会输出任何的信息,不会与用户交互。但是用户必须要记住那些设置项目,否则添加的用户可能出现一些预想不到的结果。

在AWS的EC2服务器上创建root用户密码,并使用root用户登录

今天开始研究亚马逊的云主机EC2,遇到了一个问题,我需要在EC2上安装一些Web软件时,但是执行一些命令只能是root权限才可以运行,而EC2默认不是通过root用户登录的,所以需要需要创建新的root密码并切换到root帐号

1、根据官网提供的方法登录连接到EC2服务器(官网推荐windows用户使用PUTTY连接)

2、 创建root的密码,输入如下命令:

sudo passwd root

3、然后会提示你输入new password。输入一个你要设置的root的密码,需要你再输入一遍进行验证。

4、接下来,切换到root身份,输入如下命令:

su root

5、使用root身份编辑亚马逊云主机的ssh登录方式,找到 PasswordAuthentication no,把no改成yes。输入:

vim /etc/ssh/sshd_config

6、接下来,要重新启动下sshd,如下命令:

sudo /sbin/service sshd restart

7、然后再切换到root身份

su root

8、再为原来的”ec2-user”添加登录密码。如下命令:

passwd ec2-user

按提示,两次输入密码。到此可以用root身份直接登录EC2的服务器了。

怎样在gitlab上集成github服务

为了使用启用GitHub一键验证功能,前提你需要在GitHub上注册一个应用,GitHub将会生成一个application ID和其对应的密码。其详细的操作步骤如下:

1.登录到你的GitHub帐户,点击你的头像,会弹出一个下拉菜单,找到settings选项,点击进入。

qq 20151027113908

2.在左侧菜单中,点击Applications菜单,之后在右则菜单中提供了两种选择,我们选择Developer applications

3.选择单击"Register new application"按钮.

image

4.提供所需的信息,每个字段的含义如下描述:

Application name:运用的名称,可以为任何值
Homepage URL: 安装GitLab服务的URL地址
Application description: 运用的描述,可选填。
Authorization callback URL:授权成功时的回调函数

5.单击Register application完成注册,注册成功后的信息类似下图的模版,其中Client IDClient Secret这两项特别重要,会在gitlab配置中使用到。

github_app

  1. 编辑修改gitlab.rb文件,操作命令如下:

    sudo vim /etc/gitlab/gitlab.rb

修改的内容包括,启用这些配置

gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = false
gitlab_rails['block_auto_created_users'] = true

添加GitHub授权:

gitlab_rails['omniauth_providers'] = [
    {
      "name" => "github",
      "app_id" => "YOUR_APP_ID",
      "app_secret" => "YOUR_APP_SECRET",
      "url" => "https://github.com/",
      "args" => { "scope" => "user:email" }
    }
  ]

上面的操作都是在gitlab.rb这个文件中完成的。

7.保存并重启GitLab来使刚才的修改生效。操作命令如下:

sudo gitlab-ctl reconfigure

linux系统中命令与文件的查找

命令与文件的搜寻:

文件的搜寻可就厉害了!因为我们常常需要知道那个文件放在哪里,才能够对该文件进行一些修改或维护等动作。 有些时候某些软件配置文件的文件名是不变的,但是各 distribution 放置的目录则不同。 此时就得要利用一些搜寻命令将该配置文件的完整文件名找出来,这样才能修改嘛。

脚本文件名的查询

我们知道在终端机模式当中,连续输入两次[tab]按键就能够知道使用者有多少命令可以下达。 那你知不知道这些命令的完整文件名放在哪里?举例来说,ls 这个常用的命令放在哪里呢? 就透过 which 或 type 来找寻吧!

which (寻找『执行文件』)

[root@www ~]# which [-a] command
选项或参数:
-a :将所有由 PATH 目录中可以找到的命令均列出,而不止第一个被找到的命令名称

范例一:分别用root与一般帐号搜寻 ifconfig 这个命令的完整档名
[root@www ~]# which ifconfig
/sbin/ifconfig            <==用 root 可以找到正确的运行档名喔!
[root@www ~]# su - vbird <==切换身份成为 vbird 去!
[vbird@www ~]$ which ifconfig
/usr/bin/which: no ifconfig in (/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin
:/home/vbird/bin)         <==见鬼了!竟然一般身份帐号找不到!
# 因为 which 是根据使用者所配置的 PATH 变量内的目录去搜寻可运行档的!所以,
# 不同的 PATH 配置内容所找到的命令当然不一样啦!因为 /sbin 不在 vbird 的 
# PATH 中,找不到也是理所当然的啊!了乎?
[vbird@www ~]$ exit      <==记得将身份切换回原本的 root

范例二:用 which 去找出 which 的档名为何?
[root@www ~]# which which
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot '
        /usr/bin/which
# 竟然会有两个 which ,其中一个是 alias 这玩意儿呢!那是啥?
# 那就是所谓的『命令别名』,意思是输入 which 会等於后面接的那串命令啦!
# 更多的数据我们会在 bash 章节中再来谈的!

范例三:请找出 cd 这个命令的完整档名
[root@www ~]# which cd
/usr/bin/which: no cd in (/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin
:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)
# 瞎密?怎么可能没有 cd ,我明明就能够用 root 运行 cd 的啊!

这个命令是根据『PATH』这个环境变量所规范的路径,去搜寻『执行文件』的文件名~ 所以,重点是找出『执行文件』而已!且 which 后面接的是『完整文件』!若加上 -a 选项,则可以列出所有的可以找到的同名运行档,而非仅显示第一个而已!

最后一个范例最有趣,怎么 cd 这个常用的命令竟然找不到啊!为什么呢?这是因为 cd『bash 内建的命令』啦! 但是 which 默认是找 PATH 内所规范的目录,所以当然一定找不到的啊!那怎办?没关系!我们可以透过 type 这个命令喔! 关於 type 的用法我们将在 第十一章的 bash 再来谈!

文件名的查找

再来谈一谈怎么搜寻文件吧!在 Linux 底下也有相当优异的搜寻命令!通常 find 不很常用的!因为速度慢之外。通常我们都是先使用 whereis 或者是 locate 来检查,如果真的找不到了,才用 find 来搜寻! 为什么呢?因为 whereis 与 locate 是利用数据库来搜寻数据,所以相当的快速,而且并没有实际的查询硬盘, 比较省时间啦!

whereis (寻找特定文件)

[root@www ~]# whereis [-bmsu] 文件或目录名
选项与参数:
-b    :只找 binary 格式的文件
-m    :只找在说明档 manual 路径下的文件
-s    :只找 source 来源文件
-u    :搜寻不在上述三个项目当中的其他特殊文件

范例一:请用不同的身份找出 ifconfig 这个档名
[root@www ~]# whereis ifconfig 
ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz
[root@www ~]# su - vbird        <==切换身份成为 vbird
[vbird@www ~]$ whereis ifconfig <==找到同样的结果喔!
ifconfig: /sbin/ifconfig /usr/share/man/man8/ifconfig.8.gz
[vbird@www ~]$ exit              <==回归身份成为 root 去!
# 注意看,明明 which 一般使用者找不到的 ifconfig 却可以让 whereis 找到!
# 这是因为系统真的有 ifconfig 这个『文件』,但是使用者的 PATH 并没有加入 /sbin
# 所以,未来你找不到某些命令时,先用文件搜寻命令找找看再说!

范例二:只找出跟 passwd 有关的『说明文件』档名(man page)
[root@www ~]# whereis -m passwd
passwd: /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz

等一下我们会提到 find 这个搜寻命令, find 是很强大的搜寻命令,但时间花用的很大! (因为 find 是直接搜寻硬盘,为如果你的硬盘比较老旧的话,嘿嘿!有的等!) 这个时候 whereis 就相当的好用了!另外, whereis 可以加入选项来找寻相关的数据, 例如如果你是要找可运行档( binary )那么加上 -b 就可以啦! 如果不加任何选项的话,那么就将所有的数据列出来罗!

那么 whereis 到底是使用什么咚咚呢?为何搜寻的速度会比 find 快这么多? 其实那也没有什么!这是因为 Linux 系统会将系统内的所有文件都记录在一个数据库文件里面, 而当使用 whereis 或者是底下要说的 locate 时,都会以此数据库文件的内容为准, 因此,有的时后你还会发现使用这两个运行档时,会找到已经被杀掉的文件! 而且也找不到最新的刚刚创建的文件呢!这就是因为这两个命令是由数据库当中的结果去搜寻文件的所在啊! 更多与这个数据库有关的说明,请参考下列的 locate 命令。

locate

[root@www ~]# locate [-ir] keyword
选项与参数:
-i  :忽略大小写的差异;
-r  :后面可接正规表示法的显示方式

范例一:找出系统中所有与 passwd 相关的档名
[root@www ~]# locate passwd
/etc/passwd
/etc/passwd-
/etc/news/passwd.nntp
/etc/pam.d/passwd
....(底下省略)....

这个 locate 的使用更简单,直接在后面输入『文件的部分名称』后,就能够得到结果。 举上面的例子来说,我输入 locate passwd ,那么在完整文件名 (包含路径名称) 当中,只要有 passwd 在其中, 就会被显示出来的!这也是个很方便好用的命令,如果你忘记某个文件的完整文件时。

但是,这个东西还是有使用上的限制呦!为什么呢?你会发现使用 locate 来寻找数据的时候特别的快, 这是因为 locate 寻找的数据是由『已创建的数据库 /var/lib/mlocate/』 里面的数据所搜寻到的,所以不用直接在去硬盘当中存取数据,呵呵!当然是很快速罗!

那么有什么限制呢?就是因为他是经由数据库来搜寻的,而数据库的创建默认是在每天运行一次 (每个 distribution 都不同,CentOS 5.x 是每天升级数据库一次!),所以当你新创建起来的文件, 却还在数据库升级之前搜寻该文件,那么 locate 会告诉你『找不到!』呵呵!因为必须要升级数据库呀!

那能否手动升级数据库哪?当然可以啊!升级 locate 数据库的方法非常简单,直接输入『 updatedb 』就可以了! updatedb 命令会去读取 /etc/updatedb.conf 这个配置档的配置,然后再去硬盘里面进行搜寻档名的动作, 最后就升级整个数据库文件罗!因为 updatedb 会去搜寻硬盘,所以当你运行 updatedb 时,可能会等待数分钟的时间喔!

  • updatedb:根据 /etc/updatedb.conf 的配置去搜寻系统硬盘内的档名,并升级 /var/lib/mlocate 内的数据库文件;
  • locate:依据 /var/lib/mlocate 内的数据库记载,找出使用者输入的关键字档名。

find

[root@www ~]# find [PATH] [option] [action]
选项与参数:
1. 与时间有关的选项:共有 -atime, -ctime 与 -mtime ,以 -mtime 说明
   -mtime  n :n 为数字,意义为在 n 天之前的『一天之内』被更动过内容的文件;
   -mtime +n :列出在 n 天之前(不含 n 天本身)被更动过内容的文件档名;
   -mtime -n :列出在 n 天之内(含 n 天本身)被更动过内容的文件档名。
   -newer file :file 为一个存在的文件,列出比 file 还要新的文件档名

范例一:将过去系统上面 24 小时内有更动过内容 (mtime) 的文件列出
[root@www ~]# find / -mtime 0
# 那个 0 是重点!0 代表目前的时间,所以,从现在开始到 24 小时前,
# 有变动过内容的文件都会被列出来!那如果是三天前的 24 小时内?
# find / -mtime 3 有变动过的文件都被列出的意思!

范例二:寻找 /etc 底下的文件,如果文件日期比 /etc/passwd 新就列出
[root@www ~]# find /etc -newer /etc/passwd
# -newer 用在分辨两个文件之间的新旧关系是很有用的!

时间参数真是挺有意思的!我们现在知道 atime, ctime 与 mtime 的意义,如果你想要找出一天内被更动过的文件名称, 可以使用上述范例一的作法。但如果我想要找出『4天内被更动过的文件档名』呢?那可以使用『 find /var -mtime -4 』。那如果是『4天前的那一天』就用『 find /var -mtime 4 』。有没有加上『+, -』差别很大喔!我们可以用简单的图示来说明一下:

图中最右边为目前的时间,越往左边则代表越早之前的时间轴啦。由图5.2.1我们可以清楚的知道:

find_time

  • +4代表大於等於5天前的档名:ex> find /var -mtime +4
  • -4代表小於等於4天内的文件档名:ex> find /var -mtime -4
  • 4则是代表4-5那一天的文件档名:ex> find /var -mtime 4

非常有趣吧!你可以在 /var/ 目录下搜寻一下,感受一下输出文件的差异喔!再来看看其他 find 的用法吧!

选项与参数:

2. 与使用者或群组名称有关的参数:
   -uid n :n 为数字,这个数字是使用者的帐号 ID,亦即 UID ,这个 UID 是记录在
            /etc/passwd 里面与帐号名称对应的数字。这方面我们会在第四篇介绍。
   -gid n :n 为数字,这个数字是群组名称的 ID,亦即 GID,这个 GID 记录在
            /etc/group,相关的介绍我们会第四篇说明~
   -user name :name 为使用者帐号名称喔!例如 dmtsai 
   -group name:name 为群组名称喔,例如 users ;
   -nouser    :寻找文件的拥有者不存在 /etc/passwd 的人!
   -nogroup   :寻找文件的拥有群组不存在於 /etc/group 的文件!
                当你自行安装软件时,很可能该软件的属性当中并没有文件拥有者,
                这是可能的!在这个时候,就可以使用 -nouser 与 -nogroup 搜寻。

    范例三:搜寻 /home 底下属於 vbird 的文件
    [root@www ~]# find /home -user vbird
    # 这个东西也很有用的~当我们要找出任何一个使用者在系统当中的所有文件时,
    # 就可以利用这个命令将属於某个使用者的所有文件都找出来喔!

    范例四:搜寻系统中不属於任何人的文件
    [root@www ~]# find / -nouser
    # 透过这个命令,可以轻易的就找出那些不太正常的文件。
    # 如果有找到不属於系统任何人的文件时,不要太紧张,
    # 那有时候是正常的~尤其是你曾经以原始码自行编译软件时。

如果你想要找出某个使用者在系统底下创建了啥咚咚,使用上述的选项与参数,就能够找出来啦! 至於那个 -nouser 或 -nogroup 的选项功能中,除了你自行由网络上面下载文件时会发生之外, 如果你将系统里面某个帐号删除了,但是该帐号已经在系统内创建很多文件时,就可能会发生无主孤魂的文件存在! 此时你就得使用这个 -nouser 来找出该类型的文件罗!

选项与参数:

3. 与文件权限及名称有关的参数:
   -name filename:搜寻文件名称为 filename 的文件;
   -size [+-]SIZE:搜寻比 SIZE 还要大(+)或小(-)的文件。这个 SIZE 的规格有:
                   c: 代表 byte, k: 代表 1024bytes。所以,要找比 50KB
                   还要大的文件,就是『 -size +50k 』
   -type TYPE    :搜寻文件的类型为 TYPE 的,类型主要有:一般正规文件 (f),
                   装置文件 (b, c), 目录 (d), 连结档 (l), socket (s), 
                   及 FIFO (p) 等属性。
   -perm mode  :搜寻文件权限『刚好等於』 mode 的文件,这个 mode 为类似 chmod
                 的属性值,举例来说, -rwsr-xr-x 的属性为 4755 !
   -perm -mode :搜寻文件权限『必须要全部囊括 mode 的权限』的文件,举例来说,
                 我们要搜寻 -rwxr--r-- ,亦即 0744 的文件,使用 -perm -0744,
                 当一个文件的权限为 -rwsr-xr-x ,亦即 4755 时,也会被列出来,
                 因为 -rwsr-xr-x 的属性已经囊括了 -rwxr--r-- 的属性了。
   -perm +mode :搜寻文件权限『包含任一 mode 的权限』的文件,举例来说,我们搜寻
                 -rwxr-xr-x ,亦即 -perm +755 时,但一个文件属性为 -rw-------
                 也会被列出来,因为他有 -rw.... 的属性存在!

范例五:找出档名为 passwd 这个文件
[root@www ~]# find / -name passwd
# 利用这个 -name 可以搜寻档名啊!

范例六:找出 /var 目录下,文件类型为 Socket 的档名有哪些?
[root@www ~]# find /var -type s
# 这个 -type 的属性也很有帮助喔!尤其是要找出那些怪异的文件,
# 例如 socket 与 FIFO 文件,可以用 find /var -type p 或 -type s 来找!

范例七:搜寻文件当中含有 SGID 或 SUID 或 SBIT 的属性
[root@www ~]# find / -perm +7000 
# 所谓的 7000 就是 ---s--s--t ,那么只要含有 s 或 t 的就列出,
# 所以当然要使用 +7000 ,使用 -7000 表示要含有 ---s--s--t 的所有三个权限,
# 因此,就是 +7000 ~了乎?

上述范例中比较有趣的就属 -perm 这个选项啦!他的重点在找出特殊权限的文件罗! 我们知道 SUID 与 SGID 都可以配置在二进位程序上,假设我想要找出来 /bin, /sbin 这两个目录下, 只要具有 SUID 或 SGID 就列出来该文件,你可以这样做:

[root@www ~]# find /bin /sbin -perm +6000

因为 SUID 是 4 分,SGID 2 分,总共为 6 分,因此可用 +6000 来处理这个权限! 至於 find 后面可以接多个目录来进行搜寻!另外, find 本来就会搜寻次目录,这个特色也要特别注意喔! 最后,我们再来看一下 find 还有什么特殊功能吧!

选项与参数:
4. 额外可进行的动作:
   -exec command :command 为其他命令,-exec 后面可再接额外的命令来处理搜寻到
                   的结果。
   -print        :将结果列印到萤幕上,这个动作是默认动作!

范例八:将上个范例找到的文件使用 ls -l 列出来~
[root@www ~]# find / -perm +7000 -exec ls -l {} \;
# 注意到,那个 -exec 后面的 ls -l 就是额外的命令,命令不支持命令别名,
# 所以仅能使用 ls -l 不可以使用 ll 喔!注意注意!

范例九:找出系统中,大於 1MB 的文件
[root@www ~]# find / -size +1000k
# 虽然在 man page 提到可以使用 M 与 G 分别代表 MB 与 GB,
# 不过,俺却试不出来这个功能~所以,目前应该是仅支持到 c 与 k 吧!

find 的特殊功能就是能够进行额外的动作(action)。我们将范例八的例子以图解来说明如下:

find_exec

该范例中特殊的地方有 {} 以及 ; 还有 -exec 这个关键字,这些东西的意义为:

  • {} 代表的是『由 find 找到的内容』,如上图所示,find 的结果会被放置到 {} 位置中;
  • -exec 一直到 ; 是关键字,代表 find 额外动作的开始 (-exec) 到结束 (;) ,在这中间的就是 find 命令内的额外动作。 在本例中就是『 ls -l {} 』罗!
  • 因为『 ; 』在 bash 环境下是有特殊意义的,因此利用反斜线来转义。

如果你要找的文件是具有特殊属性的,例如 SUID 、文件拥有者、文件大小等等, 那么利用 locate 是没有办法达成你的搜寻的!此时 find 就显的很重要啦! 另外,find 还可以利用万用字节来找寻档名呢!举例来说,你想要找出 /etc 底下档名包含 httpd 的文件, 那么你就可以这样做:

[root@www ~]# find /etc -name '*httpd*'

不但可以指定搜寻的目录(连同次目录),并且可以利用额外的选项与参数来找到最正确的文件名!真是好好用! 不过由於 find 在寻找数据的时后相当的操硬盘!所以没事情不要使用 find 啦!有更棒的命令可以取代呦!那就是上面提到的 whereis 与 locate 罗!

git版本控制文件状态简览

git status 命令的输出十分详细,但其用语有些繁琐。 如果你使用 git status -s 命令或 git status --short 命令,你将得到一种更为紧凑的格式输出。 运行 git status -s ,状态报告输出如下:

$ git status -s
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt

新添加的未跟踪文件前面有 ?? 标记

新添加到暂存区中的文件前面有 A 标记

修改过的文件前面有 M 标记。 你可能注意到了 M 有两个可以出现的位置,出现在右边M 表示该文件被修改了但是还没放入暂存区,出现在靠左边M 表示该文件被修改了并放入了暂存区。

例如,上面的状态报告显示: README 文件在工作区被修改了但是还没有将修改后的文件放入暂存区,lib/simplegit.rb 文件被修改了并将修改后的文件放入了暂存区。 而 Rakefile 在工作区被修改并提交到暂存区后又在工作区中被修改了,所以在暂存区和工作区都有该文件被修改了的记录。

Centos配置静态IP地址、DNS、网关

获取网络设备名称

由于默认安装时,dhcp自动获得ip,查看系统的ip,类似如下: (这步比较关键,找到对应的网络设备和配置文件)

[root@xxx ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 08:00:27:C1:E4:3D 
    inet addr:192.168.0.103  Bcast:192.168.0.255 Mask:255.255.255.0
    inet6 addr: fe80::a00:27ff:fec1:e43d/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:108 errors:0 dropped:0 overruns:0 frame:0
    TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000 
    RX bytes:12689 (12.3 KiB) TX bytes:5908 (5.7 KiB)

lo Link encap:Local Loopback 
    inet addr:127.0.0.1 Mask:255.0.0.0
    inet6 addr: ::1/128 Scope:Host
    UP LOOPBACK RUNNING MTU:16436 Metric:1
    RX packets:8 errors:0 dropped:0 overruns:0 frame:0
    TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0 
    RX bytes:480 (480.0 b) TX bytes:480 (480.0 b)

根据网络设备名找到相应的配置文件,并对它进行修改

根据上面输入的命令的出的结果,我们知道有两个设备,分别是eth0lo。那么在/etc/sysconfig/network-scripts/这个目录中存在这两个相对应的配置文件,名称分别是ifcfg-eth0ifcfg-lo。在这里我们要操作的文件是ifcfg-eth0,下面的操作都是围绕这个文件开展的。

通过vim修改网卡配置,编辑。命令如下。

vim /etc/sysconfig/network-scripts/ifcfg-eth0

常见的配置属性如下所示:

DEVICE=eth0
TYPE=Ethernet
UUID=3b632061-7971-4a7e-aeb3-55b288afd66d
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=dhcp
HWADDR=14:DD:A9:ED:1B:7F
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME="System eth0"
LAST_CONNECT=1440797869

常见属性说明

DEVICE=eth0 ##描述網卡對應的設備別名,例如ifcfg-eth0的文件中它爲eth0

BOOTPROTO=static ##設置網卡獲得ip地址的方式,可能的選項爲static,dhcp或bootp,分別對應靜態指定的ip地址,通過dhcp協議獲得的ip地址,通過bootp協議獲得的ip地址

BROADCAST=192.168.0.255 ##對應的子網廣播地址

HWADDR=00:07:E9:05:E8:B4 ##對應的網卡物理地址

IPADDR=192.168.1.2 ##如果設置網卡獲得 ip地址的方式爲靜態指定,此字段就指定了網卡對應的ip地址

NETMASK=255.255.255.0 ##網卡對應的網絡掩碼

NETWORK=192.168.1.0 ##網卡對應的網絡地址

ONBOOT=yes ##系統啓動時是否設置此網絡接口,設置爲yes時,系統啓動時激活此設備

修改后的配置

DEVICE=eth0
TYPE=Ethernet
UUID=3b632061-7971-4a7e-aeb3-55b288afd66d
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static  ##修改
IPADDR=192.168.0.124   ##新增
NETMASK=255.255.255.0  ##新增
DNS1=192.168.0.1       ##新增
GATEWAY=192.168.0.1    ##新增
HWADDR=14:DD:A9:ED:1B:7F
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME="System eth0"
LAST_CONNECT=1440797869

修改网关配置

编辑文件

vi /etc/sysconfig/network

在最下面增加一行:

GATWAY=192.168.0.1

修改DNS

编辑文件

vi /etc/resolv.conf

新增或修改后的文件如下所示:

nameserver 114.114.114.114      ##DNS首选地址
nameserver 202.96.134.133       ##DNS备用地址
search localdomain

重启网络服务

service network restart 

或者

/etc/init.d/network restart

相关链接

1.http://www.paipat.com/?post=47
2.http://www.itkee.com/os/detail-28a7.html
3.http://www.jbxue.com/LINUXjishu/14865.html

Linux下防火墙开启相关端口及查看已开启端口

在一台干净的服务器上使用OneinStack安装了java、tomcat、mysql环境。但是通过外网访问的时候,页面不能打开。经朋友指点是8080端口没有打开。

查看和打开8080端口的命令如下:

/sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT #开启8080端口 
/etc/rc.d/init.d/iptables save #保存配置 
/etc/rc.d/init.d/iptables restart #重启服务 

查看端口是否已经开放

/etc/init.d/iptables status 

其结果如下:

Table: filter
Chain INPUT (policy DROP)
num  target     prot opt source               destination         
1    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8080 
2    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
3    ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
4    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 
5    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:80 
6    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:443 
7    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           limit: avg 100/sec burst 100 
8    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           limit: avg 1/sec burst 10 
9    syn-flood  tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x17/0x02 
10   REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited

使用git pull文件时和本地文件冲突怎么办?

在使用git pull代码时,经常会碰到有冲突的情况,提示如下信息:

error: Your local changes to 'c/environ.c' would be overwritten by merge. Aborting.
Please, commit your changes or stash them before you can merge.

这个意思是说更新下来的内容和本地修改的内容有冲突,先提交你的改变或者先将本地修改暂时存储起来。

处理的方式非常简单,主要是使用git stash命令进行处理,分成以下几个步骤进行处理。

软件磁盘阵列(Software RAID)

什么是 RAID

磁盘阵列全名是『 Redundant Arrays of Inexpensive Disks, RAID 』,即容错式廉价磁盘阵列。 RAID 可以透过一个技术(软件或硬件),将多个较小的磁盘整合成为一个较大的磁盘装置; 而这个较大的磁盘功能可不止是储存而已,他还具有数据保护的功能呢。整个 RAID 由於选择的等级 (level) 不同,而使得整合后的磁碟具有不同的功能,基本常见的 level 有这几种。

  • RAID-0 (等量模式, stripe):效能最佳
  • RAID-1 (映射模式, mirror):完整备份
  • RAID 0+1,RAID 1+0 : 性能和安全兼顾
  • RAID 5:效能与数据备份的均衡考量
  • Spare Disk:预备磁碟的功能

磁盘阵列的优点

说的口沫横飞,重点在哪里呢?其实你的系统如果需要磁盘阵列的话,其实重点在于:

  • 数据安全与可靠性:指的并非资讯安全,而是当硬件 (指磁碟) 损毁时,数据是否还能够安全的救援或使用之意
  • 读写效能:例如 RAID 0 可以加强读写效能,让你的系统 I/O 部分得以改善
  • 容量:可以让多颗磁碟组合起来,故单一文件系统可以有相当大的容量

尤其数据的可靠性与完整性更是使用 RAID 的考量重点!毕竟硬件坏掉换掉就好了,软件数据损毁那可不是闹著玩的! 所以企业界为何需要大量的 RAID 来做为文件系统的硬件基准,现在您有点了解了吧?

软件磁盘阵列的配置

软件磁盘阵列的配置很简单呢!因为你只要使用一个命令即可!那就是 mdadm 这个命令。 这个命令在创建 RAID 的语法有点像这样:

[root@www ~]# mdadm --detail /dev/md0
[root@www ~]# mdadm --create --auto=yes /dev/md[0-9] --raid-devices=N \
> --level=[015] --spare-devices=N /dev/sdx /dev/hdx...
选项与参数:
--create :为创建 RAID 的选项;
--auto=yes :决定创建后面接的软件磁盘阵列装置,亦即 /dev/md0, /dev/md1...
--raid-devices=N :使用几个磁碟 (partition) 作为磁盘阵列的装置
--spare-devices=N :使用几个磁碟作为备用 (spare) 装置
--level=[015] :配置这组磁盘阵列的等级。支持很多,不过建议只要用 0, 1, 5 即可
--detail :后面所接的那个磁盘阵列装置的详细资讯

上面的语法中,最后面会接许多的设备文件名,设备文件名可以是整个磁盘,例如 /dev/sdb , 也可以是分区,例如 /dev/sdb1 之类。不过,这些设备文件名的总数必须要等於 --raid-devices 与 --spare-devices 的个数总和才行!鸟哥利用我的测试机来建置一个 RAID 5 的软件磁盘阵列给您瞧瞧! 首先,将系统里面过去练习过而目前用不到的分区通通删除掉:

[root@www ~]# fdisk -l
Disk /dev/hda: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1          13      104391   83  Linux
/dev/hda2              14        1288    10241437+  83  Linux
/dev/hda3            1289        1925     5116702+  83  Linux
/dev/hda4            1926        5005    24740100    5  Extended
/dev/hda5            1926        2052     1020096   82  Linux swap / Solaris
/dev/hda6            2053        2302     2008093+  83  Linux
/dev/hda7            2303        2334      257008+  82  Linux swap / Solaris
/dev/hda8            2335        2353      152586   83  Linux
/dev/hda9            2354        2366      104391   83  Linux

[root@www ~]# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda2              9920624   3858800   5549756  42% /
/dev/hda1               101086     21408     74459  23% /boot
tmpfs                   371332         0    371332   0% /dev/shm
/dev/hda3              4956316   1056996   3643488  23% /home
# 从上面可以发现,我的 /dev/hda6~/dev/hda9 没有用到!将他删除看看!

[root@www ~]# fdisk /dev/hda
Command (m for help): d
Partition number (1-9): 9

Command (m for help): d
Partition number (1-8): 8

Command (m for help): d
Partition number (1-7): 7

Command (m for help): d
Partition number (1-6): 6

Command (m for help): p

Disk /dev/hda: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1          13      104391   83  Linux
/dev/hda2              14        1288    10241437+  83  Linux
/dev/hda3            1289        1925     5116702+  83  Linux
/dev/hda4            1926        5005    24740100    5  Extended
/dev/hda5            1926        2052     1020096   82  Linux swap / Solaris

Command (m for help): w

[root@www ~]# partprobe
# 这个动作很重要!还记得吧!将核心的 partition table 升级!

底下是鸟哥希望做成的 RAID 5 环境:

  • 利用 4 个 partition 组成 RAID 5;
  • 每个 partition 约为 1GB 大小,需确定每个 partition 一样大较佳;
  • 利用 1 个 partition 配置为 spare disk
  • 这个 spare disk 的大小与其他 RAID 所需 partition 一样大!
  • 将此 RAID 5 装置挂载到 /mnt/raid 目录下

最终我需要 5 个 1GB 的 partition 。由于鸟哥的系统仅有一颗磁盘,这颗磁盘剩余容量约 20GB 是够用的, 分区代号仅使用到 5 号,所以要制作成 RAID 5 应该是不成问题!接下来就是连续的建置流程!

建置所需的磁碟装置

如前所述,我需要 5 个 1GB 的分区,请利用 fdisk 来建置吧!

[root@www ~]# fdisk /dev/hda
Command (m for help): n
First cylinder (2053-5005, default 2053): <==直接按下 [enter]
Using default value 2053
Last cylinder or +size or +sizeM or +sizeK (2053-5005, default 5005): +1000M
# 上述的动作请作五次!

Command (m for help): p

Disk /dev/hda: 41.1 GB, 41174138880 bytes
255 heads, 63 sectors/track, 5005 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1          13      104391   83  Linux
/dev/hda2              14        1288    10241437+  83  Linux
/dev/hda3            1289        1925     5116702+  83  Linux
/dev/hda4            1926        5005    24740100    5  Extended
/dev/hda5            1926        2052     1020096   82  Linux swap / Solaris
/dev/hda6            2053        2175      987966   83  Linux
/dev/hda7            2176        2298      987966   83  Linux
/dev/hda8            2299        2421      987966   83  Linux
/dev/hda9            2422        2544      987966   83  Linux
/dev/hda10           2545        2667      987966   83  Linux
# 上面的 6~10 号,就是我们需要的 partition 罗!

Command (m for help): w

[root@www ~]# partprobe

以 mdadm 建置 RAID

[root@www ~]# mdadm --create --auto=yes /dev/md0 --level=5 \
> --raid-devices=4 --spare-devices=1 /dev/hda{6,7,8,9,10}
# 详细的参数说明请回去前面看看罗!这里我透过 {} 将重复的项目简化!

    [root@www ~]# mdadm --detail /dev/md0
    /dev/md0:                                        <==RAID 设备文件名
            Version : 00.90.03
      Creation Time : Tue Mar 10 17:47:51 2009       <==RAID 被创建的时间
         Raid Level : raid5                          <==RAID 等级为 RAID 5
         Array Size : 2963520 (2.83 GiB 3.03 GB)     <==此 RAID 的可用磁盘容量
      Used Dev Size : 987840 (964.85 MiB 1011.55 MB) <==每个装置的可用容量
       Raid Devices : 4                              <==用作 RAID 的装置数量
      Total Devices : 5                              <==全部的装置数量
    Preferred Minor : 0
        Persistence : Superblock is persistent

        Update Time : Tue Mar 10 17:52:23 2009
              State : clean
     Active Devices : 4                              <==启动的(active)装置数量
    Working Devices : 5                              <==可动作的装置数量
     Failed Devices : 0                              <==出现错误的装置数量
      Spare Devices : 1                              <==预备磁盘的数量

             Layout : left-symmetric
         Chunk Size : 64K      <==就是图2.1.4内的小区块

               UUID : 7c60c049:57d60814:bd9a77f1:57e49c5b <==此装置(RAID)识别码
             Events : 0.2

        Number   Major   Minor   RaidDevice State
           0       3        6        0      active sync   /dev/hda6
           1       3        7        1      active sync   /dev/hda7
           2       3        8        2      active sync   /dev/hda8
           3       3        9        3      active sync   /dev/hda9

           4       3       10        -      spare   /dev/hda10
    # 最后五行就是这五个装置目前的情况,包括四个 active sync 一个 spare !
    # 至於 RaidDevice  指的则是此 RAID 内的磁碟顺序

由於磁盘阵列的构建需要一些时间,所以你最好等待数分钟后再使用『 mdadm --detail /dev/md0 』去查阅你的磁盘阵列详细信息! 否则有可能看到某些磁盘正在『spare rebuilding』之类的建置字样!透过上面的命令, 你就能够创建一个 RAID5 且含有一颗 spare disk 的磁盘阵列罗!非常简单吧! 除了命令之外,你也可以查阅如下的文件来看看系统软件磁盘阵列的情况:

[root@www ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 hda9[3] hda10[4](S) hda8[2] hda7[1] hda6[0]    <==第一行
      2963520 blocks level 5, 64k chunk, algorithm 2 [4/4] [UUUU] <==第二行

unused devices: <none>

上述的数据比较重要的在特别指出的第一行与第二行部分

  • 第一行部分:指出 md0 为 raid5 ,且使用了 hda9, hda8, hda7, hda6 等四颗磁碟装置。每个装置后面的中括号 [] 内的数字为此磁碟在 RAID 中的顺序 (RaidDevice);至於 hda10 后面的 [S] 则代表 hda10 为 spare 之意。
  • 第二行:此磁盘阵列拥有 2963520 个block(每个 block 单位为 1K),所以总容量约为 3GB, 使用 RAID 5 等级,写入磁碟的小区块 (chunk) 大小为 64K,使用 algorithm 2 磁盘阵列演算法。 [m/n] 代表此阵列需要 m 个装置,且 n 个装置正常运行。因此本 md0 需要 4 个装置且这 4 个装置均正常运行。 后面的 [UUUU] 代表的是四个所需的装置 (就是 [m/n] 里面的 m) 的启动情况,U 代表正常运行,若为 _ 则代表不正常。

这两种方法都可以知道目前的磁盘阵列状态啦!

格式化与挂载使用 RAID

[root@www ~]# mkfs -t ext3 /dev/md0
# 有趣吧!是 /dev/md0 做为装置被格式化呢!

[root@www ~]# mkdir /mnt/raid
[root@www ~]# mount /dev/md0 /mnt/raid
[root@www ~]# df
Filesystem     1K-blocks      Used Available Use% Mounted on
/dev/hda2        9920624   3858820   5549736  42% /
/dev/hda1         101086     21408     74459  23% /boot
tmpfs             371332         0    371332   0% /dev/shm
/dev/hda3        4956316   1056996   3643488  23% /home
/dev/md0         2916920     69952   2698792   3% /mnt/raid
# 看吧!多了一个 /dev/md0 的装置,而且真的可以让你使用呢!还不赖!

模拟 RAID 错误的救援模式

俗话说『天有不测风云、人有旦夕祸福』,谁也不知道你的磁盘阵列内的装置啥时会出差错,因此, 了解一下软件磁盘阵列的救援还是必须的!底下我们就来玩一玩救援的机制吧!首先来了解一下 mdadm 这方面的语法:

[root@www ~]# mdadm --manage /dev/md[0-9] [--add 装置] [--remove 装置] \
> [--fail 装置] 
选项与参数:
--add :会将后面的装置加入到这个 md 中!
--remove :会将后面的装置由这个 md 中移除
--fail :会将后面的装置配置成为出错的状态

配置磁碟为错误 (fault)

首先,我们来处理一下,该如何让一个磁碟变成错误,然后让 spare disk 自动的开始重建系统呢?

#0. 先复制一些东西到 /mnt/raid 去,假设这个 RAID 已经在使用了
[root@www ~]# cp -a /etc /var/log /mnt/raid
[root@www ~]# df /mnt/raid ; du -sm /mnt/raid/*
Filesystem   1K-blocks      Used Available Use% Mounted on
/dev/md0       2916920    188464   2580280   7% /mnt/raid
118     /mnt/raid/etc <==看吧!确实有数据在里面喔!
8       /mnt/raid/log
1       /mnt/raid/lost+found

#1. 假设 /dev/hda8 这个装置出错了!实际模拟的方式:
[root@www ~]# mdadm --manage /dev/md0 --fail /dev/hda8
mdadm: set /dev/hda8 faulty in /dev/md0

[root@www ~]# mdadm --detail /dev/md0
....(前面省略)....
          State : clean, degraded, recovering
 Active Devices : 3
Working Devices : 4
 Failed Devices : 1  <==出错的磁碟有一个!
  Spare Devices : 1
....(中间省略)....
    Number   Major   Minor   RaidDevice State
       0       3        6        0      active sync   /dev/hda6
       1       3        7        1      active sync   /dev/hda7
       4       3       10        2      spare rebuilding   /dev/hda10
       3       3        9        3      active sync   /dev/hda9

       5       3        8        -      faulty spare   /dev/hda8
# 看到没!这的动作要快做才会看到! /dev/hda10 启动了而 /dev/hda8 死掉了

[root@www ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 hda9[3] hda10[4] hda8[5](F) hda7[1] hda6[0]
      2963520 blocks level 5, 64k chunk, algorithm 2 [4/3] [UU_U]
      [>.......]  recovery =  0.8% (9088/987840) finish=14.3min speed=1136K/sec

上面的画面你得要快速的连续输入那些 mdadm 的命令才看的到!因为你的 RAID 5 正在重建系统! 若你等待一段时间再输入后面的观察命令,则会看到如下的画面了:

#2. 已经藉由 spare disk 重建完毕的 RAID 5 情况
[root@www ~]# mdadm --detail /dev/md0
....(前面省略)....
    Number   Major   Minor   RaidDevice State
       0       3        6        0      active sync   /dev/hda6
       1       3        7        1      active sync   /dev/hda7
       2       3       10        2      active sync   /dev/hda10
       3       3        9        3      active sync   /dev/hda9

       4       3        8        -      faulty spare   /dev/hda8

[root@www ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 hda9[3] hda10[2] hda8[4](F) hda7[1] hda6[0]
      2963520 blocks level 5, 64k chunk, algorithm 2 [4/4] [UUUU]

看吧!又恢复正常了!真好!我们的 /mnt/raid 文件系统是完整的!并不需要卸载!

将出错的磁碟移除并加入新磁盘

首先,我们再创建一个新的分区,这个分区要与其他分区一样大才好!然后再利用 mdadm 移除错误的并加入新的!

#3. 创建新的分区
[root@www ~]# fdisk /dev/hda
Command (m for help): n
First cylinder (2668-5005, default 2668): <==这里按 [enter]
Using default value 2668
Last cylinder or +size or +sizeM or +sizeK (2668-5005, default 5005): +1000M

Command (m for help): w

[root@www ~]# partprobe
# 此时系统会多一个 /dev/hda11 的分区!

#4. 加入新的拔除有问题的磁盘
[root@www ~]# mdadm --manage /dev/md0 --add /dev/hda11 --remove /dev/hda8
mdadm: added /dev/hda11
mdadm: hot removed /dev/hda8

[root@www ~]# mdadm --detail /dev/md0
....(前面省略)....
       0       3        6        0      active sync   /dev/hda6
       1       3        7        1      active sync   /dev/hda7
       2       3       10        2      active sync   /dev/hda10
       3       3        9        3      active sync   /dev/hda9

       4       3       11        -      spare   /dev/hda11

嘿嘿!你的磁盘阵列内的数据不但一直存在,而且你可以一直顺利的运行 /mnt/raid 内的数据,即使 /dev/hda8 损毁了!然后透过管理的功能就能够加入新磁碟且拔除坏掉的磁碟!注意,这一切都是在上线 (on-line) 的情况下进行。

启动自动启动 RAID 并自动挂载

新的 distribution 大多会自己搜寻 /dev/md[0-9] 然后在启动的时候给予配置好所需要的功能。不过鸟哥还是建议你, 修改一下配置文件吧! 。software RAID 也是有配置文件的,这个配置档在 /etc/mdadm.conf !这个配置档内容很简单, 你只要知道 /dev/md0 的 UUID 就能够配置这个文件啦!这里鸟哥仅介绍他最简单的语法:

[root@www ~]# mdadm --detail /dev/md0 | grep -i uuid
        UUID : 7c60c049:57d60814:bd9a77f1:57e49c5b
# 后面那一串数据,就是这个装置向系统注册的 UUID 识别码!

# 开始配置 mdadm.conf
[root@www ~]# vi /etc/mdadm.conf
ARRAY /dev/md0 UUID=7c60c049:57d60814:bd9a77f1:57e49c5b
#     RAID装置      识别码内容

# 开始配置启动自动挂载并测试
[root@www ~]# vi /etc/fstab
/dev/md0    /mnt/raid    ext3    defaults     1 2

[root@www ~]# umount /dev/md0; mount -a
[root@www ~]# df /mnt/raid
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/md0               2916920    188464   2580280   7% /mnt/raid
# 你得确定可以顺利挂载,并且没有发生任何错误!

如果到这里都没有出现任何问题!接下来就请 reboot 你的系统并等待看看能否顺利的启动吧!

关闭软件 RAID(重要!)

除非你未来就是要使用这块 software RAID (/dev/md0),否则你势必要跟鸟哥一样,将这个 /dev/md0 关闭! 因为他毕竟是我们在这个测试机上面的练习装置啊!为什么要关掉他呢?因为这个 /dev/md0 其实还是使用到我们系统的磁盘分区, 在鸟哥的例子里面就是 /dev/hda{6,7,8,9,10,11},如果你只是将 /dev/md0 卸载,然后忘记将 RAID 关闭, 结果就是....未来你在重新分割 /dev/hdaX 时可能会出现一些莫名的错误状况啦!所以才需要关闭 software RAID 的步骤! 那如何关闭呢?也是简单到爆炸!(请注意,确认你的 /dev/md0 确实不要用且要关闭了才进行底下的玩意儿)

#1. 先卸载且删除配置档内与这个 /dev/md0 有关的配置:
[root@www ~]# umount /dev/md0
[root@www ~]# vi /etc/fstab
/dev/md0    /mnt/raid     ext3    defaults      1 2
# 将这一行删除掉!或者是注解掉也可以!

#2. 直接关闭 /dev/md0 的方法!
[root@www ~]# mdadm --stop /dev/md0
mdadm: stopped /dev/md0  <==不罗唆!这样就关闭了!

[root@www ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
unused devices: <none>  <==看吧!确实不存在任何阵列装置!

[root@www ~]# vi /etc/mdadm.conf
ARRAY /dev/md0 UUID=7c60c049:57d60814:bd9a77f1:57e49c5b
# 一样啦!删除他或是注解他!

PS:在这个练习中,鸟哥使用同一颗磁碟进行软件 RAID 的实验。不过朋友们要注意的是,如果真的要实作软件磁盘阵列, 最好是由多颗不同的磁碟来组成较佳!因为这样才能够使用到不同磁碟的读写,效能才会好! 而数据分配在不同的磁碟,当某颗磁碟损毁时数据才能够藉由其他磁碟挽救回来!这点得特别留意呢!

循环执行的例行性工作调度(crontab命令的使用)

当使用者使用 crontab 这个指令来建立工作调度之后,该项工作就会被纪录到 /var/spool/cron/ 里面去了,而且是以帐号来作为判别的喔!举例来说, dmtsai 使用 crontab 后, 他的工作会被纪录到 /var/spool/cron/dmtsai 里头去!但请注意,不要使用 vi 直接编辑该档案, 因为可能由于输入语法错误,会导致无法执行 cron 喔!另外, cron 执行的每一项工作都会被纪录到 /var/log/cron 这个登录档中,所以啰,如果你的 Linux 不知道有否被植入木马时,也可以搜寻一下 /var/log/cron 这个登录日志呢!

好了,那么我们就来聊一聊 crontab 的语法吧!

[root@www ~]# crontab [-u username] [-l|-e|-r]
选项与参数:
-u  :只有 root 才能进行这个任务,亦即帮其他使用者建立/移除 crontab 工作排程;
-e  :编辑 crontab 的工作内容
-l  :查阅 crontab 的工作内容
-r  :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑。

范例一:用 dmtsai 的身份在每天的 12:00 发信给自己
[dmtsai@www ~]$ crontab -e
# 此时会进入 vi 的编辑画面让您编辑工作!注意到,每项工作都是一行。
0   12  *  *  * mail dmtsai -s "at 12:00" < /home/dmtsai/.bashrc
#分 时 日 月 周 |<==============指令串========================>|

预设情况下,任何使用者只要不被列入 /etc/cron.deny 当中,那么他就可以直接下达‘ crontab -e ’去编辑自己的例行性命令了!整个过程就如同上面提到的,会进入 vi 的编辑画面, 然后以一个工作一行来编辑,编辑完毕之后输入‘ :wq ’储存后离开 vi 就可以了! 而每项工作 (每行) 的格式都是具有六个栏位,这六个栏位的意义为:

代表意义 分钟 小时 日期 月份 命令
数字范围 0-59 0-23 1-31 1-12 0-7 要执行的命令

比较有趣的是那个‘周’喔!周的数字为 0 或 7 时,都代表‘星期天’的意思!另外, 还有一些辅助的字符,大概有底下这些:

特殊字符 代表意义
* 代表任何时刻都接受的意思!举例来说,范例一内那个日、月、周都是 * , 就代表着‘不论何月、何日的礼拜几的 12:00 都执行后续指令’的意思!
, 代表分隔时段的意思。举例来说,如果要下达的工作是 3:00 与 6:00 时,就会是: 0 3,6 * * * command 时间参数还是有五栏,不过第二栏是 3,6 ,代表 3 与 6 都适用
- 代表一段时间范围内,举例来说, 8 点到 12 点之间的每小时的 20 分都进行一项工作: 20 8-12 * * * command 仔细看到第二栏变成 8-12 喔!代表 8,9,10,11,12 都适用的意思!
/n 那个 n 代表数字,亦即是‘每隔 n 单位间隔’的意思,例如每五分钟进行一次,则:*/5 * * * * command 很简单吧!用 * 与 /5 来搭配,也可以写成 0-59/5 ,相同意思!

javascript变量声明提升(hoisting)

hoisting机制

javascript的变量声明具有hoisting机制JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。

先看一段代码

var v = "hello";
(function(){
  console.log(v);
  var v = "world";
})();

这段代码运行的结果是什么呢?
答案是:undefined
这段代码说明了两个问题,
第一,function作用域里的变量v遮盖了上层作用域变量v。代码做少些变动

var v = "hello";
if(true){
  console.log(v);
  var v = "world";
}    

输出结果为”hello”,说明javascript是没有块级作用域的。函数是JavaScript中唯一拥有自身作用域的结构

第二,在function作用域内,变量v的声明被提升了。所以最初的代码相当于:

var v = "hello";
(function(){
  var v; //declaration hoisting
  console.log(v);
  v = "world";
})();    

声明、定义与初始化

声明宣称一个名字的存在,定义则为这个名字分配存储空间,而初始化则是为名字分配的存储空间赋初值。
用C++来表述这三个概念

extern int i;//这是声明,表明名字i在某处已经存在了
int i;//这是声明并定义名字i,为i分配存储空间
i = 0;//这是初始化名字i,为其赋初值为0

javascript中则是这样

var v;//声明变量v
v = "hello";//(定义并)初始化变量v

因为javascript为动态语言,其变量并没有固定的类型,其存储空间大小会随初始化与赋值而变化,所以其变量的“定义”就不像传统的静态语言一样了,其定义显得无关紧要。

声明提升

当前作用域内的声明都会提升到作用域的最前面,包括变量和函数的声明

(function(){
  var a = "1";
  var f = function(){};
  var b = "2";
  var c = "3";
})();    

变量a,f,b,c的声明会被提升到函数作用域的最前面,类似如下:

(function(){
  var a,f,b,c;
  a = "1";
  f = function(){};
  b = "2";
  c = "3";
})();

请注意函数表达式并没有被提升,这也是函数表达式与函数声明的区别。进一步看二者的区别:

(function(){
  //var f1,function f2(){}; //hoisting,被隐式提升的声明

  f1(); //ReferenceError: f1 is not defined
  f2();

  var f1 = function(){};
  function f2(){}
})();    

上面代码中函数声明f2被提升,所以在前面调用f2是没问题的。虽然变量f1也被提升,但f1提升后的值为undefined,其真正的初始值是在执行到函数表达式处被赋予的。所以只有声明是被提升的。

名字解析顺序

javascript中一个名字(name)以四种方式进入作用域(scope),其优先级顺序如下:
1、语言内置:所有的作用域中都有 this 和 arguments 关键字
2、形式参数:函数的参数在函数作用域中都是有效的
3、函数声明:形如function foo() {}
4、变量声明:形如var bar;

名字声明的优先级如上所示,也就是说如果一个变量的名字与函数的名字相同,那么函数的名字会覆盖变量的名字,无论其在代码中的顺序如何。但名字的初始化却是按其在代码中书写的顺序进行的,不受以上优先级的影响。看代码:

(function(){
    var foo;
    console.log(typeof foo); //function

    function foo(){}

    foo = "foo";
    console.log(typeof foo); //string
})();    

如果形式参数中有多个同名变量,那么最后一个同名参数会覆盖其他同名参数,即使最后一个同名参数并没有定义。

以上的名字解析优先级存在例外,比如可以覆盖语言内置的名字arguments。

命名函数表达式

可以像函数声明一样为函数表达式指定一个名字,但这并不会使函数表达式成为函数声明。命名函数表达式的名字不会进入名字空间,也不会被提升。

f();//TypeError: f is not a function
foo();//ReferenceError: foo is not defined
var f = function foo(){console.log(typeof foo);};
f();//function
foo();//ReferenceError: foo is not defined

命名函数表达式的名字只在该函数的作用域内部有效。

CentOS三套菜鸟硬盘分区方案

方案1

/ :建议大小在5GB以上。
swap:即交换分区,建议大小是物理内存的1~2倍。

这种适合初次安装和接触Linux的人。设置完成swap后,把剩下所有的空间都给/根目录,缺点就是比较粗糙,优点是不怕分区错误造成无法安装的困境。

方案2

/boot:用来存放与Linux系统启动有关的程序,比如启动引导装载程序等,建议大小为200MB左右。
/ :Linux系统的根目录,所有的目录都挂在这个目录下面,建议大小为5GB以上。
/home:存放普通用户的数据,是普通用户的宿主目录,建议大小为剩下的空间。
swap:实现虚拟内存,建议大小是物理内存的1~2倍。

这种分区方案应该说是最普遍的了,难易度为中,我的实战经验是一般把/boot设置为200M-500M。虽然实际用不到这么多空间,但是现在硬盘白菜价,多加点图个安慰。'/'目录我一般设置的大小和'/home'差不多,5GB有点太小了,毕竟后期/usr, /var中会占掉一部分空间,而且是递增的趋势,所以建议设置的大一点。我一般那100G的空间给/使用。然后设置swap,大小是物理内存的1~2倍。剩下的的空间都给用户目录,即/home

方案3

/boot:用来存放与Linux系统启动有关的程序,比如启动引导装载程序等,建议大小为100MB。
/usr :用来存放Linux系统中的应用程序,其相关数据较多,建议大于3GB以上。
/var :用来存放Linux系统中经常变化的数据以及日志文件,建议大于1GB以上。
/home:存放普通用户的数据,是普通用户的宿主目录,建议大小为剩下的空间。
/ :Linux系统的根目录,所有的目录都挂在这个目录下面,建议大小为5GB以上。
/tmp:将临时盘在独立的分区,可避免在文件系统被塞满时影响到系统的稳定性。建议大小为500MB以上。
swap:实现虚拟内存,建议大小是物理内存的1~2倍。

这种方案应该是最仔细的了,各个方面都考虑到了。由于/usr/var空间的不确定性,前期一般都要分大一点,防止后期空间被占满。我实战的时候/user/var,可虑10G+,剩下的分给/home/

注意

在分区中/boot、/、等都是相关挂载点,设置的方式一般如下所示:

9833665-554acab91a0dc_articlex

但是,swap设置还是比较奇葩的。它没有相应的挂载点。设置的方式如下:

3324253828-554acb18031f6_articlex

此文章用来自己对linux系统的理解,有错恳请指教,不喜勿喷。

GitLab 配置通过 smtp.163.com 发送邮件

配置SMTP发送邮件配置,使用163邮箱。

$ sudo vi /etc/gitlab/gitlab.rb                            
# Change the external_url to the address your users will type in their browser
external_url 'http://xxhost.com'

#Sending application email via SMTP
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.163.com"
gitlab_rails['smtp_port'] = 25 
gitlab_rails['smtp_user_name'] = "[email protected]"
gitlab_rails['smtp_password'] = "xxpassword"
gitlab_rails['smtp_domain'] = "163.com"
gitlab_rails['smtp_authentication'] = :login
gitlab_rails['smtp_enable_starttls_auto'] = true

发送不成功,·sudo gitlab-ctl tail`检查日志报错如下:

WARN: {"retry"=>true, "queue"=>"default",
"class"=>"Sidekiq::Extensions::DelayedMailer",
"args"=>["---\n- !ruby/class 'Notify'\n- :project_access_granted_email\n- - 4\n"], 
"jid"=>"061604dc558ce8560b273cbe", "enqueued_at"=>1405094359.354158, 
"error_message"=>"553 Mail from must equal authorized user\n", 
"error_class"=>"Net::SMTPFatalError", }

错误原因:网易服务器smtp机器要求身份验证帐号和发信帐号必须一致,如果用户在发送邮件时,身份验证帐号和发件人帐号是不同的,因此拒绝发送。

修改gitlab.rb,修改发信人和身份验证帐号一致,163发信OK。

$ sudo vi /etc/gitlab/gitlab.rb                            
# Change the external_url to the address your users will type in their browser
external_url 'http://xxhost.com'

#Sending application email via SMTP
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.163.com"
gitlab_rails['smtp_port'] = 25 
gitlab_rails['smtp_user_name'] = "[email protected]"
gitlab_rails['smtp_password'] = "xxpassword"
gitlab_rails['smtp_domain'] = "163.com"
gitlab_rails['smtp_authentication'] = :login
gitlab_rails['smtp_enable_starttls_auto'] = true

##修改gitlab配置的发信人
gitlab_rails['gitlab_email_from'] = "[email protected]"  (新增)
user["git_user_email"] = "[email protected]"   (新增)

CentOS6.2系统系统日志rsyslog替换默认的日志服务syslog

最近遇到配置centos 6.2的sshd及sftp日志,发现/etc/syslog.conf文件不存在,然后执行下面命令:

#rpm -qa | grep syslog

出来的结果

rsyslog-5.8.10-6.el6.x86_64

然后查看rsyslog配置文件:

cat /etc/rsyslog.conf

出来的内容几乎和以前的/etc/syslog.conf类似,然后百度,Google得出的结论是:

Rsyslog可作为系统自带产品syslog的替代品,目前fedra等多种Unix/Linux系列操作系统已经正式将rsyslog替换掉系统自带的syslog,所以CentOS 6以上版本都直接采用了rsyslog作为系统的日志服务。那它有什么特性呢?

  • 后端存查日志支持的客户端多支持MySQL、PostgresSQL、Oracle 等
  • 在同一台机器上支持多子rsyslog进程,可以监听在不同端口
  • 直接兼容系统自带的syslog.conf配置文件
  • 可将消息过来后再次转发
  • 配置文件中可以写简单的逻辑判断
  • 有现成的前端web展示程序

等等。

另外和rsyslog功能差不多还有syslog-ng,但是syslog-ng免费版本是闭源。

其次下面是整理的系统默认的日志分类记录文件说明:

1./var/log/lastlog
记录每个用户最近登录系统的时间, 可以通过lastlog指令读取

2./var/run/utmp
记录每个用户登录系统的时间, who、 users、finger 等指令会查这个文件

3./var/log/wtmp
记录每个用户登入与登出的时间, last这个指令会查这个文件。这个文件也记录 shutdown及reboot的动作

4./var/log/secure
ssh登录的记录信息包括失败的记录信息,可以通过查看些日志查看机器是否被人扫描

5./var/log/maillog
记录sendmail及pop等相关讯息

6./var/log/cron
记录crontab的相关信息

7./var/log/dmesg
dmesg会将这个文件显示出来,它是开机时的系统自检的信息,同时也会记录硬件错误信息

8./var/log/xferlog
记录ftp相关的日志信息

9./var/log/messages
系统大部份的日志信息,包括login、check password、failed login、ftp、su等等

最后修改了/etc/ssh/sshd_config,/etc/rsyslog.conf 还是老套路:

#/etc/init.d/rsyslog restart
#/etc/init.d/sshd restart

Ubuntu服务器常用配置-SSH的配置

SSH基础介绍

SSH是指Secure Shell,是一种安全的传输协议,Ubuntu客户端可以通过SSH访问远程服务器 。SSH的简介和工作机制可参看上篇文章 SSH简介及工作机制

SSH分客户端openssh-client和服务器端openssh-server。如果你只是想登陆别的机器的SSH只需要安装openssh-client(ubuntu有默认安装,如果没有则sudoapt-get install openssh-client),如果要使本机开放SSH服务就需要安装openssh-server

安装客户端(openssh-client)

Ubuntu默认已经安装了客户端openssh-client。如果没有安装的话,那么可以通过下面的命令进行安装。

sudo apt-get install ssh  或 sudo apt-get install openssh-client
ssh-keygen (**按缺省生成id_rsa和id_rsa.pub文件,分别是私钥和公钥**)

PS:如果sudo apt-get insall ssh出错无法安装,则可使用sudo apt-get install openssh-client进行安装。

假定服务器ip为192.168.1.1,ssh服务的端口号为22,服务器上有个用户为root;
用ssh登录服务器的命令为:

>ssh –p 22 [email protected]
>输入root用户的密码

安装服务端(openssh-server)

Ubuntu默认没有安装SSH Server,使用以下命令安装:

sudo apt-get install openssh-server

然后确认sshserver是否启动了:(或用“netstat -tlp”命令)

如果只有ssh-agent那ssh-server还没有启动,需要/etc/init.d/ssh start,如果看到sshd那说明ssh-server已经启动了。如果没有则可以这样启动:

sudo /etc/init.d/ssh start

事实上如果没什么特别需求,到这里 OpenSSH Server 就算安装好了。但是进一步设置一下,可以让 OpenSSH 登录时间更短,并且更加安全。这一切都是通过修改 openssh 的配置文件 sshd_config 实现的。

SSH配置

ssh-server配置文件位于/etc/ssh/sshd_config,在这里可以定义SSH的服务端口,默认端口是22,你可以自己定义成其他端口号,如222。然后重启SSH服务,重启的命令如下:

sudo /etc/init.d/ssh resart  

通过修改配置文件/etc/ssh/sshd_config,可以改ssh登录端口和禁止root登录。改端口可以防止被端口扫描

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.original  (**修改配置时最好进行备份**)
sudo chmod a-w /etc/ssh/sshd_config.original  (**禁止写权限,最大程度保护备份文件**)

编辑配置文件命令:

gedit 或 vim /etc/ssh/sshd_config

找到#Port 22,去掉注释,修改成一个五位的端口:Port 22333 (修改端口)
找到#PermitRootLogin yes,去掉注释,修改为:PermitRootLogin no (禁止root登录)

配置完成后重起,重启命令如下:

sudo /etc/init.d/ssh restart 

随便说下,停止ssh的命令如下:

sudo /etc/init.d/ssh stop

SSH服务命令总结

停止服务:sudo /etc/init.d/ssh stop

启动服务:sudo /etc/init.d/ssh start

重启服务:sudo /etc/init.d/ssh resart

断开连接:exit

SSH登录命令

常用格式:ssh [-l login_name] [-p port] [user@]hostname

不指定用户:

ssh 192.168.0.1

指定用户:

ssh -l root 192.168.0.1  
ssh [email protected] 

如果修改过ssh登录端口的可以:

ssh -p 22333 192.168.0.111  
ssh -l root -p 22333 216.230.230.105  
ssh -p 22333 [email protected]     

提高登录速度

在远程登录的时候可能会发现,在输入完用户名后需要等很长一段时间才会提示输入密码。其实这是由于 sshd 需要反查客户端的 dns 信息导致的。可以通过禁用这个特性来大幅提高登录的速度。首先,打开 sshd_config 文件:

sudo vim /etc/ssh/sshd_config 

找到 GSSAPI options 这一节,将下面两行注释掉:

#GSSAPIAuthentication yes 
#GSSAPIDelegateCredentials no

然后重新启动 ssh 服务即可。

Nginx指令介绍

该文章主要用来介绍nginx常用之类。指令是nginx配置文件中相当重要的组成单元。

Linux工作调度的种类: at、cron

Linux工作调度的有以下的两种调度方式:

  • 一种是例行性的,就是每隔一定的周期要来办的事项;
  • 一种是突发性的,就是这次做完以后就没有的哪一种。(如计算机大降价)

这两种方式分别对应了linux中at与crontab这两个命令

  • at: at是个可以处理仅执行一次就结束调度的命令,不过要执行at时,必须要有atd这个服务的支持才行。在某些新版的发行版中,atd可能默认并没有启动,那么at这个命令就会失效。
  • crontab: crontab这个命令所设置的工作将会循环一直进行下去。可循环的时间为分钟、小时、每周、每月或每年等。crontab除了可以使用命令执行外,也可编辑/etc/crontab来支持。至于让crontab可以生效的服务则是crond这个命令。

git中通过gitignore文件指定要忽略不进行版本管理的文件

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件模式。 来看一个实际的例子:

$ cat .gitignore
*.[oa]
*~

第一行告诉 Git 忽略所有以 .o.a 结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。 第二行告诉 Git 忽略所有以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存副本。 此外,你可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。 要养成一开始就设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。

文件 .gitignore 的格式规范如下:

  • 所有空行或者以 # 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配。
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。

所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。 星号(*)匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。 使用两个星号(*) 表示匹配任意中间目录,比如a/**/z 可以匹配 a/z, a/b/z 或 a/b/c/z等。

我们再看一个 .gitignore 文件的例子:

# no .a files
*.a

# but do track lib.a, even though you're ignoring .a files above
!lib.a

# only ignore the TODO file in the current directory, not subdir/TODO
/TODO

# ignore all files in the build/ directory
build/

# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt

# ignore all .pdf files in the doc/ directory
doc/**/*.pdf

GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表,你可以在 https://github.com/github/gitignore 找到它.

CentOS如何将Web数据迁移至外挂的数据据盘中

暂停服务及创建目录

service nginx/httpd/tomcat stop ##停止服务器

service mysqld stop  ##停止mysql服务器

mv /data /root/  ##备份web应用、日志和mysql数据
ls /root/data    ##确保此目录有如下3个目mysql、 wwwlogs、wwwroot

mkdir /data    ##创建挂载目录

分区、格式化、挂载设备

分区、格式化

2
3
4

挂载

vim /etc/fstab  ##开机自动挂载,添加如下行

/dev/xvdb1 /data ext4 defaults 0 0

mount -a ##读取/etc/fstab挂载

5

数据恢复及权限设置

cp -R /root/data/*  /data/ ##恢复Web运用,日志和mysql数据到挂载目录下

chown -R mysql:mysql /data/mysql  ##设置数据库权限
chown -R www:www /data/wwwroot /data/wwwlogs ##设置网站和访问日志权限

重启服务

service mysqld start  ##启动数据库

service nginx/httpd/tomcat  start ##启动服务器

Linux系统bash关于减号-的作用

管道命令在bash的连续处理程序中是相当重要的,尤其在使用到前一个命令的studout(标准输出)作为这次的stdin(标准输入)时,就显得太重要了,某些命令需要用到 文件名 ,例如上篇文档的的切割命令(split)、还有tar(打包)命令等等!这时这个文件就承当studout或者stdin,这个时候这个studout或者stdin就可以用减号(-)来替代

实例一:使用ls -al /将输出的信息中,没3行记录成一个文件

[root@bogon bash]# ls -al / | split -l 3 - s
[root@bogon bash]# wc -l s*
  3 saa
  3 sab
  3 sac
  3 sad
  3 sae
  3 saf
  3 sag
  2 sah
  23 total

一般来说,如果需要stdout(标准输出)/stdin(标准输入),但偏偏又没有文件,有的只是“-”时,那么那个“-”就会被当做stdout或者stout

tar -cvf tarName.tar ./bash 本来是这样的,看我怎么用“-”来替他 文件 的标准输出

[root@bogon ~]# tar -cvf   ./bash
tar: Cowardly refusing to create an empty archive
Try `tar --help' or `tar --usage' for more information.
#这里报错了,没有办法,因为语法错误
[root@bogon ~]# tar -cvf  - ./bash 
./bash/
./bash/sag
./bash/saf
./bash/sae
./bash/aa.txt
./bash/sab
./bash/saa
./bash/sad
./bash/cc.txt
./bash/bb.txt
./bash/test.txt
.....

看到了没有这个时候用”-“替代了本来输出到文件,而标准输出到了屏幕

综合实例

[root@bogon ~]# tar -cvf - ./bash | tar -xvf -
./bash/
./bash/sag
./bash/saf
......!(省略)
./bash/saf
./bash/sah
./bash/sac
tar: ./bash: file changed as we read it
./bash/sae
.......!省略)
./bash/sah
./bash/sac

上面这个例子是说我将./bash这个文件打包,但是打包的文件不是记录到文件,而是传送到标准输出(stdout);经过管道后,将tar -cvf - ./bash传给后面的 tar -xvf -。后面这个“-”则是取用前面一个命令的stdout作为stdin,因此这里就不需要使用文件了,这是很常见的例子,因为我们写脚本的时候,就不要去写个临时文件了。

ejs模版的使用摘要

概述

ejs模版是我比较喜欢而且常用的模版引擎,一方面它的语法和java中的velocity相似,另一位方面完全把视图解耦出来,性能也比较出色,所以成为我模版选型的不二之选。

核心概念

我们先从一个简单的示例来看看ejs模版的用法吧。ejs模版的核心分别是模版、数据、和渲染。对应的代码分别如下:

数据

    var data = {
        title: "ejs模版测试"
    };

ejs模版使用的数据是标准的javascript对象,曾经视图传一个数组进去,但是渲染不出来。所以我们最好传一个Object对象给ejs模版引擎。

模版(view/title.ejs)

<h1 id="title"><%= title %></h1>     

模版是一个单独的ejs格式的文件,虽然这不是强制性的,但是结构一下清晰明了。模版里有它特殊的语法。比如:
<%= title %>的作用就是显示数据传递过来的title字段。

渲染

    var temp = new EJS({
        url : "view/title.ejs"
    }).render(data);  

ejs是通过调用render方法把数据传入模版引擎的。这也是连接数据与模版的桥梁。

完整的示例代码如下所示:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>ejs模版测试</title>
    <script type="text/javascript" src="lib/ejs.js"></script> <!--引入ejs核心文件-->
</head>
<body>
<h1 id="title"></h1>
<script>
    //模版需要用到的数据
    var data = {
        title: "ejs模版测试"
    };

    var title = document.getElementById('title');
    //模版渲染
    title.innerHTML = new EJS({
        url : "view/title.ejs"     //模版的地址
    }).render(data);
</script>
</body>
</html>

模版语法

简单的输出

<%= title %> //输出数据中title中对应的值的内容

循环

{   title:  'Cleaning Supplies'
    supplies:   ['mop', 'broom', 'duster']  
}

<% for(var i=0; i<supplies.length; i++) {%>
    <li><%= supplies[i] %></li>
<% } %>    

判断

    <% if ( defaultindex == "select") { %>
        <li class="active" %>"></li>
    <% } else { %>     //这里不能分开写
        <li></li>
    <% } %>

以上几种语法基本可以应付常用的结构了,当然我们还可以拓展。它向我们平常写脚本一样,只不过我们要主要不要出错。

核心API

render

/*第一次渲染的时候调用该方法,返回值是被数据填充的模版*/    
html = new EJS({url: '/template.ejs'}).render(data)      

update

/*当数据有更新的时候,调用update方法*/
new EJS({url: '/template.ejs'}).update(document.body, data2)    

拓展(view.js)

EJS官网除了提供其核心功能外,还提供了常用的标签的封装。
示例如下:

/*link_to封装了`a`标签*/
<ul>
<% for(var i=0; i<supplies.length; i++) {%>
    <li><%= link_to(supplies[i], 'supplies/'+supplies[i]) %></li>
<% } %>
</ul>


/*img_tag封装了img标签*/
<%= img_tag('images/maid.png') %>

高级特性

模版缓存

为了最大提高模版的性能,默认是开启了缓存的,所以遇到下面的代码,content.ejs模版只会被加载一次.

    <script type='text/javascript'>
        new EJS({url: 'templates/content.ejs'}).update('content1', {});
        new EJS({url: 'templates/content.ejs'}).update('content2', {});
    </script>

当然我们可以手动关闭缓存:

EJS.config({cache: false});

这样的话,如果遇到上面的代码,content.ejs会被加载两次。

模版嵌套

模版可以嵌套:示例如下:

<h2>This is from the containing template</h2>
<div class='template'>
    <%= this.partial({url: 'templates/partial.ejs'}) %>
</div>

该模版中包含一个子模版partial.ejs。这样对结构重用有很大的益处。

相关链接:

官网地址:http://www.embeddedjs.com/

linux命令usermod参数及用法详解

命令

usermod 

功能说明

修改用户帐号。

语法

usermod [-LU][-c <备注>][-d <登入目录>][-e <有效期限>][-f <缓冲天数>][-g <群组>][-G <群组>][-l <帐号名称>][-s <shell>][-u <uid>][用户帐号] 

补充说明:usermod可用来修改用户帐号的各项设定。

参数:

 -c<备注>  修改用户帐号的备注文字。

 -d<登入目录>  修改用户登入时的目录。

 -e<有效期限>  修改帐号的有效期限。

 -f<缓冲天数>  修改在密码过期后多少天即关闭该帐号。

 -g<群组>  修改用户所属的群组。

 -G<群组>  修改用户所属的附加群组。

 -l<帐号名称>  修改用户帐号名称。

 -L  锁定用户密码,使密码无效。

 -s  修改用户登入后所使用的shell。

 -u  修改用户ID。

 -U  解除密码锁定。

usermod 不 允 许 你 改 变 正 在线 上 的 使 用 者 帐 号 名 称 。 当 usermod 用 来 改 变 user ID, 必 须 确 认 这 名 user 没 在 电 脑 上 执 行 任 何 程 序。 你 需 手 动 更 改 使 用 者 的 crontab 档 。 也 需 手 动 更 改 使 用 者 的 at 工 作 档 。 采 用 NIS server 须 在 server 上 更 动 相 关 的 NIS 设 定 。

应用举例:

1、将 newuser2 添加到组 staff 中

# usermod -G staff newuser2 

2、修改 newuser 的用户名为 newuser1

# usermod -l newuser1 newuser 

3、锁定账号 newuser1

# usermod -L newuser1 

4、解除对 newuser1 的锁定

# usermod -U newuser1

在阿里云上通过Omnibus一键安装包安装Gitlab

假设使用的操作系统为CentOS6.5+,且最低硬件需求也符合要求,那么安装下面的操作要求安装,安装的Gitlab版本为8.1.0.

1.安装Gitlab所依赖的环境。操作命令如下所示:

sudo yum install curl openssh-server postfix cronie
sudo service postfix start
sudo chkconfig postfix on
sudo lokkit -s http -s ssh

2.下载GitLab安装包并安装,官网提供了两种方式,分别如下

方式一:

curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
sudo yum install gitlab-ce

鉴于国内伟大的防火墙,这种方式我从来就没成功安装过。不过可以使用下面的方式来安装。

首先你的去https://packages.gitlab.com/gitlab/gitlab-ce找到符合你操作系统版本的安装包,下载到本地,然后上传到阿里云服务器安装,安装命令如下所示:

rpm -i gitlab-ce-XXX.rpm

不过,貌似下载速度比较慢,不过谁需要的话,会在下面评论给出百度云盘的地址。

3.安装完成后需要下面的命令重启Gitlab使配置生效。

sudo gitlab-ctl reconfigure

4.等过浏览器进行登录和访问。默认给出了顶级的root用户密码,登录后要重现设置密码并且要牢记该密码,由于这是权限最重的用户,密码设置的时候复杂度尽量高些。

Username: root 
Password: 5iveL!fe

Web中虚拟主机的理解

虚拟主机,又称为虚拟主机服务器、主机空间或是网页空间,它是一种技术。该技术是为了节省互联网服务器硬件成本而出现的。这里的“主机”或“空间”是由实体的服务器延伸而来,硬件系统可以基于服务器集群,或者单个服务器等。虚拟主机技术主要应用于HTTP、FTP及EMAIL等多项服务,将一台服务器的某项或者全部服务内容逻辑划分为多个服务单位,对外表现为多个服务器,从而充分利用服务器硬件资源。从用户角度来看,一台虚拟主机和一台独立的硬件主机是完全一样的。

在使用Nginx服务器提供Web服务时,利用虚拟主机的技术就可以避免为每一个要运行的网站提供单独的Nginx服务器,也无需为每个网站对应运行一组Nginx进程。虚拟主机技术使得Nginx服务器可以在同一台服务器上运行一组Nginx进程,就可以运行多个网站。

在Nginx中,每个server块就相当于一台虚拟主机,它内部就可有多台主机联合提供服务,一起对外提供在逻辑上关系密切的一组服务(或网站)。

仅执行一次的工作调度(at命令的使用)

atd 的启动与 at 运作的方式

atd 的启动

[root@www ~]# /etc/init.d/atd restart
正在停止 atd:                          [  确定  ]
正在启动 atd:                          [  确定  ]

# 再设定一下开机时就启动这个服务,免得每次重新开机都得再来一次!
[root@www ~]# chkconfig atd on

运行方式

既然是工作调度,那么应该会有产生工作的方式,并且将这些工作安排进日程表中。那么生成工作以文本文件的方式写入/var/spool/at目录内,该工作便能等待atd这个服务的取用与执行了,就这么简单。

实际运行单一工作调度

基本语法如下:

[root@www ~]# at [-mldv] TIME
[root@www ~]# at -c 工作号码
选项与参数:
-m  :当 at 的工作完成后,即使没有输出讯息,亦以 email 通知使用者该工作已完成。
-l  :at -l 相当于 atq,列出目前系统上面的所有该使用者的 at 排程;
-d  :at -d 相当于 atrm ,可以取消一个在 at 排程中的工作;
-v  :可以使用较明显的时间格式列出 at 排程中的工作列表;
-c  :可以列出后面接的该项工作的实际指令内容。

TIME:时间格式,这里可以定义出‘什么时候要进行 at 这项工作’的时间,格式有:
  HH:MM             ex> 04:00
    在今日的 HH:MM 时刻进行,若该时刻已超过,则明天的 HH:MM 进行此工作。
  HH:MM YYYY-MM-DD      ex> 04:00 2009-03-17
    强制规定在某年某月的某一天的特殊时刻进行该工作!
  HH:MM[am|pm] [Month] [Date]   ex> 04pm March 17
    也是一样,强制在某年某月某日的某时刻进行!
  HH:MM[am|pm] + number [minutes|hours|days|weeks]
    ex> now + 5 minutes ex> 04pm + 3 days
    就是说,在某个时间点‘再加几个时间后’才进行。

老实说,这个 at 指令的下达最重要的地方在于‘时间’的指定了!鸟哥喜欢使用‘ now + ... ’ 的方式来定义现在过多少时间再进行工作,但有时也需要定义特定的时间点来进行!底下的范例先看看啰!

范例一:再过五分钟后,将 /root/.bashrc 寄给 root 自己
[root@www ~]# at now + 5 minutes  <==记得单位要加 s 喔!
at> /bin/mail root -s "testing at job" < /root/.bashrc
at> <EOF>   <==这里输入 [ctrl] + d 就会出现 <EOF> 的字样!代表结束!
job 4 at 2009-03-14 15:38
# 上面这行资讯在说明,第 4 个 at 工作将在 2009/03/14 的 15:38 进行!
# 而执行 at 会进入所谓的 at shell 环境,让你下达多重指令等待运作!

范例二:将上述的第 4 项工作内容列出来查阅
[root@www ~]# at -c 4
#!/bin/sh               <==就是透过 bash shell 的啦!
# atrun uid=0 gid=0
# mail     root 0
umask 22
....(中间省略许多的环境变数项目)....
cd /root || {           <==可以看出,会到下达 at 时的工作目录去执行指令
         echo 'Execution directory inaccessible' >&2
         exit 1
}

/bin/mail root -s "testing at job" < /root/.bashrc
# 你可以看到指令执行的目录 (/root),还有多个环境变数与实际的指令内容啦!

范例三:由于机房预计于 2009/03/18 停电,我想要在 2009/03/17 23:00 关机?
[root@www ~]# at 23:00 2009-03-17
at> /bin/sync
at> /bin/sync
at> /sbin/shutdown -h now
at> <EOF>
job 5 at 2009-03-17 23:00
# 您瞧瞧! at 还可以在一个工作内输入多个指令呢!不错吧!

范例四:定时在终端显示字符串
[root@www ~]# at now + 5 minutes  <==记得单位要加 s 喔!
at > echo "Hello" > /dev/tty1 ’
at > <EOF>

at的工作管理

[root@www ~]# atq
[root@www ~]# atrm [jobnumber]

范例一:查询目前主机上面有多少的 at 工作排程?
[root@www ~]# atq
5       2009-03-17 23:00 a root
# 上面说的是:‘在 2009/03/17 的 23:00 有一项工作,该项工作指令下达者为 
# root’而且,该项工作的工作号码 (jobnumber) 为 5 号喔!

范例二:将上述的第 5 个工作移除!
[root@www ~]# atrm 5
[root@www ~]# atq
# 没有任何资讯,表示该工作被移除了!

如果你是在一个非常忙碌的系统下运行at,能不能指定你的工作在系统较闲的时候进行呢?可以的,可以通过batch命令开控制。它会在CPU工作负载小于0.8的时候,才进行你所执行的工作任务batch命令使用范例如下所示:

范例一:同样是机房停电在 2009/3/17 23:00 关机,但若当时系统负载太高,则暂缓执行
[root@www ~]# batch 23:00 2009-3-17
at> sync
at> sync
at> shutdown -h now
at> <EOT>
job 6 at 2009-03-17 23:00

[root@www ~]# atq
6       2009-03-17 23:00 b root
[root@www ~]# atrm 6

linux基本命令速记

显示日期与时间的命令

$ date  //带有时区

$ date +%Y/%m/%d    //区分大小写,显示年月日

$ date +%H:%M   //显示小时和分钟

date '+%Y/%m/%d %H:%M'   //处理空格

显示日历的命令

$ cal   //显示当前这个月的月历

$ cal 2009  //显示2009年整年的日历

$ cal 10 2009 //显示2009年10月的月历

简单实用的计算器命令

$ bc 

输入该命令之后,就进入到这个软件的工作环境当中去了,运行界面截图如下:

显示日期与时间的命令

$ date  //带有时区

$ date +%Y/%m/%d    //区分大小写,显示年月日

$ date +%H:%M   //显示小时和分钟

date '+%Y/%m/%d %H:%M'   //处理空格

显示日历的命令

$ cal   //显示当前这个月的月历

$ cal 2009  //显示2009年整年的日历

$ cal 10 2009 //显示2009年10月的月历

简单实用的计算器命令

$ bc 

输入该命令之后,就进入到这个软件的工作环境当中去了,运行界面截图如下:

1

之后你就可以输入你需要的计算,比如1+1+3 2-1等。

PS: 常用的运算符为:+、-、*、/、^、%

PS: 因为bc默认仅输出整数,如果要输出全部小数,那么就必须执行scale = number,哪个number就是小数点后的位数。

PS: 要离开bc回到命令提示符时,务必要输入"quit"来离开bc的软件环境

LVM实现流程

透过 PV, VG, LV 的规划之后,再利用 mkfs 就可以将你的 LV 格式化成为可以利用的文件系统了!而且这个文件系统的容量在未来还能够进行扩充或减少, 而且里面的数据还不会被影响!实在是很『福气啦!』那实作方面要如何进行呢?很简单呢! 整个流程由基础到最终的结果可以这样看:

lvm

160003455

Nginx配置虚拟主机

增加Nginx虚拟主机

这里假设大家的 Nginx 服务器已经安装好, 不懂的请阅读各 Linux 发行版的官方文档或者 LNMP 的安装说明. 配置 Virtual host 步骤如下:

  1. 进入 /usr/local/nginx/conf/vhost 目录, 创建虚拟主机配置文件 demo.neoease.com.conf ({域名}.conf).

  2. 打开配置文件, 添加服务如下:

    server {
        listen       80;
        server_name demo.neoease.com;
        index index.html index.htm index.php;
        root  /var/www/demo_neoease_com;
        log_format demo.neoease.com '$remote_addr - $remote_user [$time_local] $request'
        '$status $body_bytes_sent $http_referer '
        '$http_user_agent $http_x_forwarded_for';
        access_log  /var/log/demo.neoease.com.log demo.neoease.com;
    }
    
  3. 打开 Nginx 配置文件 /usr/local/nginx/conf/nginx.conf, 在 http 范围引入虚拟主机配置文件如下:

    include vhost/*.conf;
    
  4. 重启 Nginx 服务, 执行以下语句.

    service nginx restart    
    

让Nginx虚拟主机支持 PHP

在前面第 2 步的虚拟主机服务对应的目录加入对 PHP 的支持, 这里使用的是 FastCGI, 修改如下.

server {
    listen       80;
    server_name demo.neoease.com;
    index index.html index.htm index.php;
    root  /var/www/demo_neoease_com;

    location ~ .*\.(php|php5)?$ {
        fastcgi_pass unix:/tmp/php-cgi.sock;
        fastcgi_index index.php;
        include fcgi.conf;
    }

    log_format demo.neoease.com '$remote_addr - $remote_user [$time_local] $request'
    '$status $body_bytes_sent $http_referer '
    '$http_user_agent $http_x_forwarded_for';
    access_log  /var/log/demo.neoease.com.log demo.neoease.com;
}

图片防盗链

图片作为重要的耗流量大的静态资源, 可能网站主并不希望其他网站直接引用, Nginx 可以通过 referer 来防止外站盗链图片.

server {
    listen       80;
    server_name demo.neoease.com;
    index index.html index.htm index.php;
    root  /var/www/demo_neoease_com;

    # 这里为图片添加为期 1 年的过期时间, 并且禁止 Google, 百度和本站之外的网站引用图片
    location ~ .*\.(ico|jpg|jpeg|png|gif)$ {
        expires 1y;
        valid_referers none blocked demo.neoease.com *.google.com *.baidu.com;
        if ($invalid_referer) {
            return 404;
        }
    }

    log_format demo.neoease.com '$remote_addr - $remote_user [$time_local] $request'
    '$status $body_bytes_sent $http_referer '
    '$http_user_agent $http_x_forwarded_for';
    access_log  /var/log/demo.neoease.com.log demo.neoease.com;
}

WordPress 伪静态配置

如果将 WordPress 的链接结构设定为 /%postname%/, /%postname%.html 等格式时, 需要 rewrite URL, WordPress 提供 Apache 的 .htaccess 修改建议, 但没告知 Nginx 该如何修改. 我们可以将 WordPress 的虚拟主机配置修改如下:

server {
    listen       80;
    server_name demo.neoease.com;
    index index.html index.htm index.php;
    root  /var/www/demo_neoease_com;

    location / {
        if (-f $request_filename/index.html){
            rewrite (.*) $1/index.html break;
        }
        if (-f $request_filename/index.php){
            rewrite (.*) $1/index.php;
        }
        if (!-f $request_filename){
            rewrite (.*) /index.php;
        }
    }
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;

    location ~ .*\.(php|php5)?$ {
        fastcgi_pass unix:/tmp/php-cgi.sock;
        fastcgi_index index.php;
        include fcgi.conf;
    }

    log_format demo.neoease.com '$remote_addr - $remote_user [$time_local] $request'
    '$status $body_bytes_sent $http_referer '
    '$http_user_agent $http_x_forwarded_for';
    access_log  /var/log/demo.neoease.com.log demo.neoease.com;
}

LNMP 套件在提供了 WordPress 为静态配置文件 /usr/local/nginx/conf/wordpress.conf, 在虚拟主机配置的 server 范围引用如下即可.

include wordpress.conf;

如果你使用 LNMP 套件, 进入 WordPress 后台发现会出现 404 页面, wp-admin 后面缺少了斜杆 /, 请在 wordpress.conf 最后添加以下语句:

rewrite /wp-admin$ $scheme://$host$uri/ permanent;    

帮助链接:

原文链接:http://www.neoease.com/nginx-virtual-host/

参考链接:http://zl382378867.blog.163.com/blog/static/407944212011124115813231/

Nginx启用nginx status状态详解

nginx和php-fpm一样内建了一个状态页,对于想了解nginx的状态以及监控nginx非常有帮助。

1. 启用nginx status配置

在默认主机里面加上location或者你希望能访问到的主机里面。

server {
    listen  *:80 default_server;
    server_name _;
    location /ngx_status 
    {
        stub_status on;
        access_log off;
        #allow 127.0.0.1;
        #deny all;
    }
}

2. 重启nginx

 # service nginx restart

3. 打开status页面

# curl http://127.0.0.1/ngx_status
Active connections: 11921 
server accepts handled requests
 11989 11989 11991 
Reading: 0 Writing: 7 Waiting: 42

4. nginx status详解

active connections – 活跃的连接数量
server accepts handled requests — 总共处理了11989个连接 , 成功创建11989次握手, 总共处理了11991个请求
reading — 读取客户端的连接数.
writing — 响应数据到客户端的数量
waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 
意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接.

Bash默认组合键及通配符的支持

默认组合键

组合按键 执行结果
Ctrl+C 终止目前的命令
Ctrl+D 输入结束(EOF),例如邮件结束的时候
Ctrl+M 等效Enter
Ctrl+S 暂停屏幕的输出
Ctrl+Q 恢复屏幕的输出
Ctrl+U 在提示符下,将整行命令删除
Ctrl+Z 暂停目前的命令

什么是LVM: PV,PE,VG,LV的意义

LVM的全名是Logical Volume Manager,中文可以译作逻辑卷管理器。之所以称为"卷"可能是因为可以将文件系统像卷一样伸长或缩短之故吧!LVM的做法是将几个物理的分区(或磁盘)通过软件组合成为一块看起来是独立的大磁盘(VG),然后将这块大磁盘再经过分成为可用分区(LV),最终就能够挂载使用了。但是为什么这样的系统可以进行文件系统的扩充或缩小呢?其实与一个称为PE的选项有关,下面我们就得要针对这几个选项来好好聊聊。

  • PhysicalVolume,PV,物理卷

    我们实际的分区需要调整系统标示符(System ID)称为8e(LVM 的标识符),然后再经过pvcreate的命令将它转成LVM最底层的物理卷(PV),之后才能够将这些PV加以利用,调正sytem ID的方就是通过fdisk.

  • Volume Group,VG,卷用户组

    所谓的LVM大磁盘就是将许多PV整合成这个VG,所以VG就是LVM组合起来的大磁盘。那么这个大磁盘最大可以达到多少容量呢?这与下面要说明的PE有关,因为每个VG最多仅能包含65534个PE而已。如果使用LVM默认的参数,则一个VG最大可以达256GB的容量。

  • Physical Extend,PE,物理拓展块

    LVM默认使用4MB的PE块,而LVM的VG最多仅能含有65534个PE,因此默认的LVM VG会有256G.这个PE很有趣。它是整个LVM最小的存储块,也就是说,其实我们的文件的文件数据都是由写入PE来处理的。简单来说,这个PE就有点像文件系统里面的block大小。所以调整PE会影响到VG的最大容量。

  • Logical Volume,LV,逻辑卷

    最终的VG还会被切成LV,这个LV就是最后可以被格式化使用的类似分区。那么LV是否可以随意指定大小呢?当然不可以。既然PE是整个LVM的最小存储单位,那么LV大大小就与此LV内的PE总数有关。为了方便用户利用LVM来管理其系统,因此LV的设备文件名通常指定为“/dev/vgname/lvname”的样式!

    此外,我们刚才谈到LVM可弹性更改文件系统的容量,那时如何办到到的?其实它就是通过交换PE来进行数据转换,将原本LV内的PE移转到其他设备中以降低LV容量,或将其他设备的PE加到LV中以加大容量。VG、LV与PE的关系如图:

    pe_vg

    如上图所示,VG内的PE会分给虚线部分的LV,如果将来这个VG要填充的话,加上其他的PV即可。而最重要的LV如果要填充的话,也是通过加入VG内没有使用到的PE来填充的。

磁盘与目录的容量的查看(df与du命令的使用)

磁盘与目录的容量

现在我们知道磁盘的整体数据是在 superblock 区块中,但是每个各别文件的容量则在 inode 当中记载的。 那在文字接口底下该如何查看这几个数据呢?底下就让我们来谈一谈这两个命令:

  • df:列出文件系统的整体磁盘使用量;
  • du:评估文件系统的磁盘使用量(常用在推估目录所占容量)

df

[root@www ~]# df [-ahikHTm] [目录或文件名]
选项与参数:
-a  :列出所有的文件系统,包括系统特有的 /proc 等文件系统;
-k  :以 KBytes 的容量显示各文件系统;
-m  :以 MBytes 的容量显示各文件系统;
-h  :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
-H  :以 M=1000K 取代 M=1024K 的进位方式;
-T  :连同该 partition 的 filesystem 名称 (例如 ext3) 也列出;
-i  :不用硬盘容量,而以 inode 的数量来显示

范例一:将系统内所有的 filesystem 列出来!
[root@www ~]# df
Filesystem      1K-blocks      Used Available Use% Mounted on
/dev/hdc2         9920624   3823112   5585444  41% /
/dev/hdc3         4956316    141376   4559108   4% /home
/dev/hdc1          101086     11126     84741  12% /boot
tmpfs              371332         0    371332   0% /dev/shm
# 在 Linux 底下如果 df 没有加任何选项,那么默认会将系统内所有的 
# (不含特殊内存内的文件系统与 swap) 都以 1 Kbytes 的容量来列出来!
# 至于那个 /dev/shm 是与内存有关的挂载,先不要理他!

范例二:将容量结果以易读的容量格式显示出来
[root@www ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/hdc2             9.5G  3.7G  5.4G  41% /
/dev/hdc3             4.8G  139M  4.4G   4% /home
/dev/hdc1              99M   11M   83M  12% /boot
tmpfs                 363M     0  363M   0% /dev/shm
# 不同于范例一,这里会以 G/M 等容量格式显示出来,比较容易看啦!

范例三:将系统内的所有特殊文件格式及名称都列出来
[root@www ~]# df -aT
Filesystem    Type 1K-blocks    Used Available Use% Mounted on
/dev/hdc2     ext3   9920624 3823112   5585444  41% /
proc          proc         0       0         0   -  /proc
sysfs        sysfs         0       0         0   -  /sys
devpts      devpts         0       0         0   -  /dev/pts
/dev/hdc3     ext3   4956316  141376   4559108   4% /home
/dev/hdc1     ext3    101086   11126     84741  12% /boot
tmpfs        tmpfs    371332       0    371332   0% /dev/shm
none   binfmt_misc         0       0         0   -  /proc/sys/fs/binfmt_misc
sunrpc  rpc_pipefs         0       0         0   -  /var/lib/nfs/rpc_pipefs
# 系统里面其实还有很多特殊的文件系统存在的。那些比较特殊的文件系统几乎
# 都是在内存当中,例如 /proc 这个挂载点。因此,这些特殊的文件系统
# 都不会占据硬盘空间喔! ^_^

范例四:将 /etc 底下的可用的磁盘容量以易读的容量格式显示
[root@www ~]# df -h /etc
Filesystem            Size  Used Avail Use% Mounted on
/dev/hdc2             9.5G  3.7G  5.4G  41% /
# 这个范例比较有趣一点啦,在 df 后面加上目录或者是文件时, df
# 会自动的分析该目录或文件所在的 partition ,并将该 partition 的容量显示出来,
# 所以,您就可以知道某个目录底下还有多少容量可以使用了! ^_^

范例五:将目前各个 partition 当中可用的 inode 数量列出
[root@www ~]# df -ih 
Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/hdc2               2.5M    147K    2.3M    6% /
/dev/hdc3               1.3M      46    1.3M    1% /home
/dev/hdc1                26K      34     26K    1% /boot
tmpfs                    91K       1     91K    1% /dev/shm
# 这个范例则主要列出可用的 inode 剩余量与总容量。分析一下与范例一的关系,
# 你可以清楚的发现到,通常 inode 的数量剩余都比 block 还要多呢

先来说明一下范例一所输出的结果信息为:

  • Filesystem:代表该文件系统是在哪个 partition ,所以列出装置名称;
  • 1k-blocks:说明底下的数字单位是 1KB 呦!可利用 -h 或 -m 来改变容量;
  • Used:顾名思义,就是使用掉的硬盘空间啦!
  • Available:也就是剩下的磁盘空间大小;
  • Use%:就是磁盘的使用率啦!如果使用率高达 90% 以上时, 最好需要注意一下了,免得容量不足造成系统问题喔!(例如最容易被灌爆的 /var/spool/mail 这个放置邮件的磁盘)
  • Mounted on:就是磁盘挂载的目录所在啦!(挂载点啦!)

由于 df 主要读取的数据几乎都是针对一整个文件系统,因此读取的范围主要是在 Superblock 内的信息, 所以这个命令显示结果的速度非常的快速!在显示的结果中你需要特别留意的是那个根目录的剩余容量! 因为我们所有的数据都是由根目录衍生出来的,因此当根目录的剩余容量剩下 0 时,那你的 Linux 可能就问题很大了。

另外需要注意的是,如果使用 -a 这个参数时,系统会出现 /proc 这个挂载点,但是里面的东西都是 0 ,不要紧张! /proc 的东西都是 Linux 系统所需要加载的系统数据,而且是挂载在『内存当中』的, 所以当然没有占任何的硬盘空间啰!

至于那个 /dev/shm/ 目录,其实是利用内存虚拟出来的磁盘空间! 由于是透过内存仿真出来的磁盘,因此你在这个目录底下创建任何数据文件时,访问速度是非常快速的!(在内存内工作) 不过,也由于他是内存仿真出来的,因此这个文件系统的大小在每部主机上都不一样,而且创建的东西在下次启动时就消失了! 因为是在内存中嘛!

du

[root@www ~]# du [-ahskm] 文件或目录名称
选项与参数:
-a  :列出所有的文件与目录容量,因为默认仅统计目录底下的文件量而已。
-h  :以人们较易读的容量格式 (G/M) 显示;
-s  :列出总量而已,而不列出每个各别的目录占用容量;
-S  :不包括子目录下的总计,与 -s 有点差别。
-k  :以 KBytes 列出容量显示;
-m  :以 MBytes 列出容量显示;

范例一:列出目前目录下的所有文件容量
[root@www ~]# du
8       ./test4     <==每个目录都会列出来
8       ./test2
....中间省略....
12      ./.gconfd   <==包括隐藏文件的目录
220     .           <==这个目录(.)所占用的总量
# 直接输入 du 没有加任何选项时,则 du 会分析『目前所在目录』
# 的文件与目录所占用的硬盘空间。但是,实际显示时,仅会显示目录容量(不含文件),
# 因此 . 目录有很多文件没有被列出来,所以全部的目录相加不会等于 . 的容量喔!
# 此外,输出的数值数据为 1K 大小的容量单位。

范例二:同范例一,但是将文件的容量也列出来
[root@www ~]# du -a
12      ./install.log.syslog   <==有文件的列表了
8       ./.bash_logout
8       ./test4
8       ./test2
....中间省略....
12      ./.gconfd
220     .

范例三:检查根目录底下每个目录所占用的容量
[root@www ~]# du -sm /*
7       /bin
6       /boot
.....中间省略....
0       /proc
.....中间省略....
1       /tmp
3859    /usr     <==系统初期最大就是他了啦!
77      /var
# 这是个很常被使用的功能~利用通配符 * 来代表每个目录,
# 如果想要检查某个目录下,哪个次目录占用最大的容量,可以用这个方法找出来
# 值得注意的是,如果刚刚安装好 Linux 时,那么整个系统容量最大的应该是 /usr 
# 而 /proc 虽然有列出容量,但是那个容量是在内存中,不占硬盘空间。

与 df 不一样的是,du 这个命令其实会直接到文件系统内去搜寻所有的文件数据, 所以上述第三个范例命令的运行会运行一小段时间!此外,在默认的情况下,容量的输出是以 KB 来设计的, 如果你想要知道目录占了多少 MB ,那么就使用 -m 这个参数即可啰!而, 如果你只想要知道该目录占了多少容量的话,使用 -s 就可以啦!

至于 -S 这个选项部分,由于 du 默认会将所有文件的大小均列出,因此假设你在 /etc 底下使用 du 时, 所有的文件大小,包括 /etc 底下的次目录容量也会被计算一次。然后最终的容量 (/etc) 也会加总一次, 因此很多朋友都会误会 du 分析的结果不太对劲。所以啰,如果想要列出某目录下的全部数据, 或许也可以加上 -S 的选项,减少次目录的加总喔!

初次运行 Git 前的配置

初次运行 Git 前的配置

既然已经在系统上安装了 Git,你会想要做几件事来定制你的 Git 环境。 每台计算机上只需要配置一次,程序升级时会保留配置信息。 你可以在任何时候再次通过运行命令来修改它们。

Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。 这些变量存储在三个不同的位置:

  1. /etc/gitconfig 文件: 包含系统上每一个用户及他们仓库的通用配置。 如果使用带有 --system 选项的 git config 时,它会从此文件读写配置变量。
  2. ~/.gitconfig~/.config/git/config 文件:只针对当前用户。 可以传递 --global 选项让 Git 读写此文件。
  3. 当前使用仓库的 Git 目录中的 config 文件(就是 .git/config):针对该仓库。

每一个级别覆盖上一级别的配置,所以 .git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量。

在 Windows 系统中,Git 会查找 $HOME 目录下(一般情况下是 C:\Users\$USER)的 .gitconfig 文件。 Git 同样也会寻找 /etc/gitconfig 文件,但只限于 MSys 的根目录下,即安装 Git 时所选的目标位置。

用户信息

当安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址。 这样做很重要,因为每一个 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改:

$ git config --global user.name "John Doe"
$ git config --global user.email [email protected]

再次强调,如果使用了 --global 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息。 当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 --global 选项的命令来配置。

很多 GUI 工具都会在第一次运行时帮助你配置这些信息。

文本编辑器

既然用户信息已经设置完毕,你可以配置默认文本编辑器了,当 Git 需要你输入信息时会调用它。 如果未配置,Git 会使用操作系统默认的文本编辑器,通常是 Vim。 如果你想使用不同的文本编辑器,例如 Emacs,可以这样做:

$ git config --global core.editor emacs

检查配置信息

如果想要检查你的配置,可以使用 git config --list 命令来列出所有 Git 当时能找到的配置。

$ git config --list
user.name=John Doe
[email protected]
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...

你可能会看到重复的变量名,因为 Git 会从不同的文件中读取同一个配置(例如:/etc/gitconfig~/.gitconfig)。 这种情况下,Git 会使用它找到的每一个变量的最后一个配置。

你可以通过输入 git config <key>: 来检查 Git 的某一项配置

$ git config user.name
John Doe

Linux中ACL 权限配置

什么是 ACL

ACL 是 Access Control List 的缩写,主要的目的是在提供传统的 owner,group,others 的 read,write,execute 权限之外的细部权限配置。ACL 可以针对单一使用者,单一文件或目录来进行 r,w,x 的权限规范,对于需要特殊权限的使用状况非常有帮助。

那 ACL 主要可以针对哪些方面来控制权限呢?他主要可以针对几个项目:

  • 使用者 (user):可以针对使用者来配置权限;
  • 群组 (group):针对群组为对象来配置其权限;
  • 默认属性 (mask):还可以针对在该目录下在创建新文件/目录时,规范新数据的默认权限;

ACL 的配置技巧: getfacl, setfacl

好了,让你的 filesystem 启动 ACL 支持后,接下来该如何配置与观察 ACL 呢? 很简单,利用这两个命令就可以了:

  • getfacl:取得某个文件/目录的 ACL 配置项目;
  • setfacl:配置某个目录/文件的 ACL 规范。

setfacl 命令用法

[root@www ~]# setfacl [-bkRd] [{-m|-x} acl参数] 目标文件名
选项与参数:
-m :配置后续的 acl 参数给文件使用,不可与 -x 合用;
-x :删除后续的 acl 参数,不可与 -m 合用;
-b :移除所有的 ACL 配置参数;
-k :移除默认的 ACL 参数,关于所谓的『默认』参数于后续范例中介绍;
-R :递归配置 acl ,亦即包括次目录都会被配置起来;
-d :配置『默认 acl 参数』的意思!只对目录有效,在该目录新建的数据会引用此默认值

上面谈到的是 acl 的选项功能,那么如何配置 ACL 的特殊权限呢?特殊权限的配置方法有很多, 我们先来谈谈最常见的,就是针对单一使用者的配置方式:

#1. 针对特定使用者的方式:
# 配置规范:『 u:[使用者账号列表]:[rwx] 』,例如针对 vbird1 的权限规范 rx :
[root@www ~]# touch acl_test1
[root@www ~]# ll acl_test1
-rw-r--r-- 1 root root 0 Feb 27 13:28 acl_test1
[root@www ~]# setfacl -m u:vbird1:rx acl_test1
[root@www ~]# ll acl_test1
-rw-r-xr--+ 1 root root 0 Feb 27 13:28 acl_test1
# 权限部分多了个 + ,且与原本的权限 (644) 看起来差异很大!但要如何查阅呢?

[root@www ~]# setfacl -m u::rwx acl_test1
[root@www ~]# ll acl_test1
-rwxr-xr--+ 1 root root 0 Feb 27 13:28 acl_test1
# 无使用者列表,代表配置该文件拥有者,所以上面显示 root 的权限成为 rwx 了!

上述动作为最简单的 ACL 配置,利用『 u:使用者:权限 』的方式来配置的啦!配置前请加上 -m 这个选项。 如果一个文件配置了 ACL 参数后,他的权限部分就会多出一个 + 号了!但是此时你看到的权限与实际权限可能就会有点误差! 那要如何观察呢?就透过 getfacl 吧!

getfacl 命令用法

[root@www ~]# getfacl filename
选项与参数:
getfacl 的选项几乎与 setfacl 相同!所以鸟哥这里就免去了选项的说明啊!

# 请列出刚刚我们配置的 acl_test1 的权限内容:
[root@www ~]# getfacl acl_test1
# file: acl_test1   <==说明档名而已!
# owner: root       <==说明此文件的拥有者,亦即 ll 看到的第三使用者字段
# group: root       <==此文件的所属群组,亦即 ll 看到的第四群组字段
user::rwx           <==使用者列表栏是空的,代表文件拥有者的权限
user:vbird1:r-x     <==针对 vbird1 的权限配置为 rx ,与拥有者并不同!
group::r--          <==针对文件群组的权限配置仅有 r 
mask::r-x           <==此文件默认的有效权限 (mask)
other::r--          <==其他人拥有的权限啰!

上面的数据非常容易查阅吧?显示的数据前面加上 # 的,代表这个文件的默认属性,包括文件名、文件拥有者与文件所属群组。 底下出现的 user, group, mask, other 则是属于不同使用者、群组与有效权限(mask)的配置值。 以上面的结果来看,我们刚刚配置的 vbird1 对于这个文件具有 r 与 x 的权限啦!这样看的懂吗? 如果看的懂的话,接下来让我们在测试其他类型的 setfacl 配置吧!

#2. 针对特定群组的方式:
# 配置规范:『 g:[群组列表]:[rwx] 』,例如针对 mygroup1 的权限规范 rx :
[root@www ~]# setfacl -m g:mygroup1:rx acl_test1
[root@www ~]# getfacl acl_test1
# file: acl_test1
# owner: root
# group: root
user::rwx
user:vbird1:r-x
group::r--
group:mygroup1:r-x  <==这里就是新增的部分!多了这个群组的权限配置!
mask::r-x
other::r--

基本上,群组与使用者的配置并没有什么太大的差异啦!如上表所示,非常容易了解意义。不过,你应该会觉得奇怪的是, 那个 mask 是什么东西啊?其实他有点像是『有效权限』的意思!他的意义是: 使用者或群组所配置的权限必须要存在于 mask 的权限配置范围内才会生效,此即『有效权限 (effective permission)』 我们举个例子来看,如下所示:

#3. 针对有效权限 mask 的配置方式:
# 配置规范:『 m:[rwx] 』,例如针对刚刚的文件规范为仅有 r :
[root@www ~]# setfacl -m m:r acl_test1
[root@www ~]# getfacl acl_test1
# file: acl_test1
# owner: root
# group: root
user::rwx
user:vbird1:r-x        #effective:r-- <==vbird1+mask均存在者,仅有 r 而已!
group::r--
group:mygroup1:r-x     #effective:r--
mask::r--
other::r--

您瞧,vbird1 与 mask 的集合发现仅有 r 存在,因此 vbird1 仅具有 r 的权限而已,并不存在 x 权限!这就是 mask 的功能了!我们可以透过使用 mask 来规范最大允许的权限,就能够避免不小心开放某些权限给其他使用者或群组了。 不过,通常鸟哥都是将 mask 配置为 rwx 啦!然后再分别依据不同的使用者/群组去规范她们的权限就是了。

继承功能

如果你想要让 acl 在目录底下的数据都有继承的功能,那就得如下这样做了!

#4. 针对默认权限的配置方式:
# 配置规范:『 d:[ug]:使用者列表:[rwx] 』

# 让 myuser1 在 /srv/projecta 底下一直具有 rx 的默认权限!
[root@www ~]# setfacl -m d:u:myuser1:rx /srv/projecta
[root@www ~]# getfacl /srv/projecta
# file: srv/projecta
# owner: root
# group: projecta
user::rwx
user:myuser1:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:myuser1:r-x
default:group::rwx
default:mask::rwx
default:other::---

[root@www ~]# cd /srv/projecta
[root@www projecta]# touch zzz1
[root@www projecta]# mkdir zzz2
[root@www projecta]# ll -d zzz*
-rw-rw----+ 1 root projecta    0 Feb 27 14:57 zzz1
drwxrws---+ 2 root projecta 4096 Feb 27 14:57 zzz2
# 看吧!确实有继承喔!然后我们使用 getfacl 再次确认看看!

[root@www projecta]# getfacl zzz2
# file: zzz2
# owner: root
# group: projecta
user::rwx
user:myuser1:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:myuser1:r-x
default:group::rwx
default:mask::rwx
default:other::---

透过这个『针对目录来配置的默认 ACL 权限配置值』的项目,我们可以让这些属性继承到次目录底下呢! 非常方便啊!那如果想要让 ACL 的属性全部消失又要如何处理?透过『 setfacl -b 檔名 』即可啦!

linux中的文件隐藏属性

这些隐藏的属性确实对於系统有很大的帮助的~ 尤其是在系统安全 (Security) 上面,重要的紧呢!不过要先强调的是,底下的chattr命令只能在Ext2/Ext3的文件系统上面生效, 其他的文件系统可能就无法支持这个命令了。底下我们就来谈一谈如何配置与检查这些隐藏的属性吧!

chattr (配置文件隐藏属性)

[root@www ~]# chattr [+-=][ASacdistu] 文件或目录名称
选项与参数:
+   :添加某一个特殊参数,其他原本存在参数则不动。
-   :移除某一个特殊参数,其他原本存在参数则不动。
=   :配置一定,且仅有后面接的参数

A  :当配置了 A 这个属性时,若你有存取此文件(或目录)时,他的存取时间 atime
     将不会被修改,可避免I/O较慢的机器过度的存取磁碟。这对速度较慢的计算机有帮助
S  :一般文件是非同步写入磁碟的(原理请参考第五章sync的说明),如果加上 S 这个
     属性时,当你进行任何文件的修改,该更动会『同步』写入磁碟中。
a  :当配置 a 之后,这个文件将只能添加数据,而不能删除也不能修改数据,只有root 
     才能配置这个属性。 
c  :这个属性配置之后,将会自动的将此文件『压缩』,在读取的时候将会自动解压缩,
     但是在储存的时候,将会先进行压缩后再储存(看来对於大文件似乎蛮有用的!)
d  :当 dump 程序被运行的时候,配置 d 属性将可使该文件(或目录)不会被 dump 备份
i  :这个 i 可就很厉害了!他可以让一个文件『不能被删除、改名、配置连结也无法
     写入或新增数据!』对於系统安全性有相当大的助益!只有 root 能配置此属性
s  :当文件配置了 s 属性时,如果这个文件被删除,他将会被完全的移除出这个硬盘
     空间,所以如果误删了,完全无法救回来了喔!
u  :与 s 相反的,当使用 u 来配置文件时,如果该文件被删除了,则数据内容其实还
     存在磁碟中,可以使用来救援该文件喔!
注意:属性配置常见的是 a 与 i 的配置值,而且很多配置值必须要身为 root 才能配置

范例:请尝试到/tmp底下创建文件,并加入 i 的参数,尝试删除看看。
[root@www ~]# cd /tmp
[root@www tmp]# touch attrtest     <==创建一个空文件
[root@www tmp]# chattr +i attrtest <==给予 i 的属性
[root@www tmp]# rm attrtest        <==尝试删除看看
rm: remove write-protected regular empty file `attrtest'? y
rm: cannot remove `attrtest': Operation not permitted  <==操作不许可
# 看到了吗?呼呼!连 root 也没有办法将这个文件删除呢!赶紧解除配置!

范例:请将该文件的 i 属性取消!
[root@www tmp]# chattr -i attrtest

这个命令是很重要的,尤其是在系统的数据安全上面!由於这些属性是隐藏的性质,所以需要以 lsattr 才能看到该属性呦!其中,个人认为最重要的当属 +i 与 +a 这个属性了。+i 可以让一个文件无法被更动,对於需要强烈的系统安全的人来说, 真是相当的重要的!里头还有相当多的属性是需要 root 才能配置的呢!

此外,如果是 log file 这种的登录档,就更需要 +a 这个可以添加,但是不能修改旧有的数据与删除的参数了!怎样?很棒吧!

lsattr (显示文件隐藏属性)

[root@www ~]# lsattr [-adR] 文件或目录
选项与参数:
-a :将隐藏档的属性也秀出来;
-d :如果接的是目录,仅列出目录本身的属性而非目录内的档名;
-R :连同子目录的数据也一并列出来! 

[root@www tmp]# chattr +aij attrtest
[root@www tmp]# lsattr attrtest
----ia---j--- attrtest

使用 chattr 配置后,可以利用 lsattr 来查阅隐藏的属性。不过, 这两个命令在使用上必须要特别小心,否则会造成很大的困扰。例如:某天你心情好,突然将 /etc/shadow 这个重要的密码记录文件给他配置成为具有 i 的属性,那么过了若干天之后, 你突然要新增使用者,却一直无法新增!别怀疑,赶快去将 i 的属性拿掉吧!

Nginx设置禁止IP访问域名

假设我有一个域名为www.mysite.com,其绑定的主机IP地址为:120.24.23.22。现在我想禁止使用IP访问,当用IP访问的时候会跳转到带域名那种形式的访问。如何实现呢? 其实很简单的

创建www.mysite.com的虚拟主机

创建过程可以参考我前面的文章,这里直接贴出代码:

server {
    listen 80;
    server_name www.mysite.com;

    access_log /home/wwwlogs/access_nginx.log combined;
    root /home/wwwroot/mysite;
    index index.html index.php;

    location /nginx_status {
          stub_status on;
          access_log off;
          allow 127.0.0.1;
          deny all;
    }

    location ~ .*\.(php|php5)?$ {
        #fastcgi_pass remote_php_ip:9000;
        fastcgi_pass unix:/dev/shm/php-cgi.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
    }

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|ico)$ {
        expires 30d;
        access_log off;
    }

    location ~ .*\.(js|css)?$ {
        expires 7d;
        access_log off;
        }
    }

建议一个网站对应一个虚拟主机,虚拟主机最好不要建在nginx.conf配置文件里。

屏蔽IP地址访问的操作步骤

接下来就是进行IP地址禁止访问的操作了,在nginx.conf文件中进行配置。配置信息如下:

server {
       listen 80 default_server;
       server_name _;
       rewrite ^ http://www.rulane.com$request_uri?;
    } 

OK,重启服务器,如果配置没有错误的话,就没什么问题了。当我们通过120.24.23.22访问的时候,会自动跳转到www.mysite.com,这就是我们想要的结果

Nginx日志文件切割Shell脚本

通过crontab调度方式实现

#!/bin/bash
## 零点执行该脚本
## Nginx 日志文件所在的目录
LOGS_PATH=/usr/local/nginx/logs
## 获取昨天的 yyyy-MM-dd
YESTERDAY=$(date -d ”yesterday” +%Y-%m-%d)
## 移动文件
mv ${LOGS_PATH}/access.log ${LOGS_PATH}/access_${YESTERDAY}.log
## 向 Nginx 主进程发送 USR1 信号。USR1 信号是重新打开日志文件
kill -USR1 $(cat /usr/local/nginx/nginx.pid)

通过日志切割的方式实现

cat > /etc/logrotate.d/nginx << EOF
$wwwlogs_dir/*nginx.log {
daily
rotate 5
missingok
dateext
compress
notifempty
sharedscripts
postrotate
    [ -e /var/run/nginx.pid ] && kill -USR1 \`cat /var/run/nginx.pid\`
endscript
}
EOF

CentOS如何分区与挂载磁盘

第一步:列出所有磁盘

命令: ll /dev/disk/by-path

1

提示:如果无法确认数据盘设备名称,请使用df命令来确认系统盘的名称,从而排除挂错盘的情况。

第二步:格式化硬盘

命令: fdisk /dev/sdb

2

注意:图中箭头标注处续手动键入

第三步:创建分区

命令: mkfs.ext4 /dev/sdb1

3

第四步:挂载分区

命令: mkdir /data mount /dev/sdb1 /data (将sdb这个硬盘挂载成为/data)

5

第五步:将信息写入fstab,让系统开启自动挂载

命令: echo "/dev/sdb1 /data ext4 defaults 0 0" >> /etc/fstab

6

linux下导入、导出mysql数据库命令

导出数据库用mysqldump命令(注意mysql的安装路径,即此命令的路径):

  1. 导出数据和表结构:

    mysqldump -u用户名 -p密码 数据库名 > 数据库名.sql

    #/usr/local/mysql/bin/   mysqldump -uroot -p abc > abc.sql
    

    敲回车后会提示输入密码

  2. 只导出表结构

    mysqldump -u用户名 -p密码 -d 数据库名 > 数据库名.sql

    #/usr/local/mysql/bin/mysqldump -uroot -p -d abc > abc.sql
    

    注:/usr/local/mysql/bin/ ---> mysql的data目录

导入数据库

  1. 首先建空数据库

    mysql>create database abc;
    
  2. 导入数据库

    方法一:

    (1)选择数据库

    mysql>use abc;
    

    (2)设置数据库编码

    mysql>set names utf8;
    

    (3)导入数据(注意sql文件的路径)

    mysql>source /home/abc/abc.sql;
    

    方法二:

    mysql -u用户名 -p密码 数据库名 < 数据库名.sql

    #mysql -uabc_f -p abc < abc.sql
    

    建议使用第二种方法导入。

    注意:有命令行模式,有sql命令

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.