目录结构:/d/home/bash_test/
total 39
drwxr-xr-x 1 Administrator 197121 0 12月 6 16:22 demo_folder1/
drwxr-xr-x 1 Administrator 197121 0 12月 6 16:22 demo_folder2/
prw-rw-rw- 1 Administrator 197121 0 12月 10 20:09 my_pipe|
-rwxr-xr-x 1 Administrator 197121 40 12月 15 02:19 pub.sh*
-rw-r--r-- 1 Administrator 197121 1311 12月 15 02:25 t.tmp
-rwxr-xr-x 1 Administrator 197121 12018 12月 15 02:28 ta.sh*
pub.sh的代码:
#!/bin/sh
pub(){
echo "pub_sh_func";
}
ta.sh的代码:
#!/bin/sh
#导入同目录下的pub.sh
#被包含的文件不用设置执行权限
. ./pub.sh
#调用pub.sh中的函数pub
pub;
#下方使用多行注释
< ./t.tmp;
#如上使用过stdout定向后,stderr可以定向到stdout
ls -al ./ > ./t.tmp 2>&1;
#从文件读取,追加输出到文件
head -5 < $0 >>./t.tmp;
#here document
printf "here document内行数统计:";
wc -l << EOF
echo "this is a test";
echo "the second line";
#结尾处的EOF旁不能又多余字符,而且必须在行首
EOF
cat << EOF
echo "this is a test";
echo "the second line";
#结尾处的EOF旁不能有多余字符,而且必须在行首
EOF
}
chapter7(){
echo "chapter7";
echo "流程控制:";
if [[ ! 0 ]];then
#0本身也是true,!取反后为false,所以执行结果为false
echo "true";
else
echo "false";
fi
echo -n "请输入一个数字: ";
#用read从控制台读取输入存入变量
read num;
local i=$(($num - 6));
while :
#冒号前的空格很重要,这种写法相当于C语言的while(1)
#其他写法for((;;))或while(true)
do
echo $i;
let i++;
if [[ $i -gt 3 ]];then break;fi
done
while(($i<=$num));do
echo $i;
let "i++";
done
echo "请在下列选项中做出选择:";
choices=( "1" "2" );
select val in "${choices[@]}";do
#输入错误时发送到错误输出stderr即&2中,并执行continue
[[ -n $val ]] || { echo "Invalid choice.">&2; continue; }
echo -n "输入结果(1/2): "
#read val;
case $val in
1) echo "你选择了1";
;;
2) echo "你选择了2";
;;
esac
break;
done
echo "Please input a command(cpu|mem|device|CD-ROM)"
read cmd
case $cmd in
cpu) echo "The cpu information is"
cat /proc/cpuinfo;;
mem) echo "The mem information is"
cat /proc/meminfo;;
device) echo "The device information is"
cat /proc/scsi/device_info;;
CD-ROM) echo "The CD-ROM information is"
cat /proc/sys/dev/cdrom/info;;
*) echo "Your input command is invalid"
esac
#关于循环的一点思考
#i如果想初始化就不能用local修饰,不然while访问不到
i=1;
while((i<=9))
do
printf "i:%d\t" "$i";
for ((j=0;j<$i;j++))
do
#printf后方跟的参数间的空格是必须
printf "j:%d\t" "$j";
if [[ $j -ge 3 ]]; then
#break只终止当前层循环
break;
fi
done
printf "\n";
let i++;
done
}
last_cmd_status_code(){
set -x;
status_code=${?};
echo "status_code:$status_code";
#我们再观察一下if判断语句中status_code的变化
if test ${?} -eq ${status_code}
then
echo "if判断的status_code(在判真分支中为0,在判假分支中为非0): ${?}";
else
echo "if判断的status_code(在判真分支中为0,在判假分支中为非0): ${?}";
fi
set +x;
}
chapter8(){
echo "chapter8";
echo_line;
echo "main的参数个数为: $#";
echo "main的参数(以字符串显示): $*";
echo "main的参数(以字符数组显示): $@";
echo "当前脚本的进程ID: ${$}";
echo "后台最后一个进程的ID: ${!}";
echo "shell当前使用的选项: ${-}";
echo "$(date)";
last_cmd_status_code;
}
main(){
for_test;
for ((i=1;i<=7;i++))
do
echo_line;echo_line;
chapter${i} "$@";
done
}
main "$@";
打印结果:
λ ./ta.sh
pub_sh_func
demo_folder1/ demo_folder2/
=================================================================================
=================================================================================
chapter1:
./ta.sh: line 77: unset: temp: cannot unset: readonly variable
echo字符试试\!
a=10 b=20 a和b的和:c = 30
a=10 b=20 a和b的积:d = 200
a less than b is true
数值比较一共六种: eq ne gt ge lt le
=================================================================================
=================================================================================
chapter2:
str : hello str_add : _world str_comb : hello_world
test -z $str_comb为假, str_comb不空
test -n $str_comb为真, str_comb不空
str_comb的长度为: 11
=================================================================================
在变量str_comb中查找字母w或o返回的索引: 5,对应下标为: 6
查找到的字符为: w
在str_comb中从指定下标6开始取字符到末尾得到: world
替换str_comb中的"world"为"bash": hello_bash
=================================================================================
str_arr 的三个成员str、str_add、str_comb:
hello _world hello_bash
拼接数组元素为str_arr_comb: hello _world hello_bash
替换str_arr_comb中所有的"hello"为"hola": hola _world hola_bash
=================================================================================
数组str_arr的长度为: 3
=================================================================================
=================================================================================
chapter3
变量的判断:
":-"
注:以下提到的null均代表未赋值或不存在
注:shell真值和假值的否定均为真
a赋值为null,b赋值为1,${a:-$b}返回值为: 10
a赋值为1024,b赋值为1,${a:-$b}返回值为: 1024
a赋值为null,b赋值为1,${a-$b}返回值为: 1
a赋值为1024,b赋值为1,${a-$b}返回值为: 1024
以上两种判断总结:
a为真返回a,
a为假返回任意指定值b,
有点像C语言的" ?: ",不同的是此处真值返回值为判断值本身a赋值为null,b赋值为1,${a:+$b}返回值为:
a赋值为1024,b赋值为1,${a:+$b}返回值为: 1
":+"判断总结:
a为真返回值为任意指定值b,返回值的否定依然为真,
a为假返回值为null,返回值否定为真,
适合做变量关联或返回值绑定,
即对a判真后返回值为b,对a判假返回值为假,与" := "判定结果相反,
应用举例见代码:
+ local word=1
++ echo
+ test
+ local var=1024
++ echo 1
+ test 1
+ echo -e '执行结果打印1024\n'
执行结果打印1024+ set +x
a赋值为null,b赋值为1,${a:=$b}返回值为: 1
a赋值为1024,b赋值为1,${a:=$b}返回值为: 1024
":="判断总结:
a为真返回a,
a为假赋值b给a并返回,
只有这个判定对变量a做出了赋值操作,
适合用于默认值赋值操作,
即a真返回a,a假返回赋值为b的a,用$()和echo捕捉结果赋值回a
=================================================================================
=================================================================================
chapter4
文件测试:
pth目录: /d/home/bash_test
test -d $pth目录存在
pth目录下文件total 42
drwxr-xr-x 1 Administrator 197121 0 12月 15 02:45 .
drwxr-xr-x 1 Administrator 197121 0 12月 15 02:45 ..
-rw-r--r-- 1 Administrator 197121 12288 12月 8 14:57 .test.c.swp
drwxr-xr-x 1 Administrator 197121 0 12月 6 16:22 demo_folder1
drwxr-xr-x 1 Administrator 197121 0 12月 6 16:22 demo_folder2
prw-rw-rw- 1 Administrator 197121 0 12月 10 20:09 my_pipe
-rwxr-xr-x 1 Administrator 197121 40 12月 15 02:19 pub.sh
-rw-r--r-- 1 Administrator 197121 756 12月 15 02:45 t.tmp
-rwxr-xr-x 1 Administrator 197121 12018 12月 15 02:28 ta.sh
-rw-r--r-- 1 Administrator 197121 0 12月 15 02:45 tbb
=================================================================================
fl文件: /d/home/bash_test/ta.sh
test -e $fl, fl文件存在
test -s $fl, fl不为空
test -r $fl, fl可读
test -w $fl, fl可写
test -x $fl, fl可执行
test -b $fl, fl不是块设备文件
test -c $fl, fl不是字符设备文件
test -f $fl, fl是普通文件
test -u $fl, fl的user执行位(SET USER ID)未被设置成s
执行者无法以文件所有者身份执行文件
test -g $pth和$fl, pth和fl的group执行位(SET GROUP ID)均未被设置成s
执行者无法以文件所有者群组身份执行文件
test -k $pth, pth的other执行位未设置成防删除位(stick bit)t
=================================================================================
pp文件: /d/home/bash_test/my_pipe
test -p $pp, pp是有名管道
=================================================================================
创建一个软链接
-rw-r--r-- 1 Administrator 197121 0 12月 15 02:46 /d/home/bash_test/tbb
test -L /d/home/bash_test/tbb: not exist
test -e /d/home/bash_test/tbb: exist#提一嘴grep的正则
#fgrep是不用正则
#grep是正常正则只认以下几个元字符 ^ $ . [ ] *
#egrep是grep元字符基础增加了 ? + | 和 ( ) { }
#并且egrep中 ( ) { } 四个符号均需要转义使用
=================================================================================
=================================================================================
chapter5
printf函数
姓名 性别 体重kg 成绩
郭靖 男 66.12 C
杨过 男 48.65 A
郭芙 女 47.99 B
=================================================================================
=================================================================================
chapter6
标准输入输出重定向
将head $0命令结果发送到发送到标准输出1:
head: cannot open '1' for reading: No such file or directory
here document内行数统计:3
echo "this is a test";
echo "the second line";
#结尾处的EOF旁不能又多余字符,而且必须在行首
=================================================================================
=================================================================================
chapter7
流程控制:
false
请输入一个数字: 8
2
3
4
5
6
7
8
请在下列选项中做出选择:
1) 1
2) 2
#? 2
输入结果(1/2): 你选择了2
Please input a command(cpu|mem|device|CD-ROM)
mem
The mem information is
MemTotal: 12547000 kB
MemFree: 8093712 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 12547000 kB
LowFree: 8093712 kB
SwapTotal: 786432 kB
SwapFree: 648064 kB
i:1 j:0
i:2 j:0 j:1
i:3 j:0 j:1 j:2
i:4 j:0 j:1 j:2 j:3
i:5 j:0 j:1 j:2 j:3
i:6 j:0 j:1 j:2 j:3
i:7 j:0 j:1 j:2 j:3
i:8 j:0 j:1 j:2 j:3
i:9 j:0 j:1 j:2 j:3