结构化命令
#--------------------条件判断--------------------- #if-then 语句 格式(可将换行换成;分隔) if command -- 和其他编程语言不一样会执行if后面的命令,命令结束返回状态码为0才会执行then后的命令 then commands fi -- 以fi结束 #if-then-else 语句 格式 if command then commands else commands -- if命令返回状态码非0则执行else命令组 fi #嵌套if 嵌套在if-then-else中的else语句中 if command then commands else commands if command then commands else commands -- 可以不使用else fi fi elif(else与if的合并,与直接嵌套if-then相比不能执行else语句) if command then commands elif command then commands elif command then commands elif command then commands else commands -- 可以不使用else fi case(替代if-then-else对一个变量的多次判断) 变量variable与模式pattern匹配,则执行commands case variable in pattern1 | pattern2 ) commands1 ;; pattern3 ) commands2 ;; *) default commands ;; esac 例如: case $sw_cs in 1 | 2) echo 1 or 2 ;; -- |或者 3) echo 3 ;; *) echo x ;; -- 其他任意输出x esac -- 结束符 #解决if命令与其他编程语言不一致:测试test if test $my_variable if [ $val1 -gt 5 ] -- 使用[]内部两端需要留空格,无须声明test test支持三类测试 test数值比较(只支持整数) n1 -eq n2 检查 n1 是否与 n2 相等 n1 -ge n2 检查 n1 是否大于或等于 n2 n1 -gt n2 检查 n1 是否大于 n2 n1 -le n2 检查 n1 是否小于或等于 n2 n1 -lt n2 检查 n1 是否小于 n2 n1 -ne n2 检查 n1 是否不等于 n2 如:if [ $val1 -gt 5 ] -- 判断变量val1的值是否大于5 test字符串比较 在比较字符串的相等性时,比较测试会将所有的标点和大小写情况都考虑在内 > < 符号需要转义,否则会被识别成重定向(大写字母的排序和sort排序不同,是根据ASCII值:小写字母值更大) 通过-n,-z测试空字符串和未初始化变量 if [ -n $val1 ] -- 变量val1字符串长度是否非0 if [ -z $val1 ] -- 变量val1字符串长度是否为0,未初始化的变量默认为0 test文件比较 if [ -d /etc ] -- 检查目录 if [ -e /etc/passwd ] -- 检查文件和目录 if [ -f /etc/passwd ] -- 仅限文件检查 if [ -r /etc/passwd ] -- 检查文件或目录是否可读 if [ -w /etc/passwd ] -- 检查文件或目录是否可写(属组没有权限编辑) if [ -x /etc/passwd ] -- 检查文件或目录是否可执行 if [ -s /etc/passwd ] -- 检查文件或目录是否未空 if [ -O /etc/passwd ] -- 检查测试出你是否是文件或目录的属主 if [ -G /etc/passwd ] -- 检查文件或目录是否属于默认组(不会检查其他组) if [ /etc -nt /etc/passwd ] -- 检查文件或目录是否更新(系统目录先于文件创建) if [ /etc -ot /etc/passwd ] -- 检查文件或目录是否更旧 复合条件测试:布尔运算符 if [ condition1 ] && [ condition2 ] -- AND布尔运算 if [ condition1 ] || [ condition2 ] -- OR布尔运算 if-then高级特性,替代test对数值和字符串的比较 if (( 5 ** 2 > 90 )) -- 数值比较使用双括号。表达式算术符号不需要转义。5的2次方 if [[ run == r* ]] -- 字符串比较使用双方括号。判断run是否是r开头的字符串 #--------------------循环--------------------- #for命令 读取列表中的值 格式 for var in list -- 变量var会自动声明。 for 循环设定list的每个值都是用空格分割 do commands done 每次 for 命令遍历值列表,它都会将列表中的下个值赋给 $test 变量 for test in 1 2 test do echo $test done -- 最后$test=test 处理空格和引号(单/双)的情况 for test in I don\'t know if "this'll" work "3 2 1" 'o"k' do echo "word:$test" done -- 空格可使用单双引号解决,引号可以使用相反引号或转义解决 处理从变量读取列 向变量中存储的已有文本字符串尾部添加文本的常用方法:list=$list" run" for test in $list 从命令读取值 echo $list list=sw_cs.sh -- 文件空格、制表符、换行都会识别为分隔符 for var in $(cat $list);do echo $var;done 更改字段分隔符(由 IFS 环境变量决定。默认:空格,制表符,换行符) 分隔符临时更改需要备份 IFS_OLD=$IFS -- IFS的值是不可见的 IFS=$'\n' -- 分隔符改成换行 IFS=$IFS_OLD -- 还原 多个分隔符赋值 IFS='\n':\; -- 赋值行串起来,分号需要转义 用通配符读取目录 for file in /home/ly_ibas/* do if [ -d $file ] then echo $file is a d elif [ -f $file ] then echo $file is a r fi done C语言风格的for循环 for ((a=0;a<9;a++)) do echo $a done 嵌套循环(for,while,until) 如: for (( a = 1; a <= 3; a++ )) do echo "Starting loop $a:" for (( b = 1; b <= 3; b++ )) do echo " Inside loop: $b" done done 循环处理文件数据: IFS.OLD=$IFS IFS=$'\n' for entry in $(cat /etc/passwd) do echo "Values in $entry –" IFS=: for value in $entry do echo " $value" done done #while命令 格式: while test command -- while是if-then和for的结合 do other commands done 如:while echo $var1 [ $var1 -gt 0 ] -- 判断var1是否大于0 do echo $var1 var1=$[ $var1 - 1 ] done #until(与while命令相反,状态码返回非0执行) 格式: until test command do other commands done 如:until echo $var1 [ $var1 -eq 0 ] do var1=$[ $var1 - 25 ] done #控制循环 break命令 -- 只能跳出一层循环 跳出单个循环(跳出for,while,until) for var1 in 1 2 3 4 5 6 7 8 9 10 do if [ $var1 -eq 5 ] then break fi echo "Iteration number: $var1" done -- 1 2 3 4 var1=1 while [ $var1 -lt 10 ] -- 判断是否小于10 do if [ $var1 -eq 5 ] then break fi echo "Iteration: $var1" var1=$[ $var1 + 1 ] done 跳出内部循环 for (( a = 1; a < 4; a++ )) do echo "Outer loop: $a" for (( b = 1; b < 100; b++ )) do if [ $b -eq 5 ] then break fi echo " Inner loop: $b" done done 跳出外部循环 -- break n,默认n=1跳出当前循环,n代表层级 for (( a = 1; a < 4; a++ )) do echo "Outer loop: $a" for (( b = 1; b < 100; b++ )) do if [ $b -gt 4 ] then break 2 -- 当n=2跳出外层循环,当n=3跳出再外层循环 fi echo " Inner loop: $b" done done continue命令 -- 不完全跳出循环 for (( var1 = 1; var1 < 15; var1++ )) do if [ $var1 -gt 5 ] && [ $var1 -lt 10 ] then continue fi echo "Iteration number: $var1" done -- 1 2 3 4 5 10 11 12 13 14 for (( a = 1; a <= 5; a++ )) do echo "Iteration $a:" for (( b = 1; b < 3; b++ )) do if [ $a -gt 2 ] && [ $a -lt 4 ] then continue 2 -- 跳出继续执行外层循环 fi var3=$[ $a * $b ] echo " The result of $a * $b is $var3" done done -- a=3未执行内存循环,外部循环a=4继续执行 #处理循环输出(> |) for file in /home/rich/* do if [ -d "$file" ] then echo "$file is a directory" elif echo "$file is a file" fi done > sw_cs #实例 查找可执行文件 IFS=: for folder in $PATH do for file in $folder/* -- 迭代特定目录中的文件 do if [ -x $file ] then echo " $file" fi done done 创建多个用户账户(未验证) useradd user1 -- 添加单个用户user1 input="users.csv" while IFS=',' read -r userid name do echo "adding $userid" useradd -c "$name" -m $userid done < "$input" -- root用户才能执行,/etc/passwd查看用户是否创建
生活就要逢山开路遇水搭桥,愿共勉!