上节继续,

1. 从键盘读取输入内容

#!/bin/bash
read -p 'please input something:' input
echo 'your input:' $input

运行效果:

./read1.sh
please input something:123
your input: 123

2. while循环及case分支

#!/bin/bash
printf '\nplease input a number or character, press "q" or "Q" to quit:\n'
while true
do
read reply
case $reply in
q|Q) echo 'bye!'; break;; #结束循环
[A-Za-z]*) echo 'you input a character:' $reply;; #如果输入的是纯英文字符
[0-9]*) echo 'you input a number:' $reply;; #如果输入的是纯数字
esac
printf 'please go on ...\n'
done

运行效果:

./read1.sh

please input a number or character, press "q" or "Q" to quit:
123
you input a number: 123
please go on ...
qwe
you input a character: qwe
please go on ...
Q
bye!

3. 文件操作相关
3.1 文件权限及所有者
ll (2个小写字母L)用于列出当前目录的所有文件(及目录)详细信息

[deploy@deploy myservice]$ ll
total 4
drwxrwxr-x. 2 deploy deploy 6 Jan 21 17:10 a
-rw-r--r--. 1 root root 40 Jan 21 14:41 test.txt

解读下这些输出,最开始的10个字符,拆分一下,其格式为:

类型(1位) 所属用户权限(3位) 所属用户组权限(3位) 其它组权限(3位)

所以:
d rwx rwx r-x 表示这是一个目录(第1位是d, Directory的首字母),然后所属用户有读(r,Read的首字母)、写(w,Write的首字母)、执行(x,代表eXecute)权限,所属用户组也同样具有所有权限,其它用户组具有读、执行权限。

- rw- r-- r-- 表示这是一个普通文件(第1位是-,表示普通文件),然后所属用户有read、write权限,所属用户组及其它组只能读。

注:第1位,除了d及-外,还有l表示link,说明这是符号链接,另外b表示块(block)设备,c表示字符(character)设备

继续看后面的输出,后面的二个字符串,即 deploy deploy 表示的是 所属用户及所属用户组,换句话说 目录 a 属于用户deploy及用户组deploy,而 test.txt属于用户root及用户组root

可以通过chown修改文件所属用户,示例:

sudo chown deploy test.txt

表示将test.txt的所属用户修改为deploy,因为该命令需要较高权限,所以前面加sudo切换到root身份,执行以后,再ll检测

[deploy@deploy myservice]$ ll
total 4
drwxrwxr-x. 2 deploy deploy 6 Jan 21 17:10 a
-rw-r--r--. 1 deploy root 40 Jan 21 14:41 test.txt

可以看到test.txt的所属用户已经变成deploy了。

chmod用于修改用户及目录权限,示例:

[deploy@deploy myservice]$ chmod +w test.txt
[deploy@deploy myservice]$ ll
total 4
drwxrwxr-x. 2 deploy deploy 6 Jan 21 17:10 a
-rw-rw-r--. 1 deploy root 40 Jan 21 14:41 test.txt

chmod +w test.txt表示将test.txt的所属用户及所属用户组的权限增加写(w,write)权限

chmod a+w test.txt
[deploy@deploy myservice]$ ll
total 4
drwxrwxr-x. 2 deploy deploy 6 Jan 21 17:10 a
-rw-rw-rw-. 1 deploy root 40 Jan 21 14:41 test.txt

这次在+w前加了一个a,表示all,即给所有人都增加了test.txt的写权限

[deploy@deploy myservice]$ chmod u-w test.txt
[deploy@deploy myservice]$ ll test.txt
-r--rw-rw-. 1 deploy root 40 Jan 21 14:41 test.txt

猜一下,也能大概知道u-w的意思,u即user缩写,-表示去掉权限,所以u-w表示将所属用户的write权限去掉,类似的

[deploy@deploy myservice]$ chmod g-r test.txt
[deploy@deploy myservice]$ ll test.txt
-r---w-rw-. 1 deploy root 40 Jan 21 14:41 test.txt

g-r表示将所属用户组的read权限去掉。

另外,从计算机内部的二进制来看,权限可以用3位2进制表示,从左向右依次为: 读、写、执行,所以111表示所有权限,101表示读及执行权限,000表示没任何权限,再考虑到 所属用户、所属用户组、其它组,也就是说有3组二进制,因此
chmod a+rwx 可以简化为 chmod 777
注:777是10进制表示,转换成权限2进制,即 111 111 111

[deploy@deploy myservice]$ chmod 777 test.txt
[deploy@deploy myservice]$ ll test.txt
-rwxrwxrwx. 1 deploy root 40 Jan 21 14:41 test.txt

类似的,如果要去掉所有人的所有权限

[deploy@deploy myservice]$ chmod -777 test.txt
[deploy@deploy myservice]$ ll test.txt
----------. 1 deploy root 40 Jan 21 14:41 test.txt

3.2 文件测试

#!/bin/bash
[ -f "test.txt" ] && echo 'test.txt is exists'
[ ! -f 'abc.txt' ] && echo 'abc.txt is not exist'

