bash函数定义/使用/传参…
函数:function, 功能
过程式编程,代码重用
模块化编程
简洁
语法:
function f_name {
函数体
}
或者
f_name() {
函数体
}
调用:使用函数名
函数名出现的地方,会被自动替换为函数代码;
练习:利用函数改写此前的服务脚本
启动一个脚本之后,脚本本身会在/var/lock/subsys/目录下创建一个对应的锁文件
service httpd start启动httpd服务,此时在/var/lock/subsys/目录下,会生成httpd锁文件
/etc/rc.d/init.d存放服务脚本,遵循的是lsb编写格式
在/etc/rc.d/init.d中有一个文件functions,为公用的函数
想要调用functions文件里的各个函数,则添加
. /etc/rc.d/init.d/functions代码,在你需要调用的文件中
假如是httpd服务,则需要另外导入 . /etc/sysconfig/httpd 的配置文件
#!/bin/bash
#
#$0是当前脚本的名称
prog=`basename $0`
lockfile=/var/lock/subsys/$prog
start() {
if [ -e $lockfile ];then
echo "$prog is already running."
else
touch $lockfile
[ $? -eq 0 ] && echo "Starting $prog finished."
fi
}
stop() {
if [ -e $lockfile ];then
rm -rf $lockfile
[ $? -eq 0 ] && echo "Stoping $prog finished."
else
echo "$prog is stopped yet."
fi
}
case $1 in
"start")
start ;;
"stop")
stop ;;
"restart")
stop
start ;;
*)
echo "Usage: $prog {start|stop|restart}"
exit 1
esac
函数返回值:
函数的执行结果返回值:
函数中使用打印语句:echo, printf
函数体中OS命令执行结果的输出
函数的退出状态码:
默认取决于函数体执行的最后一个命令的退出状态码;
自定义退出状态码:
return [0-255]
注意:函数体运行时,一旦遇到return语句,函数即返回;
函数可接受参数:
传递参数给函数,调用函数时,在函数名后给出参数列表即可;
例: testfunc arg1 arg2 arg3
在函数体中可使用$1,$2....来调用传递过来的各参数
可使用类似脚本的特殊变量
$*,$@: 一次性获取参数列表
$#: 参数的个数
$?: 上一条命令的执行状态或返回状态码
例:
#!/bin/bash
#
showuserinfo() {
[ $# -lt 1 ] && return 1 #参数个数小于1,即没有传递参数
! id $1 &> /dev/null && return 2 #用户名不存在
grep "^$1\>" /etc/passwd | cut -d: -f7
[ $? -eq 0 ] && return 0 || return 3 #前一条命令执行成功,则return 0, 否则return 3
}
while true; do
read -p "Enter a username: " username
[ "$username" == 'quit' ] && break
showuserinfo $username
[ $? -ne 0 ] && echo "There is something wrong."
done
练习:写一个脚本,完成如下功能(使用函数):
1、提示用户输入一个可执行命令;
2、获取这个命令所依赖的所有库文件(使用ldd命令);
3、复制命令至/mnt/sysroot/对应的目录中
解释:
假设,如果复制的是cat命令,其可执行程序的路径是/bin/cat,
那么就要将/bin/cat复制到/mnt/sysroot/bin/目录中,
如果复制的是useradd命令,而useradd的可执行文件路径为/usr/sbin/useradd,
那么就要将其复制到/mnt/sysroot/usr/sbin/目录中;
4、复制各库文件至/mnt/sysroot/对应的目录中;
#!/bin/bash
#
target=/mnt/sysroot/
preCmd(){
#which $1:获取命令的所在目录, 例如which cat
#which --skip-alias $1: 参数--skip-alias是跳过别名解析,例如which cp和which --skip-alias cp
if which $1 &> /dev/null; then
cmdpath=$(which --skip-alias $1)
return 0
else
echo "No such command."
return 1
fi
}
#/bin/cat
#/mnt/sysroot/bin/cat
cmdCopy(){
#dirname $cmdpath: 获取后边参数所在的目录
cmddir=$(dirname $cmdpath)
[ -d $target/$cmddir ] || mkdir -p $target/$cmddir
[ -f $target/$cmdpath ] || cp $target/$cmddir
return 0
}
#ldd /bin/cat: 查看cat命令所需的库文件
libCopy(){
for lib in $(ldd $1 | grep -E -o "/[^[space::]]+");do
libdir=$(dirname $lib)
[ -d $target/$libdir ] || mkdir -p $target/$libdir
[ -f $target/$lib ] || cp $target/$libdir
done
return 0
}
main(){
while true; do
read -p "Plz enter a command(quit):" cmd
[ "$cmd" == 'quit' ] && break
precmd $cmd
if [ $? -eq 0 ];then
cmdCopy $cmdpath
libCopy $cmdpath
fi
done
}
main
变量的作用域:
本地变量:整个脚本,在脚本的函数中也可调用,也可修改;
局部变量:函数调用的整个生命周期;
函数递归:
函数直接或间接调用函数自身
1 1 2 3 5 8 13
阶乘: 10!
n(n-1)!
n(n-1)(n-2)!
阶乘函数:
fact() {
if [ $1 -eq 0 -o $1 -eq 1 ];then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}
bash函数定义/使用/传参…的更多相关文章
- Python函数定义及传参方式
主要内容: 1.函数初识 2.函数传参方式 (1)位置参数 (2)默认参数 (3)关键参数 (4)非固定传参 一.函数初识 1. ...
- 详解Python函数参数定义及传参(必备参数、关键字参数、默认可省略参数、可变不定长参数、*args、**kwargs)
详解Python函数参数定义及传参(必备参数.关键字参数.默认可省略参数.可变不定长参数.*args.**kwargs) Python函数参数传参的种类 Python中函数参数定义及调用函数时传参 ...
- python 函数的定义及传参
函数是一个通用的程序结构部件,是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 定义一个简单的函数: >>> def test(a): #创建一个函数,函数名是test ...
- python定义函数时的参数&调用函数时的传参
一.定义函数: 1.位置参数:直接定义参数 2.默认参数(或者关键字参数):参数名 = "默认值" 3.位置参数必须在默认参数之前 二.调用函数: 1.按位置传,直接写参数的值 2 ...
- c语言-函数的定义及传参
模块化编程 定义: 数据类型 函数名(型参):如果没有数据类型,默认的为int 值传递 地址传递 嵌套调用 递归调用:直接或间接调用本身函数,求可能栈破裂,求阶乘 #include <stdio ...
- 深入理解PHP内核(十二)函数-函数的定义、传参及返回值
原文链接:http://www.orlion.ga/344/ 一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) { echo $var; ...
- 深入理解PHP内核(六)函数的定义、传参及返回值
一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) { echo $var; } 1.词法分析 在Zend/zend_language_scann ...
- python函数的动态传参.作用域与命名空间
一.动态传参1.*表示动态传参. 可以接受所有的位置参数传参的时候自动的把实参打包成元组 交给形参 def chi(*food): print(food) chi() # 动态传参可以不传参数 chi ...
- ruby中的多线程和函数的关键字传参
1.实现ruby中的多线程 # def test1 # n = 1 # if n > 10 # puts "test1结束" # else # while true # sl ...
随机推荐
- Python 踩坑之旅进程篇其四一次性踩透 uid euid suid gid egid sgid的坑坑洼洼
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 菜 ...
- Joda-Time简介
Joda-Time提供了一组Java类包用于处理包括ISO8601标准在内的date和time.可以利用它把JDK Date和Calendar类完全替换掉,而且仍然能够提供很好的集成. Joda-Ti ...
- unity3d + photon + grpc + nodejs + postgis/postgresql 游戏服务器设计
unity3d + photon + grpc + nodejs + postgis/postgresql 游戏服务器设计 最近做玩票性质的游戏项目,客户端技术是 unity3d 和 android. ...
- asp.net mvc整合Nhibernate的配置方法
http://blog.csdn.net/xz2001/article/details/8452794 http://www.cnblogs.com/GoodHelper/archive/2011/0 ...
- Redis、Memcache区别
Redis.Memcache区别 redis单核 memcahce多核 redis支持数据持久化 redis支持的数据类型比较多 memcache 只有key->value类型 key-> ...
- 数据库操作----找了MySQL和SQL Sever两个的基础语句
这是MySQL的基本操作: 1 登入数据库:mysql -uroot -p+密码 (SQL Sever登入: osql -U 用户名 -P 密码) 显示已存在的数据库:show databases; ...
- Windows7(x86) xampp php5.5 imagick install
I hate windows. 1. 下载安装 ImageMagick, 选择合适您电脑的版本,我下载的是: ImageMagick-6.8.9-1-Q16-x86-dll.exe http://ww ...
- This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms while caching
今天运行自己的网站时报了这样一个错误,很是纳闷,这个网站运行了这么久,怎么报这个错呢,原来是做缓存的时候用到了基于windows平台的加密算法.解决方法如下: 删除注册表下的这个节点即可.删除HKEY ...
- Codeforces Round #313 (Div. 2) A.B,C,D,E Currency System in Geraldion Gerald is into Art Gerald's Hexagon Equivalent Strings
A题,超级大水题,根据有没有1输出-1和1就行了.我沙茶,把%d写成了%n. B题,也水,两个矩形的长和宽分别加一下,剩下的两个取大的那个,看看是否框得下. C题,其实也很简单,题目保证了小三角形是正 ...
- UVA208 Firetruck 消防车(并查集,dfs)
要输出所有路径,又要字典序,dfs最适合了,用并查集判断1和目的地是否连通即可 #include<bits/stdc++.h> using namespace std; ; int p[m ...