shell脚本学习笔记

目录结构:/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

你可能感兴趣的:(debian,gnu,bash)