欢迎光临
我们一直在努力

linux系统下echo命令的简单用法和实例

u22e阅读(2848)

在CentOS 系统下,通过实例的形式,展现选项和参数的灵活运用,可以简明的了解echo的用法。

一、语法:echo [SHORT-OPTION]… [STRING]… ;echo [选项]…[参数]

作用:将需要的内容输出到终端或者其他文件。

二、实例和选项参数的用法:

(1)文本的直接输出

echo ‘Welcome To CNBLG’

 

(2) 输出变量的值:假设定义一个变量,bl=”Welcome To CNBLGS”

echo $bl

 

解释:bl是定义的变量名,=号后面是赋值,字符串需要用“”括起来。$后面直接跟上变量名即可。

(3)echo 后跟单双引号的区别:

解释:echo后的单引号表示强引用,单引号里面是什么就输出什么,而双引号是弱引用,变量的值会代替变量名输出。

(4)选项中加入 -e ,转义字符可用:

\t:插入制表符,即跳格显示

echo -e “Hello Linux\tHello World”

不加 -e 的对比,如下:

echo “Hello Linux\tHello World”

 

还有,转义字符如下:

\a 发出警告声;

\b 删除前一个字符;

\c 最后不加上换行符号;

\n 换行且光标移至行首;

\r 光标移至行首,但不换行;

\v 与\f相同;

\\ 插入\字符;

\0nn 插入0nn(八进制)代表的ASCII;

(5)输出彩色的命令提示符,显示结果先展示如下:

