参考资料:Bourne again shell (bash) by Daniel Robbins
bash 学习记录:
2015年8月29日 20:22:00
* bash变量赋值等号两边不能空格(变量定义时不加"$",这一点你已经写错好多次了) : myevn="ni hao ma"
* 单引号将阻止变量扩展 : ps aux | grep python | grep -v grep | awk '{print $2}' 以达到输出第二列的目的
* 变量分不开时用 {}分隔 : foo${myevn}bar
* export之后,新启动的子程序才能够看到此变量: export EDITOR="emacs" export myevn
* 清除导出的环境是: unset myevn
* dirname , basename 可以拆分文件的路径与文件名: dirname /home/liangwnag/prj/justtest.sln
* 创建一个包含可执行命令结果的环境变量(学名:命令替换): pathdir = `dirname /home/liangwnag/prj/justtest.sln`
* 命令替换的另一种形式:pathdir=%(dirname /home/liangwnag/prj/justtest.sln)
* 可将任何命令放到``或$()之中以达到目的: myfils=$(ls /etc | grep pa)
* 截断字符串,去除一部分字符串:## # % %%
## 从开头进行最长匹配并去除
# 从开头进行最短匹配并去除
% 从结尾进行最短匹配并去除
%% 从结尾进行最长匹配并去除
myevn=foodforthought.tar.gz
echo ${myevn##*fo} : rthrought.tar.gz
echo ${myevn#*fo} : odforthrought.tar.gz
echo ${myevn%.*} : foodforthrought.tar
echo ${myevn%%.*} : foodforthrought
* 取字符串::起始位置:长度:
echo ${myevn:4:5} forth
* 判断是否是tar文件:
#! /bin/bash
# filename mytar.sh and chmod 755 mytar.sh
if [ "${1##*.}" = "tar" ]
then
echo "this is maybe tarball"
else
echo "this is not tarball"
fi
测试: mytar.sh asdf.tar
* 条件语句格式:
if [ condition1 ]
then
action1
elif [ condition2 ]
then
action2
...
else
actionelse
fi
* 变量接收:
$1 $2 ...
$0 : 脚本名称
$# : 参数个数
$@ : 所以参数
2015年8月30日 07:44:58
* 文件运算符: -e(存在) -d(是文件夹) -f(是常规文件) -L(是符号连接) -r(可读) -w(可写) -x(可执行) filename
filename1 -nt(1比2新) - ot(1比2旧) filename2
* 字符串运算符:-z(长度为0) -n(长度非0) string
string1 =(相等) !=(不相等) string2
* 算术运算符:num1 -eq(相等) -nq(不等) -lt(小于) -le(小于等于) -gt(大于) -ge(大于等于) num2
#变量中有空格的,一定要使用双引号括起来,否则会比较失败
#单引号中禁止变量与历史扩展
if [ "$myevn" = "foo bar ori" ]
then
echo "myevn is foo bar ori"
fi
2015年8月30日 11:50:20
* for结构:
for x in one two three four
do
echo $x
done
#以r开头的文件
for myfile in /etc/r*
do
if [ -d "$myfile"]
then
echo "$myfile (dir)"
else
echo "$myfile"
fi
done
#多个文件列表组合
for x in /etc/r??? /var/lo* /tmp/${MYPATH}/*
do
cp "$x" /mnt/tmp
done
#使用函数
for x in /var/log/*
do
echo `basename $x` is a file living in /var/log
done
#输出所有参数
for arg in "$@"
do
echo $arg
done
* 执行算术运算语法: $(( ))
myvar=56
myvar=$(( $myvar +1 ))
* while语法:只要特定条件为真就重复
while [ conditon ]
do
action
done
* until语法:只要特定条件为假就重复
until [ condition ]
do
action
done
#example
var=0
while [ $var -ne 10 ] or untio [ $var -eq 10]
do
var=$(( var + 1 ))
done
* case语法: ) 与 ;; 是语法要求
case %var in
case1)
action1
;;
case2)
action2
;;
....
esac
# example:
case ${x##*.} in
gz)
gzunpack ${SROOT}/${x}
;;
bz2)
bz2unpack ${SROOT}/${x}
;;
*)
echo "archive format not recognized."
exit
;;
esac
* 函数定义语法:
# 类似于脚本的方式使用参数,$1,...$20..., $0, $#, $@都可以使用
# 可以把此函数放到~/bashrc 或~/bash_profile中以交互式的随时使用
tarview () {
echo -n "Display contends of $1"
if [ ${1##*.} = tar ]
then
tar tvf $1
elif [ ${1##*.} = gz ]
then
tar tzvf $1
elif [ ${1##*.} = bz2 ]
then
cat $1 | bzip2 -d | tar tvf -
if
}
* 命名空间:
# bash的函数中创建的变量将全局变量,函数执行完全之后变量还存在
# 使用local myvar来定义局部变量
myvar="hello"
myfun(){
myvar="one two three"
for x in $myvar
do
echo $x
done
}
myvar="hello"
myfunlocalvar(){
local myvar
local x
myvar="one two three"
for x in $myvar
do
echo $x
done
}
* 应用:
#在临时目录编译sed的脚本如下,保是把交互式的命令行输入方式集中到一个脚本中执行:
#! /usr/bin/evn bash
if [-d work ]
then
rm -fr work
if
mkdir work
cd work
tar xzf /usr/src/distfiles/sed-3.02.tar.gz
cd sed-3.02
./configure --prefix=/usr
make
* 通用性修改:
# sed-3.02.ebuild 文件内容如下:
# the sed ebuild file -very simple
P=sed-3.02
A=${P}.tar.gz
# ebuild.sh文件内容如下
#! /use/bin/evn bash
if [ $# -eq 1 ]
then
echo "one argument expected."
exit 1
fi
if [ -e $1 ]
then
#source 命令从文件中读取bash语句然后执行它们,好像他们直接出现在本脚本中一样
source $1
else
echo "ebuild file $1 not exist"
fi
export ORIDIR=`pwd`
export WORKDIR=${ORIDIR}/work
export SRCDIR=${WORKDIR}/${P}
if [ -z "$DISTDIR" ]
then
DISTDIR=/usr/src/distfiles
fi
export DISTDIR
if [ -d ${WORKDIR} ]
then
rm -rf ${WORKDIR}
fi
mkdir ${WORKDIR}
cd ${WORKDIR}
tar xzf ${DISTDIR}${A}
cd ${WORKDIR}
./configure --prefix=/usr
make
#交互式构建使用如下:
#./ebuild.sh sed-3.02.ebuild
2015年8月31日 17:26:00
* 应用, ebuild最终版本:
# save to /etc/ebuild.conf
#向make传递参数:并行度为2
MAKEOPTS="-j2"
#save to ebuild.sh
#将接收两个参数:脚本与动作
if [ $# -ne 3 ]
then
echo "use: ebuild.sh **.ebuild (unpack|compile|all)"
fi
source /etc/ebuild.conf
if [ -z "$DISTDIR" ]
then
DISTDIR=/usr/src/distfiles
fi
export DISTDIR
ebuild_unpack(){
if [ -d ${WORKDIR} ]
then
rm -rf ${WORKDIR}
fi
mkdir ${WORKDIR}
cd ${WORKDIR}
if [ ! -e ${DISTDIR}${A} ]
then
echo "${DISTDIR}${A} does not exist"
exit 1
fi
tar xzf ${DISTDIR}${A}
cd ${WORKDIR}
}
user_compile(){
if [ -e configure ]
then
./configure --prefix=/usr
if
make $MAKEOPTS MAKE="make $MAKEOPTS"
}
ebuild_complile(){
if [ -d "$SRCDIR" ]
then
echo "$SRCDIR" does not exist
exit 1
fi
cd $SRCDIR
user_compile
}
export ORIDIR=`pwd`
export WORKDIR=${ORIDIR}/work
if [ -e $1 ]
then
source $1
then
echo "$1 not exist"
exit 1
fi
export SRCDIR=${WORKDIR}/${P}
case "$2" in
unpack)
ebuild_unpack
;;
compile)
ebuild_compile
;;
all)
ebuild_unpack
ecuild_compile
;;
*)
echo "use: ebuild.sh **.ebuild (unpack|compile|all)"
exit 1
;;
esac
# save to e2fspogs-1.18.ebuild
P=e2fspogs-1.18
A=${P}.tar.gz
# 当默认编译参数及编译方法不满足时,可以自定义编译函数,由于ebuild.sh中的位置不同,本脚本中的会覆盖默认的user_compile
user_compile(){
./configure --enable-iif-shlibs
make
}