常用linux shell脚本记录
2015-12-30 21:05 youxin 阅读(586) 评论(0) 编辑 收藏 举报遍历目录下所有的文件是目录还是文件
for file in ./* do if test -f $file then echo $file 是文件 fi if test -d $file then echo $file 是目录 fi done
filelist=`ls ./proto` echo $filelist for file in $filelist;do #不能有判断if [-f $file ] ,为什么?因为文件是在当前目录的proto目录下,我们filelist输出的是文件列表,没有带路径,-f x.proto x.proto不在当前目录,肯定为false,if永远为假,加上路径才能为true,if [ -f ./proto/$file ];then 这样就可以了。 #protoc -I=proto --cpp_out=cpp/ proto/ClientGate.proto protoc -I=proto --cpp_out=cpp/ proto/$file # protoc -I=proto -olua/$(basename $file .proto).pb proto/$file done ~ ~ protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
在shell中的case结构与C/C++中的switch结构是相同的. 它允许通过判断来选择代码块中多条路径中的一条. 它的作用和多个if/then/else语句的作用相同, 是它们的简化结构, 特别适用于创建菜单.
case "$variable" in "$condition1" ) command... ;; "$condition2" ) command... ;; esac Note
对变量使用""并不是强制的, 因为不会发生单词分割.
*
每句测试行, 都以右小括号)来结尾.
*
每个条件判断语句块都以一对分号结尾 ;;.
*
case块以esac (case的反向拼写)结尾.
#!/bin/sh case $1 in start|begin) echo "start something" ;; stop) echo "stop !!" ;; *) echo "ignorant" ;; esac
shell中函数调用
#!/bin/bash function LoopPrint() { count=0; while [ $count -lt $1 ]; do echo $count; sleep 1 let ++count; 、、这里不能是++$count,否则无穷循环 done return 0; } read -p "please input the times of print:" n; LoopPrint $n;
特别注意,传递参数时,(这个例子中)一定要写成LoopPrint $n;而不能写成LoopPrint n。为什么?例如你输入的是20,则n的值($n)为20,前者表示的是把n的值,即20传递给函数LoopPrint,而后者则表示把字符n传递给函数LoopPrint。这点与在静态语言中的函数参数传递是很不同的,因为在Shell中变量的使用并不需要先定义,所以要使用变量,让Shell知道它是一个变量,并要传递它的值时,就是用$n,而不能直接用n,否则只把n当作一个字符来处理,而不是一个变量。c
Linux常用Shell脚本珍藏
shell字符串拼接
对于变量或者字符串的连接,shell提供了相当简单的做法
直接放到一起或用双引号即可。
例如$a, $b,有
c=$a$b
c=$a"xyz"$b
c=$a$b.txt
如果想要在变量后面添加一个字符,可以用一下方法:
$value1=home
$value2=${value1}"="
echo $value2
把要添加的字符串变量添加{},并且需要把$放到外面。
这样输出的结果是:home=,也就是说连接成功。
又如:
[root@localhost sh]# var1=/etc/
[root@localhost sh]# var2=yum.repos.d/
[root@localhost sh]# var3=${var1}${var2}
[root@localhost sh]# echo $var3
/etc/yum.repos.d/
function restart() { cd $1 if [ ! -e *.conf ] then echo "no config file" return fi if [ -e server.pid ]; then pid=`cat server.pid` echo "kill pid=$pid" kill $pid while true do oldpid=`ps -ef|grep $1|grep $pid`; if [ $oldpid" " == $pid" " ]; then echo $oldpid" "$pid sleep 1 else break fi done ../daeml ./$1 else ../daeml ./$1 fi } case $1 in login_server) restart $1 ;; msg_server) restart $1 ;; route_server) restart $1 ;; http_msg_server) restart $1 ;; file_server) restart $1 ;; push_server) restart $1 ;; db_proxy_server) restart $1 ;; *) echo "Usage: " echo " ./restart.sh (login_server|msg_server|route_server|http_msg_server|file_server|push_server)" ;; esac
# tool
red=31
green=32
yellow=33
blue=34
echoColor() {
local color=$1
shift
echo -e "\033[${color}m$@\033[m"
}
process_count=`ps -ef |grep -v grep | grep "xxx" | wc -l`
if [ $process_count == $arr_len ]
then
echoColor $green "start all process success.:) "
else
echoColor $red "start all Failed!! "
fi
#kill 所有的带有AAAA的游戏进程
ps -ef |grep -v grep | grep "AAAA" |awk '{print $2}'|xargs kill -9
linux shell 获取当前正在执行脚本的绝对路径
basepath=$(cd `dirname $0`; pwd)
在此解释下basepath :
dirname $0,取得当前执行的脚本文件的父目录 cd `dirname $0`,进入这个目录(切换当前工作目录) pwd,显示当前工作目录(cd执行后的)
由此,我们获得了当前正在执行的脚本的存放路径。
【`】,学名叫“倒引号”, 如果被“倒引号”括起来, 表示里面需要执行的是命令。
比如 `dirname $0`, 就表示需要执行 dirname $0 这个命令
【“”】 , 被双引号括起来的内容, 里面 出现 $ (美元号: 表示取变量名) `(倒引号: 表示执行命令) \(转义号: 表示转义), 其余的才表示字符串。
【’‘】, 被单引号括起来的内容, 里面所有的都表示串, 包括上面所说的 三个特殊字符。
在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的。因为他返回当前路径的"."。
这个命令写在脚本文件里才有作用,他返回这个脚本文件放置的目录,并可以根据这个目录来定位所要运行程序的相对位置(绝对位置除外)。
$0:当前Shell程序的文件名
dirname $0,获取当前Shell程序的路径
cd `dirname $0`,进入当前Shell程序的目录
Linux脚本下倒引号(`)与$()
一、倒引号(`)在Linux的作用
倒引号(`)在Linux中就是将倒引号内的Linux命令先执行,然后将执行结果赋予变量。
二、$()的作用
$()和 ` `:
在 bash shell 中,$( ) 与` ` (倒引号) 都是用来做命令替换用(commandsubstitution)的。
例如 version=$(uname -r)和version=uname -r都可以是version得到内核的版本号
各自的优缺点:
1. 倒引号 基本上可用在全部的 unix shell 中使用,若写成 shell script ,其移植性比较高。但反单引号容易打错或看错。
2. $()并不是所有shell都支持。
---------------------
一、dirname指令
1、功能:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
2、用法:dirname filename
例如下面几个例子
(1)# dirname /etc/sysconfig/network-scripts/ifcfg-eth0
/etc/sysconfig/network-scripts
二、basename指令
1、功能:从给定的包含绝对路径的文件名中去除左边目录部分或者同时去除某个后缀的内容(目录的部分),然后返回剩下的部分(非目录的部分)
$():这个小括号里放的是命令,和``反引号作用一样,执行这个命令
${}:这里面放的是变量,用来引用的
${ }变量替换
一般情况下,$var与${var}是没有区别的,但是用${ }会比较精确的界定变量名称的范围
exp 1
[root@localhost ~]# A=Linux [root@localhost ~]# echo $AB #表示变量AB [root@localhost ~]# echo ${A}B #表示变量A后连接着B LinuxB
几种特殊的替换结构
1
|
${var:-string},${var:+string},${var:=string},${var:?string} |
①${var:-string}和${var:=string}
:若变量var为空,则用在命令行中用string来替换${var:-string}
,否则变量var不为空时,则用变量var的值来替换${var:-string}
;对于${var:=string}
的替换规则和${var:-string}
是一样的,所不同之处是${var:=string}
若var为空时,用string替换${var:=string}
的同时,把string赋给变量var: ${var:=string}
很常用的一种用法是,判断某个变量是否赋值,没有的话则给它赋上一个默认值。
② ${var:+string}
的替换规则和上面的相反,即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量 var的值,即空值。(因为变量var此时为空,所以这两种说法是等价的)
③${var:?string}替
换规则为:若变量var不为空,则用变量var的值来替换${var:?string}
;若变量var为空,则把string输出到标准错误中,并从脚本中退出。我们可利用此特性来检查是否设置了变量的值。
补充扩展:在上面这五种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出。、、、、
Shell获取前N天日期
在linux环境下要取得几天前的时期只要使用
date -d "x days ago" +%Y%m%d
x用数字代替,如果需要几天前的直接写正数,如果要几天后的日期直接写负数即可;
列出当前目录下的所有 Shell 脚本文件:
- #!/bin/bash
- for filename in $(ls *.sh)
- do
- echo $filename
- done
循环日期
start_date="20220317" end_date="20220423" while [ "$start_date" -le "$end_date" ]; do #dash_stat_date=`date -d "$start_date" +%Y-%m-%d` #echo $dash_stat_date start_date=$(date -d "$start_date+1days" +%Y%m%d) done
Shell脚本里,在用参数作比较的时候,如“ [ $temp -eq "iPhone" ]”,可能会出现如题的“ integer expression expected”错误。这是因为这几个参数: -gt ,-lt,-eq 比较的都是数字和变量,因此变量temp如果是一个字符串的话就会出现上述错误了。将原句改为“ [ $temp -eq iPhone ]” 结果也是一样的
————————————————
shell数组:
Shell 数组的定义和循环
在 Shell 中,用括号( )
来表示数组,数组元素之间用空格来分隔。由此,定义数组的一般形式为:
array_name=(
ele1
ele2
ele3 ... elen)
arr=(
"a"
"b"
"c"
)
echo
"所有的内容如下:"
${arr[@]}
echo
"数组的长度:"
${
#arr[*]}
for
var
in
${arr[@]}
do
echo
"打印的内容:"
$var
done
shell遍历数组的3种用法:
for … in 不带数组下标
for element in ${array[@]} #也可以写成for element in ${array[*]} do echo $element done
带数组下标
for i in "${!arr[@]}"; do printf "%s\t%s\n" "$i" "${arr[$i]}" done
3. While循环法: i=0 while [ $i -lt ${#array[@]} ] #当变量(下标)小于数组长度时进入循环体 do echo ${ array[$i] } #按下标打印数组元素 let i++ done
Shell函数返回值,常用的两种方式:return,echo
1) return 语句
shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回。
Shell 函数返回值只能是整形数值,一般是用来表示函数执行成功与否的,0表示成功,其他值表示失败。因而用函数返回值来返回函数执行结果是不合适的。如果要硬生生地return某个计算结果,比如一个字符串,往往会得到错误提示:“numeric
argument required”。
如果一定要让函数返回一个或多个值,可以定义全局变量,函数将计算结果赋给全局变量,然后脚本中其他地方通过访问全局变量,就可以获得那个函数“返回”的一个或多个执行结果了。
A、如何调用shell函数(执行函数):函数名 参数
B、获取shell函数结果:$?
C、另外,可以直接用函数的返回值用作if的判断。(示例3)
注意:return只能用来返回整数值,且和c的区别是返回“0”为正确,其他的值为错误。
2) echo 返回值
其实在shell中,函数的返回值有一个非常安全的返回方式,即通过输出到标准输出返回。因为子进程会继承父进程的标准输出,因此,子进程的输出也就直接反应到父进程。
总结:所以,可以总结一下函数返回值获取的方法:
1)用变量接收函数返回值,函数用echo等标准输出将要返回的东西打印出来。
2)用$?来接收函数的执行状态,但是$?要紧跟在函数调用处的后面。
、
1 语法上的返回值
Shell函数返回值不同于很多语言的返回值。
Shell函数返回值:表示退出状态码,只能返回0~255之间的整数。
返回值的正规用途:表示这条命令是执行成功,还是执行失败。执行成功返回0,执行失败返回非0值。
通常,我们不返回值,会自动返回0,表示执行成功。
什么时候需要表示执行失败?
Shell用退出状态码的常用场景:if条件、 语句&& 、语句|| 。如果我们函数用于这些场景,才会去设置返回值。
查看返回值(退出状态码)
$? 返回上一条语句(命令)的退出状态码。
function f6(){
return 100
}
f6
#查看返回状态码
echo $?
f6 && echo "666666"
if `f6` ;then
echo "条件成立"
else
echo "条件不成立"
fi
echo end
将上述代码返回值改为0,或者去掉return这一句,再执行。
2 业务返回值
比如:求和,要返回和;返回一个提示信息的字符串给调用方。
这类返回值,我们称之为业务返回值,不要通过return来传递,严重不规范。
Shell语言没有正式语法来实现返回业务返回值,曲线救国。
方法1:在Shell文件定义一个全局变量,函数内部修改全局变量,调用方访问这个全局变量。
缺陷:除了记函数名,还要记一个额外的全局变量名。
方法2:返回值通过echo打印,调用函数后通过``来执行命令替换。
#业务返回1个字符串
f1(){
echo "网站地址:www.xiaobuteach.com"
}
a=`f1`
echo $a
缺陷:只有返回值能echo,其它内容不要echo;如果是要调试,可借助其它手段看调试信息,例如输出到文件。
优点:知道函数名就能使用。