操作某个目录下的子目录:
统计某个目录所有子目录有多少行代码:
(cd src; files=`ls`; for file in $files; do echo "stat dir$file"; find $file -name "*.*pp"|xargs wc -l|grep"total"; done)
取文件名/扩展名/路径之类:
取路径的文件名:
path="/home/winlin/file.txt"
# file.txt
echo `basename $path`
取路径的目录:
path="/home/winlin/file.txt"
# /home/winlin
echo `dirname $path`
取文件的文件名:
file="/home/winlin/file.txt"
# /home/winlin/file
echo "${file%.*}"
取文件的扩展名:
file="/home/winlin/file.txt"
# txt
echo "${file##*.}"
子函数用法:
定义可以调用的子函数,$0是脚本的$0,其他是传递给函数的名称,代码如下:
function print(){
echo "args: $0(app name) $1(arg0)$2(arg1)"
}
arg0="winlin" arg1=27
print $arg0 $arg1
其实可以用句号或source执行另外的脚本,把脚本当作函数,好处是调试方便。参考“执行其他脚本(伪函数调用)”。
FOR典型用法:
for可以用来执行多次指令,譬如每隔一秒看看当前的1935端口的连接数:
for((;;)); do netstat -an|grep 1935|grep ESTABLISHED|wc -l; sleep 1;done
也可以写成容易看懂的多行:
for((;;)); do
netstat -an|grep 1935|grep ESTABLISHED|wc -l;
sleep 1;
done
假设执行指定次数:
for((i=0;i<10;i++)); do
netstat -an|grep 1935|grep ESTABLISHED|wc -l;
sleep 1;
done
算术运算/运行结果/退出等:
算数运算用let,譬如:
var=100
let var=${var}*100
echo $var
退出直接用exit就行,后面跟返回值:
exit -1
运行结果若需要保存到变量,可以用``,键盘“1”旁边的那个键:
var=`date +%s`
echo $var
数组及其遍历(for)方法:
定义数组的方法是用小括号:
arr=("ab" "cd" "ef")
所以可以把ls的结果作为数组:
files=`ls temp`
for file in ${files[*]}; do
echo $file
done
数组的复制:
MOUDULE_FILES=("smart_app" "smart_server")
APP_OBJS="${MOUDULE_FILES[@]}"
echo ${MODULE_OBJS}
遍历方法之一:
for item in ${arr[*]}; do
echo ${item}
done
遍历方法之二:
for((i=0; i <${#arr[*]};i++)); do
echo ${arr[$i]}
done
文件目录存在性(if)判断:
以下脚本用到了文件存在性和目录存在性判断,if-elif-then-else-fi结构。
test_dir="mydir" test_file="myfile"
if [ ! -d ${test_dir} ] && [ ! -f ${test_file} ]; then
echo "dir(${test_dir}) andfile(${test_file}) does not exists"
elif [ ! -d ${test_dir} ]; then
echo "dir(${test_dir}) does not exists"
elif [ ! -f ${test_file} ]; then
echo "file(${test_file}) does notexists"
else
echo "both file(${test_file}) and dir(${test_dir})exist"
fi
脚本的参数使用:
遍历所有的参数的方法,用for:
for option; do
echo $option
done
这样就可以一个一个参数取到了,用在分析程序参数上面,特别是无序的参数,例如编译选项。
取某个参数的方法,以及判断参数个数是否达标:
if [[ $# -lt 3 ]]; then
echo "Usage: $0 <arg0> <arg1><arg2>"
exit 1
fi
arg0=$1
arg1=$2
arg2=$3
echo "$0 $# arg0=$arg0, arg1=$arg1, arg2=$arg2"
执行其他脚本(伪函数调用),可以用source,或者用一个句号,例如:
命令 . options.sh 将会执行options.sh文件,不会重新打开进程,所以当前的变量都可以用,可以作为函数调用。
使用function定义的函数,没有直接用变量的方便,譬如:
name="winlin"age=27 . print.sh
注意,句号后面必须要有个空格。其中,print.sh这么写:
# arguments:
# @param name the name
# @param age the age
echo "name:$name, age:$age"
块操作/块注释,可以把整个块作为操作,例如:
cat << END
hello, server!
this is a block!
END
把END和END之间的内容给cat,就相当于echo出来。
可以把它定向到文件,譬如定义一个常量到文件:
cat << END >> header.hpp
#ifndef MY_VAR
#define MY_VAR "linux"
#endif
END
因此可以用它来注释某块:
cat << END >> /dev/null
for option; do
echo $option
done
END
定义变量方式:
winlin=”abc”等价于winlin=abc
但不等于winlin= abc,它等价于winlin=” abc”
若为空则定义的运算符:“:-”冒号横杠
winlin=${winlin:-${value}}表示若winlin没有定义,则使用变量value的值。
也可写成常量:winlin=${winlin:-“my_value”}等价于 winlin=${winlin:-my_value}
也可以用其他变量:winlin=${condi:-${value}}若变量condi没有定义,则使用变量value的值。
http://www.gnu.org/software/bash/manual/bashref.html
显示选择菜单的语法如下:
select sel in "s0""s1" "s2";
do
case $sel in
"s0")
echo "s0: ok";
break;;
"s1")
echo "s1: ok";
break;;
"s2")
echo "s2: ok";
break;;
*)
echo "invalid choice";
continue;;
esac
done