上面这段表示,表示如果文件test.txt存在,则输出test.txt is exists,类似的,如果文件abc.txt不存在,则输出abc.txt is not exists

再增加一些判断:

#!/bin/bash
[ -f "test.txt" ] && echo 'test.txt is exists'
[ ! -f 'abc.txt' ] && echo 'abc.txt is not exist'
[ -x "test.txt" ] || echo 'test.txt can not execute'
[ -d "a" ] && echo "a is directory"
[ -d "a" ] && [ -r "a" ] && echo "a is directory and can read "

完整的文件判断条件收集如下:

-e filename 如果 filename存在,则为真 (e即Exist的首字母)
-d filename 如果 filename为目录,则为真 (d即Directory的首字母)
-f filename 如果 filename为常规文件,则为真 (f即File的首字母)
-L filename 如果 filename为符号链接,则为真 (L即Link的首字母,注意这个是大写的)
-r filename 如果 filename可读,则为真 (r即Read的首字母)
-w filename 如果 filename可写,则为真 (w即Write的首字母)
-x filename 如果 filename可执行,则为真 (x即eXecute)
-s filename 如果文件长度不为0,则为真(可记忆为Substance的意思)
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,则为真(-nt 可记忆为new than)
filename1 -ot filename2 如果 filename1比 filename2旧,则为真(-nt 可记忆为old than)

  

4. 获取其它命令的输出

cmd_pwd=`pwd`
cmd_date=`date "+%Y-%m-%d %H:%M:%d"` current_dir=${cmd_pwd}
current_time=${cmd_date}