命令如下:echo -e  “\e[1;32mHello Linux\e[0m”

其中,\e[1;32m是整体转义的部分,数字代表的是字体的颜色和背景的颜色等等。其中例子中数字1 表示字体高亮度(加粗),32表示字体为绿色,0 表示关闭所有属 性。

(6)echo 输出到一个文件,而非终端。

解释:刚开始,test1文件不存在,通过echo输出重定向到test1文件,cat命令表示查看文件内容。

开发者GIT常用命令之二

u22e阅读(2234)

前言

今天继续整理自己的书签,对于开发者而言,版本管理工具是必不可少的,这里我要说的就是git,在我之前一篇git常用命令就已经对git有了一些介绍,这一篇我继续来整理一下,所谓温故而知新。

个人开发者(单独开发)

单独的个人开发者不会与他人交换修补程序,只用到下列命令,独自在单独的代码库上工作:

it-init(1)用来创建新代码库。
git-show-branch(1)用来查看你在哪里。
git-log(1)查看发生过什么。
git-checkout(1)和git-branch(1)用来切换分支。
git-add(1)用来管理索引文件。
git-diff(1)和git-status(1)查看你正在做什么。
git-commit(1)将内容推进现分支
git-reset(1)和git-checkout(1)(带路径名 参数)放弃修改。
git-merge(1)用来合并本地分支
git-rebase(1)用来维护主题分支
git-tag(1)用来给已知点打标签

实例

用Tar包作为一个新代码库的起始点

$ tar zxf frotz.tar.gz
$ cd frotz
$ git init
$ git add . //添加现目录下的所有文件。
$ git commit -m "import of frotz source tree."
$ git tag v2.43 //打一个轻量的无注释的标签

创建一个主题分支并开发

$ git checkout -b alsa-audio //创建一个主题分支。
$ edit/compile/test
$ git checkout -- curses/ux_audio_oss.c //还原你在curses/ux_audio_oss.c文件里搞砸了的修改
$ git add curses/ux_audio_alsa.c //如果你要添加一个新文件是,你需要告诉git;之后,如果你使用git commit -a, 删除和修改就会被捕获
$ edit/compile/test
$ git diff HEAD //查看你正在提交什么修改
$ git commit -a -s //提交你已签署了的所有已测试文件。
$ edit/compile/test
$ git reset --soft HEAD^ //退回到上一个提交,并保留工作树
$ edit/compile/test
$ git diff ORIG_HEAD //查看自从上一个不成熟提交后的修改
$ git commit -a -c ORIG_HEAD //使用原先写过的信息,重做在之前步骤中撤销了的提交
$ git checkout master //切换到主干分支。
$ git merge alsa-audio //把主题分支合并到你的主分支
$ git log --since='3 days ago' //回顾提交记录;其他限制输出的形式也可以合并包含: –max-count=10(显示10个提交),–until=2005-12-10等
$ git log v2.43.. curses/ //只查看影响到在curses/目录里,从v2.43标签开始的修改

 

个人开发者(参与开发)

作为在一个团体项目里参与角色的开发人员,需要学习如何与他人沟通,除了那些单独开发者需要掌握的命令以外,还要使用这些命令。

git-clone从上游代码库填充你的本地代码库。
git-pullgit-fetch从“origin”得到最新的上游代码库。
git-push用来共享代码库,如果你采用cvs风格的代码库工作流的话。
git-format-patch用来准备e-mail提交,如果你使用Linux内核风格的公共论坛工作流的话。

实例

复制上游代码库并在其之上工作。提交修改到上游代码库

$ git clone git://git.kernel.org/pub/scm/.../torvalds/linux-2.6 my2.6
$ cd my2.6
$ edit/compile/test; git commit -a -s //按需重复
$ git format-patch origin //从你的分支中提取补丁文件,用于电子邮件提交
$ git pull //git pull命令默认从“origin”里取得内容并合并到当前的分支中去
$ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 //在拉过内容之后,立即查看在上游仓库中从上次我们检查过之后提交的修改,只检查我们关心的区域
$ git pull git://git.kernel.org/pub/.../jgarzik/libata-dev.git ALL //从一个指定代码库的一个指定分支获取内容并合并
$ git reset --hard ORIG_HEAD //撤销拉操作
$ git gc //从撤销的拉操作中回收残存的对象
$ git fetch --tags //不时地,从origin处获取官方的标签,并保存于.git/refs/tags

推进另一个代码库

$ git clone mothership:frotz frotz //mothership机器在你的home目录下有一个frotz代码库;将它复制,以在satellite机器上启动一个代码库
$ cd frotz
$ git config --get-regexp '^(remote|branch)\.' //复制操作默认设定这些配置变量。它安排git pull去抓取并保存mothership机上的分支到本地的remotes/origin/* 的跟踪分支上
remote.origin.url mothership:frotz
remote.origin.fetch refs/heads/*:refs/remotes/origin/*
branch.master.remote origin
branch.master.merge refs/heads/master
$ git config remote.origin.push \
      master:refs/remotes/satellite/master //安排git push去推送本地的主分支到mothership机的remotes/satellite/master分支
$ edit/compile/test/commit
$ git push origin //推操作会在mothership机的remotes/satellite/master的远程跟踪分支上收藏我们的工作。你可以用此作为一个备用方法  
$ cd frotz
$ git checkout master
$ git merge satellite/master //在mothership机上,将satellite机上已完成的工作合并到master分支去

分支的特定标签

$ git checkout -b private2.6.14 v2.6.14 //创建一个私有分支,基于熟知(但稍许过时的)标签
$ edit/compile/test; git commit -a
$ git checkout master
$ git format-patch -k -m --stdout v2.6.14..private2.6.14 |
  git am -3 -k //在没有正式的“合并”下,向前移植所有private2.6.14分支的修改到master分支上

集成人员

在一个团队项目中担任集成者的是一名相当重要的人员,他接受别人的修改,评审并且集成并且发布结果,供他人使用;除了那些参与者需要的命令之外,还会使用这些命令

git-am用来采用你的贡献者发电邮寄来的补丁文件。
git-pull用来从你的可信任的助手处合并内容。
git-format-patch用来准备并向你的贡献者发送建议选项。
git-revert用来撤销不好的提交。
git-push用来发布最新的内容。

 

实例

我典型的GIT一天

$ git status //查看我正在做什么,如果有的话
$ git show-branch //查看我拥有的主题分支,并考虑它们的完成度。
$ mailx //读邮件,保存合适的,并且保存那些尚未完成的。
s 2 3 4 5 ./+to-apply
s 7 8 ./+hold-linus
q
$ git checkout -b topic/one master
$ git am -3 -i -s -u ./+to-apply //采用它们,交互式地,带着我的签名。
$ compile/test
$ git checkout -b hold/linus && git am -3 -i -s -u ./+hold-linus //按需创建主题分支,还是由我签名采用。
$ git checkout topic/one && git rebase master //为内部的还未合并到主分支,也没有作为稳定分支的一部分公开的主题分支重定基线
$ git checkout pu && git reset --hard next //从接下来开始,每次都重启pu
$ git merge topic/one topic/two && git merge hold/linus //合并仍然在料理中的主题分支
$ git checkout maint
$ git cherry-pick master~4 //向后移植极其重要的修正
$ compile/test
$ git tag -s -m "GIT 0.99.9x" v0.99.9x //创建一个签名的标签
$ git fetch ko && git show-branch master maint 'tags/ko-*' //确保我不会意外将主分支回滚到我已经推出来的内容。
$ git push ko //推出最新内容
$ git push ko v0.99.9x //也推标签

代码库管理

代码库管理员使用下列工具来设置及维护开发者对代码库的访问

git-daemon允许匿名者从代码库下载
git-shell可以被用作为限制登录shell,用于共享中央代码库的用户

update hook howto有一个很好的管理共享中央代码库的实例。

实例

我们假设下面的内容均在/etc/services目录下。

$ grep 9418 /etc/services
git             9418/tcp                
# Git Version Control System

从inetd运行git-daemon来服务于/pub/scm

$ grep git /etc/inetd.conf
git     stream  tcp     nowait  nobody \
  /usr/bin/git-daemon git-daemon --inetd --export-all /pub/scm

实际的配置应该在1行里。

从xinetd运行git-daemon来服务于/pub/scm

$ cat /etc/xinetd.d/git-daemon
# default: off
# description: The git server offers access to git repositories
service git
{
        disable = no
        type            = UNLISTED
        port            = 9418
        socket_type     = stream
        wait            = no
        user            = nobody
        server          = /usr/bin/git-daemon
        server_args     = --inetd --export-all --base-path=/pub/scm
        log_on_failure  += USERID
}

检查xinetd(8)文档并设置,这个文档来自于Fedora系统。其他也许会不一样。 授予开发者只推/拉访问操作权限

$ grep git /etc/passwd //登录shell被设置到/usr/bin/git-shell, 不允许git push和git pull以外的任何操作。用户应该会获得一个访问此机器的ssh权限。
alice:x:1000:1000::/home/alice:/usr/bin/git-shell
bob:x:1001:1001::/home/bob:/usr/bin/git-shell
cindy:x:1002:1002::/home/cindy:/usr/bin/git-shell
david:x:1003:1003::/home/david:/usr/bin/git-shell
$ grep git /etc/shells //在许多发布版本中,/etc/shells需要列出作为一个登录shell需要的内容
/usr/bin/git-shell

CVS风格的共享代码库

$ grep git /etc/group //把开发者置于同一git组中
git:x:9418:alice,bob,cindy,david
$ cd /home/devo.git
$ ls -l //将共享代码库配为可被组写
  lrwxrwxrwx   1 david git    17 Dec  4 22:40 HEAD -> refs/heads/master
  drwxrwsr-x   2 david git  4096 Dec  4 22:40 branches
  -rw-rw-r--   1 david git    84 Dec  4 22:40 config
  -rw-rw-r--   1 david git    58 Dec  4 22:40 description
  drwxrwsr-x   2 david git  4096 Dec  4 22:40 hooks
  -rw-rw-r--   1 david git 37504 Dec  4 22:40 index
  drwxrwsr-x   2 david git  4096 Dec  4 22:40 info
  drwxrwsr-x   4 david git  4096 Dec  4 22:40 objects
  drwxrwsr-x   4 david git  4096 Nov  7 14:58 refs
  drwxrwsr-x   2 david git  4096 Dec  4 22:40 remotes
$ ls -l hooks/update //使用Carl的update-hook实例,这个实例在Documentation/howto/, 讲述了分支策略控制
  -r-xr-xr-x   1 david git  3536 Dec  4 22:40 update
$ cat info/allowed-users //alice和cindy可以推送到主分支,只有bob可以推送进doc-update。david是发布经理,并且是唯一一位可以创建并推送版本标签的人
refs/heads/master       alice\|cindy
refs/heads/doc-update   bob
refs/tags/v[0-9]*       david

支持dumb协议传送的HTTP服务器

dev$ git update-server-info //确保你的info/refes和objects/info/packs是最新的。
dev$ ftp user@isp.example.com //上传到由你的ISP拥有的公共HTTP服务器。
ftp> cp -r .git /home/user/myproject.git

git常用命令之一

u22e阅读(3630)

创建新仓库

创建新文件夹,打开,然后执行
git init
以创建新的 git 仓库。

检出仓库

执行如下命令以创建一个本地仓库的克隆版本:
git clone /path/to/repository
如果是远端服务器上的仓库,你的命令会是这个样子:
git clone username@host:/path/to/repository

工作流

你的本地仓库由 git 维护的三棵“树”组成。第一个是你的 `工作目录`,它持有实际文件;第二个是 `缓存区(Index)`,它像个缓存区域,临时保存你的改动;最后是 `HEAD`,指向你最近一次提交后的结果。

添加与提交

你可以计划改动(把它们添加到缓存区),使用如下命令:
git add
git add *
这是 git 基本工作流程的第一步;使用如下命令以实际提交改动:
git commit -m "代码提交信息"
现在,你的改动已经提交到了 HEAD,但是还没到你的远端仓库。

推送改动

你的改动现在已经在本地仓库的 HEAD 中了。执行如下命令以将这些改动提交到远端仓库:
git push origin master
可以把 master 换成你想要推送的任何分支。

如果你还没有克隆现有仓库,并欲将你的仓库连接到某个远程服务器,你可以使用如下命令添加:
git remote add origin
如此你就能够将你的改动推送到所添加的服务器上去了。

 

分支

分支是用来将特性开发绝缘开来的。在你创建仓库的时候,master 是“默认的”。在其他分支上进行开发,完成后再将它们合并到主分支上

创建一个叫做“feature_x”的分支,并切换过去:
git checkout -b feature_x
切换回主分支:
git checkout master
再把新建的分支删掉:
git branch -d feature_x
除非你将分支推送到远端仓库,不然该分支就是 不为他人所见的:
git push origin

 

更新与合并

要更新你的本地仓库至最新改动,执行:
git pull
以在你的工作目录中 获取(fetch) 并 合并(merge) 远端的改动。
要合并其他分支到你的当前分支(例如 master),执行:
git merge 两种情况下,git 都会尝试去自动合并改动。不幸的是,自动合并并非次次都能成功,并可能导致 冲突(conflicts)。 这时候就需要你修改这些文件来人肉合并这些 冲突(conflicts) 了。改完之后,你需要执行如下命令以将它们标记为合并成功:
git add
在合并改动之前,也可以使用如下命令查看:
git diff

标签

在软件发布时创建标签,是被推荐的。这是个旧有概念,在 SVN 中也有。可以执行如下命令以创建一个叫做 1.0.0 的标签:
git tag 1.0.0 1b2e1d63ff
1b2e1d63ff 是你想要标记的提交 ID 的前 10 位字符。使用如下命令获取提交 ID:
git log
你也可以用该提交 ID 的少一些的前几位,只要它是唯一的

替换本地改动

假如你做错事(自然,这是不可能的),你可以使用如下命令替换掉本地改动:
git checkout --
此命令会使用 HEAD 中的最新内容替换掉你的工作目录中的文件。已添加到缓存区的改动,以及新文件,都不受影响。

假如你想要丢弃你所有的本地改动与提交,可以到服务器上获取最新的版本并将你本地主分支指向到它:
git fetch origin
git reset --hard origin/master

 

有用的贴士

内建的图形化 git:
gitk
彩色的 git 输出:
git config color.ui true
显示历史记录时,只显示一行注释信息:
git config format.pretty oneline
交互地添加文件至缓存区:
git add -i

git配置全局信息

git config --global user.name "9958"
git config --global user.email "694178563@qq.com"

git生成public_key

ssh-keygen -t rsa -C "694178563@qq.com"

git克隆,指定维度

git clone git://xxoo --depth 1

git添加远程库

git remote add origin git@github.com:9958/helloword.git 添加远程库
git push -u origin master 强推本地库

git添加一个空目录,即只同步本空目录

# Ignore everything in this directory
*
# Except this file
!.gitignore

git恢复指定文件的历史版本

#查看相应版本号
git log --pretty=oneline 指定文件
#重置版本号
git reset git版本号 指定文件
#检出指定文件
git checkout -- 指定文件
7、查看版本详细日志

git show git版本号

输出最后一次提交的改变

这个命令,我经常使用它 来发送其他没有使用git的人来检查或者集成所修改的。它会输出最近提交的修改类容到一个zip文件中。

git archive -o ../updated.zip HEAD $(git diff --name-only HEAD^)

仅回退commit到某个版本

git reset --soft git版本号
git log --all 可以查看reset之前的log
git reflog

Nginx配置文件nginx.conf中文详解

u22e阅读(2318)

定义Nginx运行的用户和用户组

user www www;

nginx进程数,建议设置为等于CPU总核心数.

worker_processes 8;

全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]

error_log /var/log/nginx/error.log info;

进程文件

pid /var/run/nginx.pid;

一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。

worker_rlimit_nofile 65535;

工作模式与连接数上限

events
{
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; 
epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,
如果跑在FreeBSD上面,就用kqueue模型。
use epoll;
#单个进程最大连接数(最大连接数=连接数*进程数)
worker_connections 65535;
}

设定http服务器

http
{
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型
#charset utf-8; #默认编码
server_names_hash_bucket_size 128; #服务器名字的hash表大小
client_header_buffer_size 32k; #上传文件大小限制
large_client_header_buffers 4 64k; #设定请求缓
client_max_body_size 8m; #设定请求缓
sendfile on; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,
对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,
以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。
tcp_nopush on; #防止网络阻塞
tcp_nodelay on; #防止网络阻塞
keepalive_timeout 120; #长连接超时时间,单位是秒

#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。下面参数看字面意思都能理解。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

#gzip模块设置
gzip on; #开启gzip压缩输出
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 16k; #压缩缓冲区
gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; #压缩等级
gzip_types text/plain application/x-javascript text/css application/xml;
#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,
但是会有一个warn。
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用

upstream blog.ha97.com {
#upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,
权值越高被分配到的几率越大。
server 192.168.80.121:80 weight=3;
server 192.168.80.122:80 weight=2;
server 192.168.80.123:80 weight=3;
}

虚拟主机的配置

server
{
#监听端口
listen 80;
#域名可以有多个,用空格隔开
index index.html index.htm index.php;
root /data/www/ha97;
location ~ .*.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
#图片缓存时间设置
location ~ .*.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 10d;
}
#JS和CSS缓存时间设置
location ~ .*.(js|css)?$
{
expires 1h;
}

日志格式设定

log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
#定义本虚拟主机的访问日志
access_log /var/log/nginx/ha97access.log access;

#对 "/" 启用反向代理
location / {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是一些反向代理的配置,可选。
proxy_set_header Host $host;
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
}

设定查看Nginx状态的地址

location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file conf/htpasswd;
#htpasswd文件的内容可以用apache提供的htpasswd工具来产生。
}

#本地动静分离反向代理配置
#所有jsp的页面均交由tomcat或resin处理
location ~ .(jsp|jspx|do)?$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
}
#所有静态文件由nginx直接读取不经过tomcat或resin
location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$
{ expires 15d; }
location ~ .*.(js|css)?$
{ expires 1h; }
}
}

其他案例分享


1.thinkphp PATH_INFO支持

可以考虑通过配置URL重写规则来模拟实现,可以参考 thinkphp 隐藏index.php

2.thinkphp 隐藏index.php

thinkphp config配置:

'URL_MODEL'          => '2', //URL模式

nginx rewrite配置:

location / { 
   if (!-e $request_filename) {
   rewrite  ^(.*)$  /index.php?s=$1  last;
   break;
    }
}

如果你的ThinkPHP安装在二级目录,Nginx的伪静态方法设置如下,其中youdomain是所在的目录名称

location /youdomain/ {
        if (!-e $request_filename){
            rewrite  ^/youdomain/(.*)$  /youdomain/index.php?s=$1  last;
        }
    }

 

LNMP 配置NGINX 支持THINKPHP PATHINFO模式

u22e阅读(2678)

在支付宝回调,和微信回调方法中。正常不支持参数中带 ?s= ,所以要开启THINKPHP 的PATHINFO模式 。

THINKPHP 官方论坛 和网络上很多NGINX配置教程不是太完善的。

我一直比较喜欢使用lnmp.org配置服务器环境。

所以本文将介绍 LNMP 配置NGINX 支持THINKPHP  PATHINFO模式 。

方法很简单 。

1,修改PHP.INI 支持 PHPINOF

PHP配置文件:/usr/local/php/etc/php.ini

更改php.ini
找到:cgi.fix_pathinfo=0
更改为:cgi.fix_pathinfo=1

2.修改nginx对应配置文件

/usr/local/nginx/conf/vhost/你的域名配置文件

去掉include pathinfo的#,在try_files前加#;

3.重启lnmp即可。

lnmp restart

这个是真实有用的方法,希望能帮助你。

Nginx下实现pathinfo及ThinkPHP的URL Rewrite模式支持

u22e阅读(2666)

打开Nginx的配置文件 /usr/local/nginx/conf/nginx.conf 一般是在这个路径,根据你的安装路径可能有所变化。如果你配置了vhost,而且只需要你这一个vhost支持pathinfo的话,可以直接打开你的vhost的配置文件。找到类似如下代码(不同版本的nginx可能稍有不同,但是相差不会很远):

location ~ .*.(php|php5)?$
{
#原有代码
}

修改成以下代码:

#去掉$是为了不匹配行末,即可以匹配.php/,以实现pathinfo
#如果你不需要用到php5后缀,也可以将其去掉
location ~ .php
{
#原有代码

#定义变量 $path_info ,用于存放pathinfo信息
set $path_info "";
#定义变量 $real_script_name,用于存放真实地址
set $real_script_name $fastcgi_script_name;
#如果地址与引号内的正则表达式匹配
if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
#将文件地址赋值给变量 $real_script_name
set $real_script_name $1;
#将文件地址后的参数赋值给变量 $path_info
set $path_info $2;
}
#配置fastcgi的一些参数
fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;
}

这样,nginx服务器就可以支持pathinfo了。但是如果要支持ThinkPHP的URL_MODE设置为2的模式,还需要配置rewrite规则。找到access_log语句,在其上方加上以下语句:

#如果请求既不是一个文件,也不是一个目录,则执行一下重写规则
if (!-e $request_filename)
{
#地址作为将参数rewrite到index.php上。
rewrite ^/(.*)$ /index.php/$1;
#若是子目录则使用下面这句,将subdir改成目录名称即可。
#rewrite ^/subdir/(.*)$ /subdir/index.php/$1;
}

最后,保存配置文件,重启nginx服务,把ThinkPHP的URL_MODEL设置为2,访问下你的页面,如果能正常访问,恭喜你pathinfo配置成功了^_^

Linux 开机显示welcome to emergency mode 的解决方法

u22e阅读(4501)

今天安装软件,重启之后发现无法进系统了,显示emergency mode.


后来发现是/etc/fstab中挂在/sda3分区挂不上去,只要把那行注释掉就可以正常登录。

UUID=94e3613e-45a8-4e6a-b791-e573843a432d / xfs defaults 0 0
UUID=568859bd-d5f5-4194-b413-7792ec1a5f2e /boot xfs defaults 0 0
#UUID=bc458cbb-6958-412d-9c5f-c949eceedbd1 /data1 xfs defaults 0 0
UUID=6166065b-7bfb-497d-9bd4-1676f3422ddf swap swap defaults 0 0

注释掉之后就可看到/data1分区没有了

[root@u22e ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda5 2.2T 1.7G 2.2T 1% /
devtmpfs 3.8G 0 3.8G 0% /dev
tmpfs 3.8G 0 3.8G 0% /dev/shm
tmpfs 3.8G 8.6M 3.8G 1% /run
tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup
/dev/sda2 494M 162M 332M 33% /boot
tmpfs 770M 0 770M 0% /run/user/0

 

基于Docker安装WordPress博客系统

u22e阅读(8452)

Docker在现有云计算虚拟化中是非常火的一个项目,那么他和虚拟化有什么不同呢

从上图来看,好像和我们之前说到的虚拟化并没有什么不同,但这里需要说明的是在各guest主机上,是没有操作系统的,他们共用Host主机上的内核空间,只对用户空间进行了隔离。

因此在这种环境下我们不把他称为虚拟化而称作容器。

此种方式的实现主要基于了linux内核自带的两项技术,分别是namespace和cgroup,下面解释下它们分别做了什么

Namespace

PID NameSpace:PID隔离。
Network NameSpace:网络设备、网络栈、端口等网络资源隔离。
User NameSpace:用户和用户组资源隔离。
IPC NameSpace:信号量、消息队列和共享内存的隔离。
UTS NameSpace:主机名和域名的隔离。
Mount NameSpace:挂载点(文件系统)隔离。

Cgroup

Resource limitation:资源限制。
Prioritization:优先级控制。
Accounting:审计和统计,主要为计费。
Control:挂起进程,恢复进程。
依靠上面所提到的技术,我们应该明白已经完全可以隔离用户空间了,甚至还可以进行对各空间的资源限定,当然要想正常使用,还需要依赖下面2样技术,也是内核所带的功能。

UnionFS:把不同的物理位置的目录合并到同一个目录中。(打个比方说就是把一个磁盘挂载至一个目录中,我们知道如果正常情况下挂载点里面所拥有的文件会被隐藏,基于此项技术,可以同时看到,也可以修改,但此种修改并不在原文件上生效,而是相当于在磁盘中新建的数据)

Device mapper:用于在内核中支持逻辑卷管理的通用设备映射机制

Docker就是依靠以上技术进行的一步封装,以便人们可以更方便的使用,就像很久前,我们提到的linux各发行版一样,如果你想学习linux,却只提供给你一个内核,相信没有多少人安装成功。

Docker于2013年发布,go语言研发,并遵从apache开原协议,C/S架构。

Docker的重要组件:

registry:主要提供各镜像文件(repository),以及镜像的元数据信息,还包括给各镜像创建索引分类(index)。

container:运行于host主机上的实例。

volume:在容器运行的应用程序,如果关闭,会删除容器中保存的数据,因此volume主要给容器和物理磁盘作一个映射关系,这样每个容器关闭或删除时上面的数据都会存在。

link:各实例的关联关系,类似于定义依赖关系。

docker通常用于运行单个任务,单个任务结束,即会退出实例。

下面就来简单演示下基于docker容器实现的lamp部署wordpress

配置好extras yum源

[root@localhost ~]# yum -y install docker

[root@localhost ~]# docker pull centos

直接安装并下载centos的image镜像,

这里我已经有了两个镜像,一个是官网下的centos镜像,然后自己配置了一下yum源,新生成了一个镜像否则下载太慢。

下面就用两种方式生成image来完成对web和mariadb的部署。

先来web吧

[root@localhost ~]# docker run -it –rm centos:7 /bin/bash

-i:交互式运行

-t:打开一个伪终端

–rm:退出后直接删除实例

centos:7  指明运行的镜像

/bin/bash:运行的程序

[root@feba71b34795 /]# yum -y install httpd php php-mysql

直接安装PHP HTTPD和php链接mysql所需要的包

另外打开一个终端。接着使用docker ps 查看启动的容器ID,并使用docker commit 指明容器ID 并给此容器定义一个名字就生成新镜像了,使用docker images可以查看到。我们之前起的实例就可以关闭了。

重新起一个实例

-v:将host主机的/web目录挂载至/var/www/html  因为之前什么都没改,apache默认的根目录就在此,我们直接将此目录挂载出来。

-d:后台运行

-p:将本机的80端口映射为虚拟机的80端口,其实就是docker自己添加一条dnat规则

/sbin/http: 运行此命令 -DFOREGROUND 使其运行至前台,我们前面提到过,docker每个实例的生命周期为一个任务结束,所以要让他一直占据前台。

接着在映射出的目录里面创建一个测试页,接着就可以尝试访问看能否访问到。

可以看到我们直接访问虚拟机的80端口就能访问到我们提供的测试页了。 我们先不管这台容器了。

接着我们用dockerfile创建一个mariadb的实例出来。

[root@localhost mariadb]# docker build -f ./mariadb.df -t centos7:mariadb ./

-f :指明构建所用到的文件

-t :指明在images里面看到的标签

./:指明工作的目录

这里我是新建一个目录 然后在里面创建的文件

注意 这里是两个文件 一个是构建的文件,一个是脚本。

在这里折腾许久,一直想直接一个文件写完,添加授权尝试了很多种方法都不行,会直接报没有mysql命令 ,要不就是语法错误,后来看了mariadb官方提供的镜像,发现他也是通过脚本来执行的,于是自己写了个简单的脚本。这里还有莫名其妙的地方,那就是后台启动了mariadb过后还是需要sleep两秒才能执行成功。最后呢 ,授权完了,任务也就完了,实例还会自己关,就偷了个鸡,tail -f 让他一直在前台刷新mariadb自己的日志。

接着启动实例吧

启动实例并且查看运行中的实例 确定mariadb和http都在运行状态, 并且也已经看到了mariadb已经把初始化的目录正确的写入到host主机了。

接着去解压wordpress到host主机上的/web目录应该就完成了~

这里需要注意的是,我们不知道mariadb的地址,可以使用下面的命令查看

[root@localhost mariadb]# docker  inspect -f {{.NetworkSettings.IPAddress}} 3b7a7e94bb8e
172.17.0.3

后面的3b7a。。是容器ID

也可以不使用-f 显示容器的所有参数,如果只想看某一项就可以使用上面的格式查看

接着在wordpress的配置页面里面填上这些就可以了。

这里可以看到已经可以创建

centos7忘记密码的解决方法

u22e阅读(2229)

centos7/rhel7进入单用户方式和重置密码方式发生了较大变化,GRUB由变成了GRUB2,b引导变成了ctrl+x引导。确解方法有rd.break和init两种。

一、rd.break重置密码

1、启动的时候,在启动界面,相应启动项,内核名称上按“e”;

2、进入后,找到linux16开头的地方,按“end”键到最后,输入rd.break,按ctrl+x进入。或者打到linux16 中ro的位置,执行ctrl +k 删除到行尾,再增加rd.break;

3、进去后输入命令mount,发现根为/sysroot/,并且不能写,只有ro=readonly权限;

4、mount -o remount,rw /sysroot/,重新挂载,之后mount,发现有了r,w权限;

5、chroot /sysroot/ 改变根;

(1)echo redhat|passwd –stdin root 修改root密码为redhat,或者输入passwd,交互修改;

(2)还有就是先cp一份,然后修改/etc/shadow文件

6、touch /.autorelabel 这句是为了selinux生效,重新扫描磁盘标签,autorelabel 是一个隐藏文件,前面有点,而且一定不能写错,不然reboot时会卡住。

7、ctrl+d 退出

8、然后reboot

至此,密码修改完成

二、init重置密码

1. 启动系统,并在GRUB2启动屏显时,按下e键进入编辑模式。

2. 在linux16/linux/linuxefi所在参数行尾添加以下内容:init=/bin/sh

3. 按Ctrl+x启动到shell。

4. 挂载文件系统为可写模式:mount –o remount,rw /

5. 运行passwd,并按提示修改root密码。

6. 如何之前系统启用了selinux,必须运行以下命令,否则将无法正常启动系统:touch /.autorelabel

7. 运行命令exec /sbin/init来正常启动,或者用命令exec /sbin/reboot重启

linux系统利用awk 不排序删除重复行

u22e阅读(2314)

实例如下

1 2 3
1 2 3
1 2 4
1 2 3
1 2 5

这里假设我要处理的文件如上面的例子。不难看出里面有三行123,而我想所有的排列顺序不变,遇到重复的就自动删除。想实现的最终效果为:

1 2 3
1 2 4
1 2 5

而如果使用sort加uniq进行排序的话,这个文档是看不出有什么不妥,不过我要处理的是用户名与密码一行行对应好的,如果使用sort + uniq处理的话,用户名都排到一块了,密码也又都跑到一块了。这样就分不出来那个是那个了。 而使用的脚本很简单:

awk '!x[$0]++' filename 

注:此处的x只是一个数据参数的名字而已,随你用a、b、c、d都行。

简要解释一下,awk 的基本执行流程是,对文件的每一行,做一个指定的逻辑判断,如果逻辑判断成立,则执行指定的命令;如果逻辑判断不成立,则直接跳过这一行。

我们这里写的 awk 命令是!x[$0]++,意思是,首先创建一个 map 叫x,然后用当前行的全文$0作为 map 的 key,到 map 中查找相应的 value,如果没找到,则整个表达式的值为真,可以执行之后的语句;如果找到了,则表达式的值为假,跳过这一行。由于表达式之后有++,因此如果某个 key 找不到对应的 value,该++操作会先把对应的 value 设成 0,然后再自增成 1,这样下次再遇到重复的行的时候,对应的 key 就能找到一个非 0 的 value 了。

注:该处的map类似于array数组,只不过在awk中叫array不恰当。

awk Oneline中我们也学到过,awk 的流程是先判断表达式,表达式为真的时候就执行语句,可是我们前面写的这个 awk 命令里只有表达式,没有语句,那我们执行什么呢?原来,当语句被省略的时候,awk 就执行默认的语句,即打印整个完整的当前行。就这样,我们通过这个非常简短的 awk 命令实现了去除重复行并保留原有文件顺序的功能。

当然,我们也可以对该例进行下改变,通过判断某列的值相同,就只保留首行。

awk ‘!a[$3]++’ filename
删除第三列重复的行
awk ‘!a[$NF]++’ filename
删除最后一列重复的行
如何在去除重复行时对空白行不做处理,我这里总结了三种实现方法(都是仅使用awk工具),具体如下(为了便于区分,这里我使用nl命令加了行号):

[root@u22e ~]# cat a.txt |nl -b a #原文件
1 1 2 3
2 1 2 3
3
4
5 1 2 4
6 1 2 3
7
8
9 1 2 5
[root@u22e ~]# awk '!NF || !a[$0]++' a.txt |nl -b a #方法一
1 1 2 3
2
3
4 1 2 4
5
6
7 1 2 5
[root@u22e ~]# awk '!NF {print;next} !($0 in a) {a[$0];print}' a.txt |nl -b a #方法二
1 1 2 3
2
3
4 1 2 4
5
6
7 1 2 5
[root@u22e ~]# awk '!/./ || !a[$0]++' a.txt |nl -b a #方法三
1 1 2 3
2
3
4 1 2 4
5
6
7 1 2 5
[root@u22e ~]#