Linux系统下find命令递归删除查找目录的方法

本文将会讲述如何使用linux系统下的find查找命令来查找目录或文件,并将查找到的所有文件和目录递归删除掉。

Linux find 命令递归删除非空目录

通常情况下我们会想到find命令里的删除操作是使用-delete选项,但是使用该选项只能删除空目录的文件,不能递归删除该目录里的其它文件。如下面的例子:

$ ls dir1
test1
$ find ./ -name "dir1" -type d -delete
find: cannot delete `./dir1': Directory not empty

可以使用下面的Linux find 命令删除非空目录,如:

$ find ./ -name “dir1” -type d -exec rm -rf {} +

或者

$ find ./ -name “dir1” -type d -exec rm -rf  \;

Linux find 命令结合xargs命令实现删除非空目录

删除当前目录下的所有空目录

$ find ./ -type d -empty -print0 |xargs -0 -i {} rm -rf  “{}”

删除当前目录下所有以“dir”开头的目录

$ find ./ -type d -name “dir*” -print0 |xargs -0 -I {} rm -rf “{}”

 

Linux系统下通过bash shell脚本实现倒计时的方法

本文主要讲述如何在linux系统下通过bash shell 脚本来实现在屏幕上输出倒计时的方法。
先来看看实现后的脚本,如下:

#!/bin/bash
 # script name: ctimer.sh
 # Author: osetc.com
 # --------------------------------------------------------
row=2
 col=2
 countdown() {
 msg="starting..."
 clear
 tput cup $row $col
 echo -n "$msg"
 l=${#msg}
 l=$(( l+$col ))
 for i in {30..1}
 do
     tput cup $row $l
     echo -n "$i"
     sleep 1
 done
 }
 countdown

首先我们定义了一个名为countdown的shell 函数,在函数里定义了一个msg变量用于在屏幕上显示倒计时信息,clear 命令用于清除屏幕上的历史输出信息,tput cut 命令用于设置屏幕输出信息的位置,最后通过for循环来实现倒计时,并更新输出信息的位置。
执行上面的脚本

$bash ctimer.sh
 Starting...30

 

Linux系统下批量升级LXD容器里的虚拟机的方法

本文将会讲述如何在linux 系统下自动升级LXD容器里的所有的虚拟机。
下面我们通过两种方法实现自动升级所有虚拟机:

方法一:使用shell 脚本来升级

手动的升级命令是:

/usr/bin/lxc exec 虚拟机名 -- /usr/bin/apt-get -y upgrade (ubuntu系统)
/usr/bin/lxcexec 虚拟机名  -- /usr/bin/yum -y update    (centos 系统)

下面来创建bash shell 脚本来自动升级所有的虚拟机:

#!/bin/bash
#脚本名:vmUpgrade.sh
#--------------------------------
cmd="$@"for i in 虚机1 虚机2 虚机3 虚机4
do
echo "[*** $i ***]"
/usr/bin/lxc exec $i -- $cmd
done

下面就可以调用脚本来升级vm了,执行下面的命令:
Ubuntu 系统:

$ ./vmUpgrade.sh /usr/bin/apt-get update
$ ./vmUpgrade.sh /usr/bin/apt-get -y upgrade

Centos 系统:

$ ./vmUpgrade.sh /usr/bin/yum -y update

方法二:使用Ansible 自动化工具

1# 安装ansible 工具
执行命令:

$ sudo apt-get install ansible

命令输出:

正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
下列软件包是自动安装的并且现在不需要了:
gyp javascript-common libjs-inherits libjs-jquery libjs-node-uuid libjs-underscore libnvpair1linux libssl-dev libssl-doc libuutil1linux libuv1-dev
libzfs2linux libzpool2linux zfs-doc zlib1g-dev
使用'apt autoremove'来卸载它(它们)。
将会同时安装下列软件:
ieee-data libyaml-0-2 python-crypto python-ecdsa python-httplib2 python-jinja2 python-markupsafe python-netaddr python-paramiko python-selinux
python-six python-yaml
建议安装:
sshpass python-crypto-dbg python-crypto-doc python-jinja2-doc ipython python-netaddr-docs
下列【新】软件包将被安装:
ansible ieee-data libyaml-0-2 python-crypto python-ecdsa python-httplib2 python-jinja2 python-markupsafe python-netaddr python-paramiko python-selinux
python-six python-yaml
升级了 0 个软件包,新安装了 13 个软件包,要卸载 0 个软件包,有 5 个软件包未被升级。
需要下载 2,903 kB 的归档。
解压缩后会消耗 17.6 MB 的额外空间。
您希望继续执行吗? [Y/n] y
获取:1 http://archive.ubuntu.com/ubuntu xenial/main amd64 libyaml-0-2 amd64 0.1.6-3 [47.6 kB]
获取:2 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 python-crypto amd64 2.6.1-6ubuntu0.16.04.2 [246 kB]
获取:3 http://archive.ubuntu.com/ubuntu xenial/main amd64 python-markupsafe amd64 0.23-2build2 [15.5 kB]
获取:4 http://archive.ubuntu.com/ubuntu xenial/main amd64 python-jinja2 all 2.8-1 [109 kB]
获取:5 http://archive.ubuntu.com/ubuntu xenial/main amd64 python-six all 1.10.0-3 [10.9 kB]
获取:6 http://archive.ubuntu.com/ubuntu xenial/main amd64 python-ecdsa all 0.13-2 [34.0 kB]
获取:7 http://archive.ubuntu.com/ubuntu xenial/main amd64 python-paramiko all 1.16.0-1 [109 kB]
获取:8 http://archive.ubuntu.com/ubuntu xenial/main amd64 python-yaml amd64 3.11-3build1 [105 kB]
获取:9 http://archive.ubuntu.com/ubuntu xenial/main amd64 python-httplib2 all 0.9.1+dfsg-1 [34.2 kB]
获取:10 http://archive.ubuntu.com/ubuntu xenial/main amd64 ieee-data all 20150531.1 [830 kB]
获取:11 http://archive.ubuntu.com/ubuntu xenial/main amd64 python-netaddr all 0.7.18-1 [174 kB]
获取:12 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 ansible all 2.0.0.2-2ubuntu1 [1,016 kB]
获取:13 http://archive.ubuntu.com/ubuntu xenial/universe amd64 python-selinux amd64 2.4-3build2 [173 kB]
已下载 2,903 kB,耗时 10秒 (287 kB/s)
正在选中未选择的软件包 libyaml-0-2:amd64。
(正在读取数据库 ... 系统当前共安装有 69061 个文件和目录。)
正准备解包 .../libyaml-0-2_0.1.6-3_amd64.deb  ...
正在解包 libyaml-0-2:amd64 (0.1.6-3) ...
正在选中未选择的软件包 python-crypto。
正准备解包 .../python-crypto_2.6.1-6ubuntu0.16.04.2_amd64.deb  ...
正在解包 python-crypto (2.6.1-6ubuntu0.16.04.2) ...
正在选中未选择的软件包 python-markupsafe。
正准备解包 .../python-markupsafe_0.23-2build2_amd64.deb  ...
正在解包 python-markupsafe (0.23-2build2) ...
正在选中未选择的软件包 python-jinja2。
正准备解包 .../python-jinja2_2.8-1_all.deb  ...
正在解包 python-jinja2 (2.8-1) ...
正在选中未选择的软件包 python-six。
正准备解包 .../python-six_1.10.0-3_all.deb  ...
正在解包 python-six (1.10.0-3) ...
正在选中未选择的软件包 python-ecdsa。
正准备解包 .../python-ecdsa_0.13-2_all.deb  ...
正在解包 python-ecdsa (0.13-2) ...
正在选中未选择的软件包 python-paramiko。
正准备解包 .../python-paramiko_1.16.0-1_all.deb  ...
正在解包 python-paramiko (1.16.0-1) ...
正在选中未选择的软件包 python-yaml。
正准备解包 .../python-yaml_3.11-3build1_amd64.deb  ...
正在解包 python-yaml (3.11-3build1) ...
正在选中未选择的软件包 python-httplib2。
正准备解包 .../python-httplib2_0.9.1+dfsg-1_all.deb  ...
正在解包 python-httplib2 (0.9.1+dfsg-1) ...
正在选中未选择的软件包 ieee-data。
正准备解包 .../ieee-data_20150531.1_all.deb  ...
正在解包 ieee-data (20150531.1) ...
正在选中未选择的软件包 python-netaddr。
正准备解包 .../python-netaddr_0.7.18-1_all.deb  ...
正在解包 python-netaddr (0.7.18-1) ...
正在选中未选择的软件包 ansible。
正准备解包 .../ansible_2.0.0.2-2ubuntu1_all.deb  ...
正在解包 ansible (2.0.0.2-2ubuntu1) ...
正在选中未选择的软件包 python-selinux。
正准备解包 .../python-selinux_2.4-3build2_amd64.deb  ...
正在解包 python-selinux (2.4-3build2) ...
正在处理用于 man-db (2.7.5-1) 的触发器 ...
正在设置 libyaml-0-2:amd64 (0.1.6-3) ...
正在设置 python-crypto (2.6.1-6ubuntu0.16.04.2) ...
正在设置 python-markupsafe (0.23-2build2) ...
正在设置 python-jinja2 (2.8-1) ...
正在设置 python-six (1.10.0-3) ...
正在设置 python-ecdsa (0.13-2) ...
正在设置 python-paramiko (1.16.0-1) ...
正在设置 python-yaml (3.11-3build1) ...
正在设置 python-httplib2 (0.9.1+dfsg-1) ...
正在设置 ieee-data (20150531.1) ...
正在设置 python-netaddr (0.7.18-1) ...
正在设置 ansible (2.0.0.2-2ubuntu1) ...
正在设置 python-selinux (2.4-3build2) ...
正在处理用于 libc-bin (2.23-0ubuntu9) 的触发器 ...

2# 创建一个yml个格式的ansible playbook 文件(update.yml),加入下面的内容

# Update host running on Debian/Ubuntu
- name: Updating host using apt
apt:
update_cache: yes
upgrade: dist
#
# Now update VMs powered by Debian/Ubuntu Linux
#
- name: Run lxc to update debian/ubuntu vms repo
command: /usr/bin/lxc exec {{ item }} -- /usr/bin/apt-get -y update
with_items:
- ubuntuvm1
- debianvm2
- ubuntuvm3
- name: Run lxc to upgrade debian/ubuntu vms pacakges
command: /usr/bin/lxc exec {{ item }} -- /usr/bin/apt-get -y upgrade
with_items:
- ubuntuvm1
- debianvm2
- ubuntuvm3
#
# Now update VMs powered by CentOS 7 Linux
#
- name: Run lxc to upgrade centos vms
command: /usr/bin/lxc exec {{ item }} -- /usr/bin/yum -y update
with_items:
- centosvm4
- centosvm5
- centosvm6

3# 执行下面的ansible-playbook命令,执行升级操作

$ ansible-playbook -i /etc/ansible/hosts update.yml

 

Linux系统下删除包含特定字符或数字的方法

本文将会讲述如何在linux 系统下通过删除rm命令来删除包含特定字符或数字的方法。本文主要针对linux初学者。
在linux下面删除文件或目录的命令是rm, 如果想删除特定模式的文件或者目录,那么就需要使用linux命令中特有的通配符。
比如下面的几个通配符模式:
* : 可以匹配任意字符串
*b*: 可以匹配包含字符”b”的任意字符串
*2*: 可以匹配包含数字”2”的任意字符串
*.[ab]: 可以匹配任意以字母a 或b 结尾的字符串
*[cd]*:可以匹配包含字母‘c’或 ‘d’的任意字符串
: 可以匹配任意一个单一字符

实例:

显示出当前目录下所有的以包含test 的文件

$ ls *test*
test2  test30  test5

显示以数字1结尾的文件

$ ls *1
text1

显示所有以“test”开头的文件

$ ls test*
test2  test30  test5

删除所有以“test”开头的文件

$ rm -v test*
removed 'test2'
removed 'test30'
removed 'test5'

 
 

shell:BASH 的目录切换

By WEN Pingbo ofTinyLab.org

2015/06/02

在 BASH 中你用的最多的命令是什么?这绝对非 cd 莫属(ls 也是个潜力股,暂时做老二吧)。所以在这篇文章中,我们聊聊如何高效的在 BASH 中切换目录。

往后切换目录

回退目录,正规的做法是 cd ..。但网上的小伙伴很有才,发明了更简洁实用的命令。这里把它搬过来,其实我自己也一直这么用的:

alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'

甚至可以定义5点的别名,但感觉用到的几率不大。有了这些别名,就可以愉快的用 N 个点来回退 N 级目录。

其实在进行目录切换时,BASH 默认会把上一个目录记录在 OLDPWD。可以用 cd –,或者 cd $OLDPWD来在两个目录之间来回切换。这在两个不同的目录树下,很有作用。

往前切换目录

进入指定的目录,这个没什么特别的技巧了。老老实实用 cd /path/to/dir来做吧。虽然目的地咱不能省,还是可以偷点懒的。

CDPATH

我们可以利用 CDPATH 定义 cd命令的 base 目录,然后就可以直达目的地,而不用在前面加一堆父目录。比如:

vim: BASH 的目录切换
vim: BASH 的目录切换

不过这个方法不是很灵活,且有副作用。前段时间,我机器上编译 Android,死活过不去,最后发现是这货搞的鬼。所以,玩玩可以,在生产环境慎用!

CDSPELL

在 BASH 中打开 cdspell( shopt -s cdspell),可以在你目标目录写错的时候,BASH 能自动帮你矫正,省了重新敲一遍。效果如下:

vim: BASH 的目录切换
vim: BASH 的目录切换

这个还是很有用的,建议打开。

目录堆栈

前面讲的大多数是两个目录之间的切换,我们可以简单的用一个变量 OLDPWD 来记录。如果涉及到多个目录,为了记录之前目录切换的历史记录,就得另起一套机制了。而 BASH 就为我们提供了这样一套机制 – “目录堆栈(dirs/pushd/popd)”。其运行机制就是一个堆栈,先进先出。我们可以用 pushd dir来 push 对应的目录路径,用 popd来弹出栈顶的目录,用 dirs可以查看当前堆栈的内容。这个堆栈,在各个 BASH 实例之间是不通用的。也就是说在当前 BASH 中 push 的目录,不会影响其他 BASH。每开一个 BASH,都会初始化一个这样的堆栈。

有的时候,在脚本中需要临时保存当前工作路径,以便回溯。这个时候就可以利用这个目录堆栈了。

模拟 Windows Explorer (icd)

之前,我一直纠结在为什么 BASH 只能记录两层目录。当你的工作目录层数比较多的时候,你经常需要多次 cd ..来把工作目录回退 A 目录,然后又要进入 B 目录,再进入 C 目录,最后还要回到 A 目录。尽管前面已经偷了很多懒,还是显得很繁琐。而我的想法是把 Windows 的文件浏览器中前进和后退功能添加到 BASH 中,就像 nautilus 和 各大浏览器做的那样。

为了实现这种效果,首先得记录每次进入的目录路径。这个 BASH 自带的目录堆栈可以做,但是 BASH 在 popd 之后,就把栈顶的路径删除了。这样就导致后退后,无法再前进了。所以得额外定义一套机制来保存目录记录。这里我用一个文件来存放,文件的第一行是记录的路径总数,第二行是当前所在的目录位置,而之后的的每一行就代表一条目录记录。比如:

3
2
/home
/home/wenpingbo
/var/log

这样,后退可以到 /home,前进可以到 /var/log。另外,为了保证各个 BASH 之间互不干扰,还得引入 session 这个概念。还是直接为每一个 BASH 创建这样一个文件,放在 /tmp下,文件名就以 BASHPID 为后缀,避免重名。

逻辑上,得实现 3 个函数 icd_mainicd_backwardicd_forward,用于进入新目录、后退、前进。然后定义快捷键绑定到这 3 个函数,来实现相应的功能。我自己是这样绑定的:

1
2
3
4
5
6
7
alias cd=icd_main
alias h=icd_backward
alias l=icd_forward
# Ctrl + right
bind '"e[1;5D>":"hn>"'
# Ctrl + left
bind '"e[1;5C>":"ln>"'

这样,就可以用 h/ Ctrl-right来回退, l/ Ctrl-left来前进, cd来做正常的目录改变。一起来看一下效果:

vim: BASH 的目录切换
vim: BASH 的目录切换

对应的源码,可以在这找到 icd src

~原创有您,更持久!期待您的支持~

vim: BASH 的目录切换
vim: BASH 的目录切换

0 0

原文:http://www.tinylab.org/bash-directory-change/

BASH 的调试手段

By WEN Pingbo ofTinyLab.org

2015/06/01

平时在写 BASH 脚本时,总是会碰到让人抓狂的 BUG。和 C/C++ 这么丰富的调试工具相比,BASH 又有什么调试手段呢?

echo/print (普通技)

打印一些变量,或者提示信息。这应该是一个通用的方法了。在 BASH 里,我们可以简单的用 echo,或者 print 来输出一些 log,或者加一些 loglevel 来过滤一些 log。这里贴一下我平常用的函数:

1
2
3
4
5
6
7
8
9
10
11
_loglevel=2
DIE() {
    echo "Critical: $1>" >&2
    exit 1
}
INFO() {
    [ $_loglevel -ge 2 ] && echo "INFO: $1>" >&2
}
ERROR() {
    [ $_loglevel -ge 1 ] && echo "ERROR: $1>" >&2
}

这里的实现只是简单的加了一个 loglevel,其实可以把 log 输出到一个文件中,或者给 log 加上颜色。比如:

1
2
3
4
# add color
[ $_loglevel -ge 1 ] && echo -e "\033[31m ERROR:\033[0m $1>" >&2
# redirect to file
[ $_loglevel -ge 1 ] && echo "ERROR: $1>" > /var/log/xxx_log.$BASHPID

set -x (稀有技)

-x(xtrace) 选项会导致 BASH 在执行命令之前,先把要执行的命令打印出来。这个选项对调试一些命令错误很有帮助。

有的时候,由于传进来的参数带有一些特殊字符,导致 BASH 解析时不是按照我们预想的进行。这个时候,把 -x 打开,就能在命令执行前,把扩展后的命令打印出来。比如基于前面写的函数:

1
2
3
4
set -x
INFO "this is a info log>"
ERROR "this is a error log>"
set +x

然后就可以看到如下输出:

1
2
3
4
5
6
7
8
9
+ INFO 'this is a info log'
+ '[' 2 -ge 2 ']'
+ echo -e '\033[32m INFO:\033[0m this is a info log'
 INFO: this is a info log
+ ERROR 'this is a error log'
+ '[' 2 -ge 1 ']'
+ echo -e '\033[33m ERR:\033[0m this is a error log'
 ERR: this is a error log
+ set +x

如果想全程打开 xtrace,可以在执行脚本的时候加 -x参数。

trap/bashdb (史诗技)

为了方便调试,BASH 也提供了陷阱机制。这跟之前介绍的两种方法高级不少。我们可以利用 trap 这个内置命令来指定各个 sigspec 应该执行的命令。trap 的具体用法如下:

trap [-lp] [[arg] sigspec ...]

sigspec 包括 中定义的各个 signal, EXIT,ERR,RETURN 和 DEBUG。

各个 signal 这里就不介绍了。EXIT 会在 shell 退出时执行指定的命令。若当前 shell 中有命令执行返回非零值,则会执行与 ERR 相关联的命令。而 RETURN 是针对 source.,每次执行都会触发 RETURN 陷阱。若绑定一个命令到 DEBUG,则会在每一个命令执行之前,都会先执行 DEBUG 这个 trap。这里要注意的是,ERR 和 DEBUG 只在当前 shell 有效。若想函数和子 shell 自动继承这些 trap,则可以设置 -T(DEBUG/RETURN) 和 -E(ERR)。

比如,下面的脚本会在退出时,执行echo:

1
2
3
#!/bin/bash
trap "echo this is a exit echo>" EXIT
echo "this is a normal echo>"

或者,让脚本中命令出错时,把相应的命令打印出来:

1
2
3
4
#!/bin/bash
trap 'echo $BASH_COMMAND return err' ERR
echo this is a normal test
UnknownCmd

这个脚本的输出如下:

1
2
3
this is a normal test
tt.sh: line 6: UnknownCmd: command not found
UnknownCmd return err

亦或者,让脚本的命令单步执行:

1
2
3
4
5
6
7
8
9
#!/bin/bash
trap '(read -p "[$0 : $LINENO] $BASH_COMMAND ?>")' DEBUG
echo this is a test
i=0
while [ true ]
do
    echo $i
    ((i++))
done

其输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[tt.sh : 5] echo this is a test ?
this is a test
[tt.sh : 7] i=0 ?
[tt.sh : 8] [ true ] ?
[tt.sh : 10] echo $i ?
[tt.sh : 11] ((i++)) ?
[tt.sh : 8] [ true ] ?
[tt.sh : 10] echo $i ?
1
[tt.sh : 11] ((i++)) ?
[tt.sh : 8] [ true ] ?
[tt.sh : 10] echo $i ?
2
[tt.sh : 11] ((i++)) ?

是不是有点意思了?其实有一个 bashdb的开源项目,也是利用 trap 机制,模拟 gdb 做了一个 bash 脚本的调试器。它本身也是一个 bash 脚本。在加载要调试的脚本后,可以用和 gdb 类似的命令,甚至缩写也是一样的,大家可以尝试一下:)

(上个月沉迷于 Diablo3,最后发现自己脸不行,悴!还是回来写点东西吧!)

~原创有您,更持久!期待您的支持~

BASH 的调试手段
BASH 的调试手段

0 0

原文:http://www.tinylab.org/bash-debugging-tools/

Nginx服务启动、停止和重启等操作的SHELL脚本

由于使用源码编译安装Nginx,不会像yum install那样自动生成Nginx服务控制脚本,所以需要自己添加一个操作脚本。谷歌上搜了一下,shell脚本的代码基本类似,因此自己稍微整理改动了下。

下面的shell脚本内容,需要根据Nginx实际编译安装的配置,修改 NGINX_CONF_FILE=”/etc/nginx/nginx.conf>”lockfile=/var/lock/nginx.lock这两个参数(即前文 《2015博客升级记(三):CentOS 7.1编译安装Nginx1.9.0》中的configure配置)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#! /bin/bash
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse
#              proxy and IMAP/POP3 proxy server
#
# processname: nginx
# config:     /etc/nginx/nginx.conf
# pidfile:   /var/run/nginx/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING>" = "no>" ] && exit 0
nginx="/usr/sbin/nginx>"
prog=$(basename $nginx)
NGINX_CONF_FILE="/etc/nginx/nginx.conf>"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/nginx.lock
start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: >"
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
stop() {
    echo -n $"Stopping $prog: >"
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
restart() {
    configtest || return $?
    stop
    sleep 1
    start
}
reload() {
    configtest || return $?
    echo -n $"Reloading $prog: >"
    killproc $nginx -HUP
    RETVAL=$?
    echo
}
force_reload() {
    restart
}
configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
    status $prog
}
rh_status_q() {
    rh_status >/dev/null 2>&1
}
case "$1>" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}>"
        exit 2
esac

将上面的shell脚本内容以 Unix格式(不能用dos哦)保存并命名为 nginx,然后上传到centos系统的 /etc/init.d/目录,接着添加可执行权限,最后执行添加到开机启动的命令: chkconfig –add nginxchkconfig nginx on即可。

最后,我们可以使用如下命令对Nginx服务进行操作:

1
2
3
4
5
6
7
8
9
10
######启动Nginx服务
[root@typecodes ~]# service nginx start
######停止Nginx服务
[root@typecodes ~]# service nginx stop
######重启Nginx服务
[root@typecodes ~]# service nginx restart
######Nginx服务的状态
[root@typecodes ~]# service nginx status
######在Nginx服务启动的状态下,重新加载nginx.conf这个配置文件
[root@typecodes ~]# service nginx reload

原文:http://typecodes.com/web/nginxserviceoptshell.html

Linux Shell 程序调试

Linux Shell程序调试

Shell程序的调试是通过运行程序时加入相关调试选项或在脚本程序中加入相关语句,让shell程序在执行过程中显示出一些可供参考的“调试信息”。当然,用户也可以在shell程序中的适当位置加入一些echo命令用于调试与跟踪。

方法一:在运行脚本程序时加入调试选项:

【用法】bash –选项./shellScript.sh

几个常用的调试选择项如下: 
1
        -e :如果一个命令返回一个非0退出状态值(失败),就退出。
1
        -n : 不需要执行脚本只是检查语法结构,返回所有的语法错误信息。
1
        -u : 置换时把未设置的变量看作出错。
1
  -v: 当读入shell输入行时,把它们显示出来。
1
        -x: 执行命令时,把命令和它们的参数显示出来。

方法二:在脚本程序中通过
set命令 调试程序:

【用法】set –选项,set +选项      #set命令的常用选项同上

1
        以在Shell程序内部用“set -选择项”的形式引用,而“set +选择项”则将禁止该选择项起作用。如果只想对程序的某一部分使用某些选择项时,则可以将该部分用上面两个语句包围起来。

(1)未置变量退出(-u)和立即退出(-e)

未置变量退出特性允许用户对所有变量进行检查,如果引用了一个未赋值的变量就终止Shell程序的执行。Shell通常允许未置变量的使用,在这种情况下,变量的值为空。如果设置了未置变量退出选择项,则一旦使用了未置变量就显示错误信息,并终止程序的运行。未置变量退出选择项为-u。

当Shell运行时,若遇到不存在或不可执行的命令、重定向失败或命令非正常结束等情况时,如果未经重新定向,该出错信息会显示在终端屏幕上, 而Shell程序仍将继续执行。要想在错误发生时迫使Shell程序立即结束,可以使用-e选项将Shell程序的执行立即终止。

(2)Shell程序的跟踪(-v或-x)

调试Shell程序的主要方法是利用Shell命令解释程序的-v或-x选项来跟踪程序的执行。-v选择项使Shell在执行程序的过程中,把它读入的每一个命令行都显示出来,而-x选择项使Shell在执行程序的过程中把它执行的每一个命令在行首用一个+加上命令名显示出来。并把每一个变量和该变量所取的值也显示出来。因此,它们的主要区别在于:在执行命令行之前无-v,则显示出命令行的原始内容,而有-v时则显示出经过替换后的命令行的内容。

【例子】

./iftest.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#! /bin/bash
iftest(){
     if  [ $# -ne 1  ]
    then
        echo  " Usage: $0 dir  >"
        exit  1
    fi
   #  set  -v or set  -x      #若选择方法二,则取消注释,并选择其中一个set命令
     if  [ -d " $1 >"  ]
    then
        ls  -l $1
        exit  0
    fi
    #  set  +v or set  +x    #若选择方法二,则取消注释,并选择其中一个set命令
    echo  " Warn:$1 is not a directory! >"
    exit  2
}
iftest ..

方法一运行结果:

bash -v ./iftest.sh

bash -x ./iftest.sh

注:$#=1    $1=..  

方法二运行结果:  

取消iftest.sh程序中的注释,并且只选择set -x 和 set +x命令,表明只对第二个if..fi语句块进行调试。

./iftest.sh

感谢:http://www.cnblogs.com/hicome/archive/2007/10/30/943002.html

原文:http://www.cnblogs.com/CherishFX/p/4558958.html

shell: [原]shell终端多目录间快速cd工具

1.解决的问题

当在多个目录间cd的时候,需要输入一大串的路径。例如在不同的项目、不同的分支代码目录跳转,在桌面和文档目录跳转

cd ~/Desktop/project_trunk

cd ~/Download/cang_lao_shi

cd ~/code/branch-1.11/

cd ~/code/branch-3.1/project/android 

这个工具就能令这些cd简化成几个字符:

g2t

g2c

g21

g2a

2.脚本配置

工具是个shell脚本,附在本文末尾,复制整个代码保存为任意文件名,例如g2.sh,然后在 ~/.bashrc的最后一行加入单引号里的内容 ‘source g2.sh’ 或 ‘. g2.sh’

3.自定义路径

如果想加入自定义的路径,找到

shortcut_and_paths=(xxxxx)

的地方,增加一行就可以了。每行就是一个参数和实际命令。可以看到

1
2
3
4
5
6
7
shortcut_and_paths=(
  'd ~/Desktop'
  's ~/Downloads/subversion-1.7.17'
  '7 ~/Downloads/gmock-1.7.0'
  'n ~/Documents/department/17无线推广部/内部文档/主管文档'
  'wk /home/liuhx/Desktop/WebKit/Source/WTF/icu'
)

第一个空格前是g2的后缀,第一个空格后是cd的路径。增加完需要重新source或者新建一个terminal才会生效。

如果忘了可以g2啥,可以输入g2help(不是g2hell哦)就能列出所有命令。

附脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash
#author http://blog.csdn.net/hursing
# this variable should be complex enough to avoid naming pollution
shortcut_and_paths=(
  'd ~/Desktop'
  's ~/Downloads/subversion-1.7.17'
  '7 ~/Downloads/gmock-1.7.0'
  'n ~/Documents/department/17无线推广部/内部文档/主管文档'
  'wk /home/liuhx/Desktop/WebKit/Source/WTF/icu'
)
for ((i = 0; i < ${#shortcut_and_paths[@]}; i++)); do
  cmd=${shortcut_and_paths[$i]}
  shortcut=${cmd%% *}
  path=${cmd#* }
  func="g2$shortcut() { cd $path; }>"
  eval $func
done
g2help() {
  for ((i = 0; i < ${#shortcut_and_paths[@]}; i++)); do
    cmd=${shortcut_and_paths[$i]}
    shortcut=${cmd%% *}
    path=${cmd#* }
    echo -e "g2$shortcutt=>tcd $path>"
  done
  echo -e "\033[0;33;1mexample: input 'g2${shortcut_and_paths[0]%% *}' to run 'cd ${shortcut_and_paths[0]#* }'\033[0m>"
}

FAQ:

为什么不用alias呢?因为非交互式shell不会展开alias,也就是用function就能被其它脚本调用了

转载请注明出处: http://blog.csdn.net/hursing

原文:http://blog.csdn.net/hursing/article/details/44098161