shell学习笔记
##变量
##普通变量:
eg1:
name=axe
echo $name
ps.等号两遍不能有空格,否则会报错.
eg2:
name="axe prpr"
echo $name
or
name='axe prpr'
echo $name
ps.双引号中可以引用其他变量,单引号不可以。
eg:
name=axe
fullname="$name prpr"
echo $fullname
eg3:
version=`uname -a`(在变量中引用命令)
echo $version
eg4:
变量的扩增:
echo $PATH
PATH=${PATH}:/home/axe
echo $PATH
or
PATH="$PATH":/home/axe
如果希望预定义一个变量,但是暂时不给他赋值,可以使用decalre命令:
declare INT_NUMBER
typeset -i INT_NUMBER #使用typeset -i 设置正式变量
##环境变量:
env查看:
`axe@axe:~$ env
LC_PAPER=zh_CN.UTF-8
LC_ADDRESS=zh_CN.UTF-8
XDG_SESSION_ID=6
LC_MONETARY=zh_CN.UTF-8
TERM=vt100
……`
or export查看.
eg:
name=axe
echo $name
bash(新建一个子程序)
echo $name(此时没有输出)
exit
export name
bash
echo $name
##取消变量
eg:
name=axe
echo $name
unset name(取消变量)
echo $name
##只读变量
eg:
name=axe
readonly name
name=prpr(此时报错)
##变量的展开替换
eg:name=
echo ${name}
echo ${name:-noset} 如果name存在且不为null则返回其值,否则返回noset
echo ${name:=noset} 如果name存在且不为null则返回其值,否则设置为noset
echo ${name:?message} 如果name存在且不为null则返回其值,否则显示name:message
echo ${name:+set } 如果name存在且不为null返回set,否则返回null
${variable#key} 从头开始删除关键字,最短匹配
${variable##key} 从头开始删除关键字,执行最长匹配
${varibale%key} 从尾开始删除关键字,执行最短匹配
${variable%%key} 从尾开始删除关键字,执行最短匹配
##特殊变量
eg.eg:
vi test2.sh
`#!/bin/sh
echo $$ #表示当前shell进程的ID
echo $0 #表示当前的文件名
echo $1 #表示脚本或函数的输入值
echo $# #表示传递给脚本或函数的参数个数
echo $* #表示传递给脚本或函数的所有参数
echo $@ #表示传递给脚本或函数的所有参数
echo $? #表示函数的返回值
#区别下$*和$@
for i in $*
do
echo $i
done
for i in $@
do
echo $i
done
for i in "$*"
do
echo $i
done
for i in "$@"
do
echo $i
done
#不加""时,两个输出一样为"$1","$2"..加""时,$*会以"$1,$2.."输出
#可以看出没什么吊用
`
wq!
chmod +x test2.sh
./test2.sh a b
执行结果为:
`axe@axe:~/test$ ./test2.sh a b
12304
./test2.sh
a
2
a b
a b
0
a
b
a
b
a b
a
b
ps.这里的$?执行结果为0,表示当前shell上一个命令的退出状态为success.
##算术运算
shell中算术运算使用$(())实现,eg:$((1+2))
支持自增$((x++));mod$((x%y));幂运算$((x**y)) #x的y次方
写一个斐波那契数列的shell:
#!/bin/sh
i=1;j=2
function fibonacci(){
echo $i
echo $j
i=$(($i+$j))
j=$(($j+$i))
fibonacci
}
fibonacci
顺便斐波那契数列的自增比想象中快很多啊。
算术运算也可以用expr实现:
eg:
vi test3.sh
`#!/bin/sh
value1=`expr 2 + 2`
value2=`expr 2 - 2`
value3=`expr 2 \* 2`
value4=`expr 2 / 2`
echo $value1
echo $value2
echo $value3
echo $value4
`
输出结果为:4 0 4 1
##关系运算
vi test4.sh
`#!/bin/sh
if [ $1 -eq $2 ];then
echo "$1=$2"
fi
if [ $1 -ne $2 ];then
echo "$1!=$2"
fi
if [ $1 -gt $2 ];then
echo "$1>$2"
fi
if [ $1 -lt $2 ];then
echo "$1<$2"
fi
if [ $1 -ge $2 ];then
echo "$1>=$2"
fi
if [ $1 -le $2 ];then
echo "$1<=$2"
fi
`
##布尔运算符
eg:
if [ 1 -eq 2 -o 1 -lt 2 ];then echo true;fi;
if [ 1 -ge 1 -a 1 -le 1 ];then echo true;fi;
if [ ! 1 -eq 2 ];then echo true;fi;
##字符串运算符
eg:
if [ a = a ];then echo true;fi;
if [ a != b ];then echo true;fi;
if [ -z ];then echo true;fi;
if [ -n a ];then echo true;fi;
if [ str ];then echo true;fi;
##文件测试运算符
file="/home/axe/test/test1.sh"
if [ -r $file ];then echo true;fi;
if [ -w $file ];then echo ture;fi;
if [ -x $file ];then echo ture;fi;
if [ -s $file ];then echo ture;fi;(是否为空)
if [ -e $file ];then echo ture;fi;(是否存在)
其余:
`
-b file 检测文件是否是块设备文件,如果是,则返回 true。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。
-d file 检测文件是否是目录,如果是,则返回 true。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件)
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回true。
-p file 检测文件是否是具名管道,如果是,则返回 true。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。
`
##字符串
name="axe prpr"
echo $name
echo ${#name} #表示字符串长度
echo `expr index "$name" a` #表示字符a在$name中的位置
name2="axe prpr $name" #双引号拼接字符串
echo ${name:1:4} 提取字符串
##数组
array=(a b c)
echo ${array[1]}
echo ${array[*]} #或者@
echo ${#array[*]} #获取长度
补充:这里同样可以使用declare命令预定义。ps.declare是bash版本2后才有的。
##条件选择
#if else elif fi
eg:
a=b
if [ -n $a ];then echo true;elfi [ -z $a ];then echo ture;fi;
#case in ;; esac
eg:
#!/bin/sh
case $1 in
axe) echo "$1 is a name"
;;
0904) echo "$1 is a date"
;;
esac
#for in do done
eg:
for file in /home/axe/test/*.sh
do
echo $file
done
#while do done
eg:
while read file;do echo "get $file";echo "type CTRL+D to terminate";done;
#until do done
eg:
a=100;until [ `expr $a - 1` -le 0 ] ;do a=`expr $a - 1`;echo $a;done;(输出100-1)
#break,continue
略
##函数
eg:
function name(){
name=axe
echo $name
}
name
eg2:函数的返回值
function add(){
return `expr 1 + 2`
}
add
echo $?
删除函数使用unset.f
eg3:传参
function calputer(){
case $2 in
+) echo `expr $1 + $3`;;
-) echo `expr $1 - $3`;;
*) echo `expr $1 \* $3`;;
/) echo `expr $1 / $3`;;
esac
}
calputer 1 + 2
##重定向
eg:
echo `pwd` > pwd.sh
ls -l < pwd.sh
linux中有一个特殊的设备/dev/null,任何写入此设备的东西将会永远消失。对于大量无意义的输出,可以通过重定向导入/dev/null
echo "pass" | passwd --stdin root > /dev/null
标准输出与错误输出分离重定向:
id axe >>user 2>>error
##文件包含
略
##命令序列的使用技巧
& 开启一个子shell后台运行
&&和|| 前者表示前一个命令执行成功则执行后一个命令,后者则相反。
eg:cat /etc/passwd | awk -F ':' '{print $1}' && echo "success "|| echo "error"
##作业控制
1.开启一个子进程并进入后台 firefox &
2.jobs 查看
3.fg 回调 eg:fg1
## {}使用技巧
echo {a,b,c} 显示a,b,c
echo user{1,2,3} 显示user1,user2,user3
echo {0..10}显示 0,1,2,3,4,5,6,7,8,9,10
echo {0..10..2} 显示 0,2,4,6,8,10
echo a{2..-1} 显示a2,a1,a0,a-1
mkdir /tmp/{dir1,dir2,dir3}
ls -ld /tmp/dir{1,2,3}