注意:命令字符串两端的不是单引号,而是`(即:键盘最左上角esc键下的~键)

输出:

当前目录:/Users/yjmyzz
当前时间:2016-01-21 18:13:21

  

5. 获取nohup的进程id
先建一个app-test.sh来模拟应用程序,内容如下:

#!/bin/bash
echo 'I want to sleep 100 second'
sleep 100

这段代码,啥也不干,上来就sleep 100秒

再建一个app-run.sh来模拟后台启动app-test,内容如下:

#!/bin/bash
echo 'app is starting...'
nohup ./app-test.sh >/dev/null 2>&1 &
echo 'ok,the pid is :'$!

测试一下:

➜  ~  ./app-run.sh
app is starting...
ok,the pid is :3168
➜ ~ ps -ef|grep app-test.sh
501 3168 1 0 6:26PM ttys001 0:00.01 /bin/bash ./app-test.sh

即: $!可以取到nohup后台启动的程序对应的pid

将前面写到的这些知识,来一个综合练习:

#!/bin/bash
cmd_pwd=`pwd`
pwd_dir=${cmd_pwd}
pid_file=${pwd_dir}/my.pid #启动
sub_start() {
printf "starting..."
if [ -w "${pid_file}" ]; then
echo ${pid_file}' has already exists'
else
nohup ./netty-sample >/dev/null 2>&1 &
pid=$!
echo $! > ${pid_file}
sleep 2
printf 'ok!\n'
fi
} #停止
sub_stop() {
printf "stopping..."
if [ -w "${pid_file}" ]; then
pkill -F ${pid_file}
sleep 2
printf 'ok!\n'
else
printf '\n'${pid_file}' NOT exists'
fi
} #查看状态
sub_status(){
if [ -w "${pid_file}" ]; then
printf "running.\n"
else
printf "NOT running.\n"
fi
} case $1 in
start)
sub_start
;;
stop)
sub_stop
;;
restart)
printf "restarting...\n"
sub_stop
sleep 1
sub_start
sleep 1
sub_status
;;
status)
sub_status
;;
*)
printf "usage: $0 {start|stop|restart|status}\n"
exit 1
;;
esac exit 0

这是一段通用的启动shell脚本,大意是启动指定应用(上面的代码中,待启用的应用为netty-sample,大家可以自行修改)时,先找到进程id,然后保存到pid文件中,这样后面就通过检测pid是否存在,来判断程序是否在运行中,也可用于结束程序或重启程序。  

6、编写自己的linux服务

linux下的服务,只要在/etc/rc.d/init.d/下放一个自己的shell脚本就可以了,参考内容如下:

#! /bin/bash

# chkconfig: 2345 10 90
# description: myservice .... #. /etc/init.d/functions desc='my-service'
cmd=`date "+%Y-%m-%d %H:%M:%S"` case "$1" in
start)
printf '%s is starting...' ${desc}
sleep 1
printf 'ok!\n'
echo ${cmd} >> /opt/myservice/test.txt
;;
stop)
printf '%s is stopping...' ${desc}
sleep 1
printf 'ok!\n'
;;
status)
printf '%s is ok!\n' ${desc}
;;
restart|reload|force-reload)
$0 stop
$0 start
;;
*)
echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
exit 2
esac exit 0

代码不复杂,启动时在指定目录写个文件而已,将其保存成myservice.sh,赋予执行权限,应该就可以service myservice start|stop|restart|status了,很简单吧。

(注:第3,4行的注释不能删除,否则后面加入开机启动时会报错。)

如果想让myservice服务开机即自动启动,可以执行

sudo chkconfig --add myservice

加好后,可以尝试重启下机器,看指定目录下的文件是否有生成,如果生成且写入了新内容,表明服务确实运行了。

另外:chkconfig 不加任何参数,可以查看当前有哪些服务配置了开机自动启动。如果要从开机启动的服务列表中删除,chkconfig --del myservice.

bash/shell编程学习(3)的更多相关文章

  1. bash/shell编程学习(1)

    1)定义变量 myvar=abc #注:等号前后不能加空格 #或 myvar="abc" #或 myvar='abc' #注:如果变量后面的值中间本身没有空格,加不加引号都无所谓, ...

  2. bash/shell编程学习(2)

    先来复习上节重定向的用法: 1.快速清空文件 cat demo.txt < /dev/null 注:linux中有一个经典名言[一切皆文件],/dev/null可以认为是一个特殊的空文件,更形象 ...

  3. Bash脚本编程学习笔记08:函数

    官方资料:Shell Functions (Bash Reference Manual) 简介 正如我们在<Bash脚本编程学习笔记06:条件结构体>中最后所说的,我们应该把一些可能反复执 ...

  4. Bash脚本编程学习笔记07:循环结构体

    本篇中涉及到算术运算,使用了$[]这种我未在官方手册中见到的用法,但是确实可用的,在此前的博文<Bash脚本编程学习笔记03:算术运算>中我有说明不要使用,不过自己忘记了.大家还是尽量使用 ...

  5. abc高级bash shell编程

    http://www.pythoner.com/122.html     abc高级bash shell编程

  6. Linux 下shell 编程学习脚手架

    linux body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-t ...

  7. linux 10 -Bash Shell编程

    二十三. Bash Shell编程:     1.  读取用户变量:     read命令是用于从终端或者文件中读取输入的内建命令,read命令读取整行输入,每行末尾的换行符不被读入.在read命令后 ...

  8. Bash脚本编程学习笔记06:条件结构体

    简介 在bash脚本编程中,条件结构体使用if语句和case语句两种句式. if语句 单分支if语句 if TEST; then CMD fi TEST:条件判断,多数情况下可使用test命令来实现, ...

  9. shell编程学习之使用jq对json数据进行提取

    shell编程学习之使用jq对json提取 jq命令允许直接在命令行下对JSON进行操作,包括分片.过滤.转换等 ,jq是用C编写,没有运行时依赖,所以几乎可以运行在任何系统上.预编译的二进制文件可以 ...

随机推荐

  1. CSS3与页面布局学习总结(三)——BFC、定位、浮动、7种垂直居中方法

    一.BFC与IFC 1.1.BFC与IFC概要 BFC(Block Formatting Context)即“块级格式化上下文”, IFC(Inline Formatting Context)即行内格 ...

  2. Linux A机器免密码SSH登录B机器

    一.问题 如上,A机器经常需远程操作B机器,传输文件到B机器,每次输入帐号密码过于繁琐,下文通过ssh公钥能解免密码操作问题. 二.解决 1.方案 SSH认证采用公钥与私钥认证方式. 2.步骤 1) ...

  3. .net程序部署(setupFactory进阶)

    接上一篇 继续使用上一篇的project .将archive里无用的文件删除 添加我们需要的文件进来. config是一个文本文件. 注意所有文件的 destination都是 %appfolder% ...

  4. 【C#公共帮助类】 WebHelper帮助类

    如果你是一个新手,如果你刚接触MVC,如果你跟着置顶的那个项目,我们肯定会用到这里面的几个帮助类 它们都在Common类库下,大家一定要记住要点:取其精华去其糟粕,切勿拿来主义~ Applicatio ...

  5. Struts2入门(二)——配置拦截器

    一.前言 之前便了解过,Struts 2的核心控制器是一个Filter过滤器,负责拦截所有的用户请求,当用户请求发送过来时,会去检测struts.xml是否存在这个action,如果存在,服务器便会自 ...

  6. 初识Spring框架实现IOC和DI(依赖注入)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的, IoC是 ...

  7. MySQL大数据优化

    我们考虑的情况是在你的数据量很大的情况下,千万级别的数据量.不要当我们的请求响应时间已经让我无法忍受的时候,再来想起来优化,可能有点迟了.因为可能会丢失很多潜在的价值客户.所以,在我们当初设计表,或者 ...

  8. 关于IOS中safari下的select下拉菜单,文字过长不换行的问题

    今天遇到下图这种问题,文字过长,显示不全.折腾了老半天,在网上搜了半天也找不到解决方案. 于是问了下同事,同事提到了<optgroup>,这个标签厉害. <optgroup> ...

  9. 使用WebRTC搭建前端视频聊天室——入门篇

    http://segmentfault.com/a/1190000000436544 什么是WebRTC? 众所周知,浏览器本身不支持相互之间直接建立信道进行通信,都是通过服务器进行中转.比如现在有两 ...

  10. React Native知识11-Props(属性)与State(状态)

    一:Props(属性) 大多数组件在创建时就可以使用各种参数来进行定制.用于定制的这些参数就称为props(属性).props是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变 通过 ...