shell脚本实例备忘
2013-03-27 04:35
453 查看
将一些练习题以及我自己实际写过的shell脚本记录于此,供学习查询。
用户输入y或Y结束
case、函数、函数参数使用方法
shell脚本中执行命令的方法
shell脚本中for的使用方法
dirname 命令与脚本语句$(dirname "${0}")
显示指定路径除了最后的文件名或者目录名之外的路径前缀,即截取给定路径的目录部分。例如:dirname /usr/bin/sort 得到/usr/bin。
在shell脚本中经常看到这样的语句:$(dirname "${0}")
说明:${0}表示当前脚本的第一个参数,即程序的完整路径,再执行dirname命令,则取得当前脚本所在的目录。
还有语句:cd $(dirname "$0") || exit 1
说明:$(dirname "$0")表示当前脚本所在的目录,cd即进入脚本所在目录,失败则exit 1(退出)。
还有常用的获取当前脚本文件所在目录的方式:
[b]THIS_DIR=$(cd "$(dirname $0)"; pwd)[/b]
或者是:
THIS_DIR=$(readlink -f "$(dirname "${0}")")
grep妙用
今天在shell脚本中看到这样一条语句:
NUM_JOBS="$(grep -c "^processor" /proc/cpuinfo)"
文件/proc/cpuinfo是cpu的信息,grep -c只统计查询结果的行数但是不输出,正则表达式"^processor"表示以processor开始的行,查看/proc/cpuinfo文件可以看出processor开始的行是cpu的第几个核心的信息。综上可知上面的shell语句就是统计了当前机器的cpu核心数目。
判断字符串是否是数
apache httpd自动编译生成的小脚本
脚本功能很简单,先判断当前目录中是否有Makefile文件,有则执行make进行编译生成,否则执行./configure(默认该文件存在,可以加上一条判断语句)生成Makefile文件,再进行判断和执行,过程中用MAKE_RES记录make执行的返回值,最终打印出该值。
判断用户输入的字符串是否为“Yes”或“No”(包含各种大小写字母组合)
for循环一例
脚本中用sudo执行命令,怎样自动输入密码,以免脚本执行中断等待用户输入密码
echo "password" | sudo -S netstat -tlnp
The -S (stdin) option causes sudo to read the password from the standard input instead of the terminal device.
系统/etc/profile 中的一段代码,可以学习借鉴
今天开了一下/etc/下的配置文件profile,看到如上的一段代码,其中#×××的语句值得借鉴,根本不需要查找!!!
一个简单的例子,包含我写脚本的基本框架,以后可以复用
对目录中所有文件求md5值并输出到文件
命名临时文件
TMP_file="/tmp/tmp.$$"
$$是Script 的进程编号,利用$$组成临时文件名,这样,可避免不同的Script 开启重复的临时文件。
一个例子
维护debian源码包时,需要获取源码包需要的编译依赖。要想知道你的软件在编译的时候需要用到哪一个软件包,可以通过下面的方法,在源码根目录运行:
strace -f -o /tmp/log ./configure
部分log文件文件如下:
while方式 #!/bin/bash read -p "input you choice : " c while [ "$c" != "Y" -a "$c" != "y" ] do read -p "input you choice : " c done echo "Ok!" until方式 #!/bin/bash until [ "$c" == "Y" -o "$c" == "y" ] do read -p "input your choice : " c done echo "done!"
#!/bin/bash function print() { echo "Your choice is $1" } case $1 in "one") #echo "one" print 1 ;; "two") #echo "two" print 2 ;; "three") #echo "othre" print 3 ;; *) echo "Usage $0 {one|two|three}" ;; esac
#!/bin/bash str=$(whoami) #或者:str=`whoami`(这里的引号为反引号——ESC下面那个键) echo $str
循环读取字符串中的每一个子串(以空格隔开) #!/bin/bash string="Waiting for a while" for str in ${string} do echo $str done 循环读取字符串中的每一个子串(以空格隔开) #!/bin/bash for str in "Waiting for a while" do echo $str done 循环读取ls命令返回结果的每一个 #!/bin/bash for str in `ls` do echo $str done 循环次数的例子,for(())是bash支持的 #!/bin/bash for ((i=0; i<10; i++)) #或者:for i in {1..10} do echo $i done
显示指定路径除了最后的文件名或者目录名之外的路径前缀,即截取给定路径的目录部分。例如:dirname /usr/bin/sort 得到/usr/bin。
在shell脚本中经常看到这样的语句:$(dirname "${0}")
说明:${0}表示当前脚本的第一个参数,即程序的完整路径,再执行dirname命令,则取得当前脚本所在的目录。
还有语句:cd $(dirname "$0") || exit 1
说明:$(dirname "$0")表示当前脚本所在的目录,cd即进入脚本所在目录,失败则exit 1(退出)。
还有常用的获取当前脚本文件所在目录的方式:
[b]THIS_DIR=$(cd "$(dirname $0)"; pwd)[/b]
或者是:
THIS_DIR=$(readlink -f "$(dirname "${0}")")
grep妙用
今天在shell脚本中看到这样一条语句:
NUM_JOBS="$(grep -c "^processor" /proc/cpuinfo)"
文件/proc/cpuinfo是cpu的信息,grep -c只统计查询结果的行数但是不输出,正则表达式"^processor"表示以processor开始的行,查看/proc/cpuinfo文件可以看出processor开始的行是cpu的第几个核心的信息。综上可知上面的shell语句就是统计了当前机器的cpu核心数目。
判断字符串是否是数
function isDigit() { if [ $# == 1 ];then if [ `echo $1 | grep -P "^\d+$" | wc -l` == 1 ];then return 0; fi fi return 1; } isDigit '111' echo $? isDigit 'ass' echo $?
apache httpd自动编译生成的小脚本
脚本功能很简单,先判断当前目录中是否有Makefile文件,有则执行make进行编译生成,否则执行./configure(默认该文件存在,可以加上一条判断语句)生成Makefile文件,再进行判断和执行,过程中用MAKE_RES记录make执行的返回值,最终打印出该值。
#!/bin/bash MAKE_RES=255 # 记录make的返回值,默认失败 if [ -f Makefile ];then # 测试Makefile文件是否存在 make # 执行make MAKE_RES=$? # 保存make的返回值 else # 如果Makefile文件不存在,则执行configure ./configure --with-included-apr --with-pcr if [ -f Makefile ];then # 判断是否生成了Makefile文件 make MAKE_RES=$? else echo "./configure failed!" fi fi echo "Make result : "${MAKE_RES} # 输出make的返回值(0表示成功,其他表示失败)
判断用户输入的字符串是否为“Yes”或“No”(包含各种大小写字母组合)
case "$OPT" in [Oo][Nn]) CMD='YES';; [Oo][Ff][Ff]) CMD='NO';; *) echo '选项格式错误! 请用on 或off 来切换匿名登录的开关。' exit 1 ;; esac
for循环一例
#! /bin/bash DIR="/var" cd ${DIR} for f in $(ls ${DIR}) do [ -d $f ] && du -s $f done该脚本用来列出/var目录下各子目录占用磁盘空间的大小。
脚本中用sudo执行命令,怎样自动输入密码,以免脚本执行中断等待用户输入密码
echo "password" | sudo -S netstat -tlnp
The -S (stdin) option causes sudo to read the password from the standard input instead of the terminal device.
系统/etc/profile 中的一段代码,可以学习借鉴
<span style="font-size:12px;">if [ -d /etc/profile.d ]; then for i in /etc/profile.d/*.sh; do #××× if [ -r $i ]; then . $i fi done unset i fi</span>经常会有这样的需求:获取某个路径下的所有文件或者某些匹配的文件,然后做某种操作。以前的做法是先用find或者ls+grep的方式获取结果,然后再对结果进行循环操作,例如:result=$(find /etc/profile.d/ -name *.sh) 或者 result=$(ls /etc/profile.d/ | grep ".sh$")。
今天开了一下/etc/下的配置文件profile,看到如上的一段代码,其中#×××的语句值得借鉴,根本不需要查找!!!
一个简单的例子,包含我写脚本的基本框架,以后可以复用
#! /bin/bash ############################################################################### # author: andy <44452114@qq.com> # date: 04/24/2014 # descrp: 脚本功能为列出给定目录中所有的文件和目录,通过参数形式给定需要查询 # 的目录。运行方式如下: # $ ./list_dir.sh /home/andy # ############################################################################### # 判断输入参数是否合法 if [[ $# < 1 ]]; then echo "[Error] Too few parameters!" exit 1 fi # 获得输入的参数 dir=$1 if [ ! -d $dir ]; then echo "[Error] The path you give($dir) not exist!" exit 2 fi # 程序功能实现 list=$(ls $dir) for item in $list do echo "item : $item" done # 结束提示 echo "Ok!"
对目录中所有文件求md5值并输出到文件
sudo find . -type f -print0 | xargs -0 md5sum | grep -v "\./md5sum.txt" > md5sum.txt
命名临时文件
TMP_file="/tmp/tmp.$$"
$$是Script 的进程编号,利用$$组成临时文件名,这样,可避免不同的Script 开启重复的临时文件。
一个例子
维护debian源码包时,需要获取源码包需要的编译依赖。要想知道你的软件在编译的时候需要用到哪一个软件包,可以通过下面的方法,在源码根目录运行:
strace -f -o /tmp/log ./configure
部分log文件文件如下:
32171 mmap2(NULL, 126192, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb76e0000 32171 close(3) = 0 32171 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 32171 open("/lib/i386-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 32171 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320\n\0\0004\0\0\0"..., 512) = 512 32171 fstat64(3, {st_mode=S_IFREG|0644, st_size=13856, ...}) = 0 32171 mmap2(NULL, 16512, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb76db000 32171 mmap2(0xb76de000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0xb76de000 32171 close(3) = 0 32171 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 32171 open("/lib/i386-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 32171 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\0F\0\0004\0\0\0"..., 512) = 512 32171 fstat64(3, {st_mode=S_IFREG|0644, st_size=280108, ...}) = 0在使用下面的脚本分析,提取出依赖的软件包及版本,脚本如下(重要的地方加了注释):
for x in `dpkg -S $(grep open ./log|\ perl -pe 's!.* open\(\"([^\"]*).*!$1!' |\ grep "^/"| sort | uniq|\ grep -v "^\(/tmp\|/dev\|/proc\)" ) 2>/dev/null|\ cut -f1 -d":"| sort | uniq`; \ do echo -n "$x (>=" `dpkg -s $x|grep ^Version|cut -f2 -d":"` "), "; done # 注释说明 # 1行:找到含有open的行; # 2行:perl -pe 's!!!'或者perl -pe 's///',替换字符串。这里实际上是为了得到$1,例如: # 上面log的第4行,会提取得到:/lib/i386-linux-gnu/libdl.so.2,注意读一下其中的正则匹配, # 匹配open后面“”中的内容保存在$1; # 3行:提取/开头的行; # 4行:去掉/tmp,/dev,/proc开始的行,即不处理/tmp,/dev,/proc开头的文件。注意这里有grep使用 # 的技巧——查询多个字符串匹配:grep "\(aaa\|bbb\)) # 另外,dpkg -S 查询某个文件属于哪个debian包,dpkg -s 查询debian包的详细信息。
相关文章推荐
- 用shell脚本监控进程是否存在 不存在则启动的实例
- shell脚本实例之Charpter8-8
- shell脚本实例之Charpter8-14
- 查看: 35330 | 回复: 9 打印 上一主题 下一主题 [学习共享] 转:Shell 编程--本文结合大量实例阐述如何编写一个shell脚本
- shell脚本基础(备忘)
- shell脚本建多库、多表、多实例(mysql)
- shell(一) 入门到复杂 自己做的各种脚本实例与解释
- 我的一些简单的shell脚本实例
- shell脚本实例
- shell脚本实现快速生成xml格式sitemap实例分享
- [shell应用进阶]:限制同时运行脚本实例的个数 -- 串行化:换一个思路。
- Linux命令行与shell脚本(19)--实例:监测磁盘空间
- shell脚本实例-matrix
- 我的一些简单的shell脚本实例
- 用shell脚本实现杨辉三角的4个实例
- CentOS6、7 LVM逻辑卷分区自动扩容Shell脚本编程思路与实例
- shell脚本中的常见应用实例
- [实例]利用php+mysql完成shell脚本的授权验证
- 我的一些简单的shell脚本实例
- shell脚本实例-菜单样例