bash/shell编程学习(3)

上节继续,

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.

 

时间: 2024-10-02 21:16:38

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

bash/shell编程学习(1)

1)定义变量 myvar=abc #注:等号前后不能加空格 #或 myvar="abc" #或 myvar='abc' #注:如果变量后面的值中间本身没有空格,加不加引号都无所谓,但值本身如果有空格,则引号是必须的,比如: myvar='abc 123' 2) 使用变量echo $myvar 完整示例: #!/usr/bin/env bash myvar1='ddddddd 111' echo 'myvar1='$myvar1 echo 'myvar1=$myvar1' #注意这一行跟

bash/shell编程学习(2)

先来复习上节重定向的用法: 1.快速清空文件 cat demo.txt < /dev/null 注:linux中有一个经典名言[一切皆文件],/dev/null可以认为是一个特殊的空文件,更形象点,可以理解为科幻片中的黑洞,任何信息重向定输出到它后,便有去无回,当然黑洞里也没有信息能出来. 综合来讲,上面的意思就是利用<将黑洞做为demo.txt的标准输入,黑洞里没任何内容,任何文件里的内容被它吞噬了,自然也没就没东西能剩下了,所以最终就是demo.txt被黑洞洗空了. /dev/null 还

Linux系统中bash shell编程的10个基础问题讲解_linux shell

第1问:为何叫做shell?在介绍 shell 是什么东西之前,不妨让我们重新审视使用者与电脑的关系.我们知道电脑的运作不能离开硬件,但使用者却无法直接对硬件作驱动,硬件的驱动只能透过一个称为"操作系统(Operating System)"的软件来控管,事实上,我们每天所谈的linux,严格来说只是一个操作系统,我们称之为"核心(kernel)".然而,从使用者的角度来说,使用者也没办法直接操作kernel,而是透过kernel的"外壳"程序,也

Linux服务器Shell编程学习笔记

Shell脚本编程学习入门是本文要介绍的内容,我们可以使用任意一种文字编辑器,比如gedit.kedit.emacs.vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行):  代码如下 复制代码 #!/bin/sh ...注意:最好使用"!/bin/bash"而不是"!/bin/sh",如果使用tc shell改为tcsh,其他类似. 符号#!用来告诉系统执行该sell脚本的程序,本例使用/bin/sh.编辑结束并保存后,如果要执行该shell脚本

Shell编程学习:Shell子程序结构和函数

函数可以简化代码,实现脚本代码重用.一次定义可以多次调用.结构化编程,增强可读性,可以将功能定义为多个函数,然后保存在一个文件中,然后在~/bashrc或者在命令行使用source(.)调用这个文件.加快运行速度 1.定义函数的方法(传统风格) function name{ } C语言风格: name(){ } 推荐使用C语言风格,兼容性好,可以在csh/tsch中使用 函数中return和exit的区别,return退出执行,返回到主程序函数之后继续执行 exit直接退出当前脚本. shell

Bash Shell脚本学习小结_linux shell

1.字符截断: 如果是一般路径的字符截断可以用basename和dirname这两个工具:basename可以从一个文件路径中截一个文件名 例如: 复制代码 代码如下: $ basename /home/file.tarfile.tar dirname可以从一个文件路径中截到一个目录路径例如: 复制代码 代码如下: $ dirname /home/file.tar/home 不使用外部工具进行字符截断bash有自带的功能来对变量进行字符截断,一般使用"##", "#"

Shell编程学习:分支结构和循环结构

一.if结构 1.单分支结构 if condition then statement1 statement2 ... fi 2.双分支结构 if condition then statement1 statement2 ... else statement3 statement4 fi 3.多分支结构 if condition then statement elif condition2 then statement2 fi 二:case结构 case condition in pattern1

shell编程学习:shell基础和文件

1shell就是用户和内核进行交互操作的一种接口, 2shell可以运行的命令包括linux命令,内置命令,实用程序,用户程序,shell脚本 3shell元字符: 4.获取命令帮助:man,info.--help 5.文件类型有普通文件(-),目录(d),符号链接文件(l),字符设备文件(c),块设备文件(b),套接字(s),命名管道(p),块设备文件就是计算机外围设备文件,让用户可以操作设备的时候和操作普通文件一样. 6,常用文件和目录操作命令: ls ,ls -al,ls -R递归列出所有

SHELL编程基础之BASH入门

1.了解SHELL 只要能够操作应用程序的接口都能够称shell.shell也是一个应用程序,工作在用户模式,运行为进程.shell进程主要用于提供命令行界面,提供一系列的工作特性,有些特性可以自行的设定.当用户通过多种方式登录到Linux操作系统时,我们就可以认为该用户打开了一个SHELL,从而和系统进行交互. shell在linux系统下的角色如下: 2.为什么要学习shell 命令行界面的shell是很不好的,但是学完之后好处却很多.例如图形化界面像windows xp.win 7每个版本