运行脚本的方式: sh hello.sh bash hello.sh . ./hello.sh source hello.sh ./hello.sh(需要给用户增加执行权限) 符号 作用 # 注释 ; 命令分隔符 ;; 终止case选项 . 等价于source "" 可以读取""中的部分变量 ‘‘ 阻止String中所有字符的解释 / 路径分隔 \ 转义 ` 反引号中的命令优先执行 : 空命令,变量扩展,子串替换 ? 测试操作符 $ 变量替换,命令替换 #! 用于指定当前脚本的解释器 脚本示例: #!/bin/bash echo hello; echo there filename=ttt.sh if [ -e "$filename" ]; then # 注意: "if"和"then"需要分隔,-e用于判断文件是否存在 echo "File $filename exists."; cp $filename $filename.bak else echo "File $filename not found."; touch $filename fi; echo "File test complete." 脚本解释: 上面脚本使用了一个if分支判断一个文件是否存在,如果文件存在打印相关信息并将该文件备份;如果不存在打印相关信息并创建一个新的文件。最后将输出"测试完成"。 -e filename 如果 filename存在,则为真 -d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真 -L filename 如果 filename为符号链接,则为真 -r filename 如果 filename可读,则为真 -w filename 如果 filename可写,则为真 -x filename 如果 filename可执行,则为真 -s filename 如果文件长度不为0,则为真 -h filename 如果文件是软链接,则为真 -n 当串的长度大于0时为真(非空串) -z 当串的长度为0时为真(空串) 脚本示例: #!/bin/bash varname=b case "$varname" in [a-z]) echo "abc";; [0-9]) echo "123";; esac 脚本解释: 上面脚本使用case语句,首先创建了一个变量初始化为b,然后使用case语句判断该变量的范围,并打印相关信息。如果你有其它编程语言的经验,这将很容易理解。 反斜线\: \n 表示新 \r 表示回车 \t 表示水平制表符 \v 表示垂直制表符 \b 表示后退符 \a 表示"alert"(蜂鸣或者闪烁) \0xx 转换为八进制的ASCII码, 等价于0xx " 表示引号字面的意思 脚本示例: $ cp `mkdir back` test.sh back $ ls 脚本解释: 先创建了 back 目录,然后复制 test.sh 到 back 目录 #!/bin/bash condition=5 if [ $condition -gt 0 ] #gt表示greater than,也就是大于,同样有-lt(小于),-eq(等于) then : # 什么都不做,退出分支 else echo "$condition" fi : > test.sh #把test.sh 文件清空,如果没有这个文件就创建这个文件,功能和 cat /dev/null > test.sh 相同,但是并不会产生一个新的进程 在一个双括号中, ? 就是一个三元表达式 符号 作用 () 局部变量,初始化数组 {} 文件名扩展 [] 条件测试,数组元素 | 分析前面命令的输出,并将输出作为后面命令的输入 - 选项,重定向stdin或stdout ~ home目录 命令组: () 在括号中的变量,由于是在子shell中,所以对于脚本剩下的部分是不可用的。父进程,也就是脚本本身,将不能够读取在子进程中创建的变量,也就是在子shell 中创建的变量 脚本示例: #!/bin/bash a=123 ( a=321; ) echo "$a" #a的值为123而不是321,因为括号将判断为局部变量 初始化数组: arr=(1 2 3 4) echo ${arr[2]} 命令组: {} 文件名扩展 #!/bin/bash if [ ! -w ‘t.txt‘ ]; then touch t.txt fi echo ‘test test‘ >> t.txt cp t.{txt,back} 代码块 #!/bin/bash a=123 { a=321; } echo "a = $a" bash xxx.sh a=321 #a的值被修改 命令组: [] 条件测试 #!/bin/bash a=5 if [ $a -lt 10 ] then echo "a: $a" else echo ‘a>10‘ fi 数组元素 #!/bin/bash arr=(12 22 32) arr[0]=10 echo ${arr[0]} 命令组: <> 重定向 test.sh > filename:重定向test.sh的输出到文件 filename 中。如果 filename 存在的话,那么将会被覆盖。 test.sh &> filename:重定向 test.sh 的 stdout(标准输出)和 stderr(标准错误)到 filename 中。 test.sh >&2:重定向 test.sh 的 stdout 到 stderr 中。 test.sh >> filename:把 test.sh 的输出追加到文件 filename 中。如果filename 不存在的话,将会被创建 命令组: | 分析前面的输出,并将输出作为后面命令的输入 #!/bin/bash tr ‘a-z‘ ‘A-Z‘ exit 0 chmod 755 test26.sh ls -l | ./test26.sh 输出的内容均变为了大写字母 命令组: - 选项,前缀 #!/bin/bash a=5 b=5 if [ "$a" -eq "$b" ] then echo "a is equal to b." fi bash test27.sh a is equal to b. 重定向stdin或stdout 变量定义 注意 变量名和等号之间不能有空格。同时,变量名的命名须遵循如下规则: 首个字符必须为字母(a-z,A-Z)。 中间不能有空格,可以使用下划线(_)。 不能使用标点符号。 不能使用bash里的关键字(可用help命令查看保留关键字)。 除了直接赋值,还可以用语句给变量赋值,如:for file in `ls /etc` 只读变量 #!/bin/bash myUrl="http://www.shiyanlou.com" readonly myUrl myUrl="http://www.shiyanlou.com" 运行脚本报错 特殊变量 局部变量 环境变量 位置参数 从命令行传递到脚本的参数:$0,$1,$2,$3... $0就是脚本文件自身的名字,$1 是第一个参数,$2 是第二个参数,$3 是第三个参数,然后是第四个。$9 之后的位置参数就必须用大括号括起来了,比如,${10},${11},${12}。 $# : 传递到脚本的参数个数 $* : 以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过 9个 $$ : 脚本运行的当前进程 ID号 $! : 后台运行的最后一个进程的进程 ID号 $@ : 与$*相同,但是使用时加引号,并在引号中返回每个参数 $: 显示shell使用的当前选项,与 set命令功能相同 $? : 显示最后命令的退出状态。 0表示没有错误,其他任何值表明有错误。 脚本: #!/bin/bash # 作为用例, 调用这个脚本至少需要10个参数, 比如: # bash test.sh 1 2 3 4 5 6 7 8 9 10 MINPARAMS=10 echo echo "The name of this script is \"$0\"." echo "The name of this script is \"`basename $0`\"." echo if [ -n "$1" ] # 测试变量被引用. then echo "Parameter #1 is $1" # 需要引用才能够转义"#" fi if [ -n "$2" ] then echo "Parameter #2 is $2" fi if [ -n "${10}" ] # 大于$9的参数必须用{}括起来. then echo "Parameter #10 is ${10}" fi echo "-----------------------------------" echo "All the command-line parameters are: "$*"" if [ $# -lt "$MINPARAMS" ] then echo echo "This script needs at least $MINPARAMS command-line arguments!" fi echo exit 0 运行结果: $ bash test30.sh 1 2 10 The name of this script is "test.sh". The name of this script is "test.sh". Parameter #1 is 1 Parameter #2 is 2 ----------------------------------- All the command-line parameters are: 1 2 10 This script needs at least 10 command-line arguments! 算数运算符 原生bash不支持简单的数学运算,但是可以利用其他命令实现,如:awk/expr 注意使用反引号` 表达式与运算符之间要有空格: $a + $b可以, $a+$b不行 条件表达式放在中括号中也要有空格: [ $a == $b ]可以, [$a==$b]不行 乘号* 前面必须要有反斜线\,才能实现乘法运算 脚本: #!/bin/bash a=10 b=20 val=`expr $a + $b` echo "a + b : $val" val=`expr $a - $b` echo "a - b : $val" val=`expr $a \* $b` echo "a * b : $val" val=`expr $b / $a` echo "b / a : $val" val=`expr $b % $a` echo "b % a : $val" if [ $a == $b ] then echo "a == b" fi if [ $a != $b ] then echo "a != b" fi 关系运算符只支持数字,不支持字符串,除非字符串的值是数字 -eq 检测两个数是否相等,相等返回true -ne 检测两个数是否相等,不相等返回true -gt 检测左边的数是否大于右边的,是,返回true -lt 检测左边的数是否小于右边的,是,返回true -ge 检测左边的数是否大于等于右边的,是,返回true -le 检测左边的数是否小于等于右边的,是,返回true 脚本: #!/bin/bash a=10 b=20 if [ $a -eq $b ] then echo "$a -eq $b : a == b" else echo "$a -eq $b: a != b" fi 逻辑运算符 && 逻辑的AND || 逻辑的OR 脚本: #!/bin/bash a=10 b=20 if [[ $a -lt 100 && $b -gt 100 ]] then echo "return true" else echo "return false" fi if [[ $a -lt 100 || $b -gt 100 ]] then echo "return true" else echo "return false" fi 字符串运算符 = 检测两个字符串是否相等,相等返回true != 检测两个字符串是否相等,不相等返回true -z 检测字符串长度是否为0,为0 返回true -n 检测字符串长度是否为0,不为0返回true str 检测字符串是否为空,不为空返回true 脚本: #!/bin/bash a="abc" b="efg" if [ $a = $b ] then echo "$a = $b : a == b" else echo "$a = $b: a != b" fi if [ -n $a ] then echo "-n $a : The string length is not 0" else echo "-n $a : The string length is 0" fi if [ $a ] then echo "$a : The string is not empty" else echo "$a : The string is empty" fi 文件测试运算符 -e 文件存在 -a 文件存在(已弃用) -f 表示这个文件是一个一般文件,不是目录或设备文件 -s 文件大小不为零 -d 表示这是一个目录 -b 表示这是一个块设备(软盘,光驱,等) -c 表示这是一个字符设备(键盘,modem,声卡,等) -p 表示这是一个管道 -h 这是一个符号链接 -L 这是一个符号链接 -S 这是一个socket -t 文件被关联到一个终端设备上,一般被用来检测脚本中的stdin([-t 0])或者stdout([-t 1])是否来自一个终端 -r 文件是否具有可读权限(指的是正在运行这个测试命令的用户是否具有可读权限) -w 文件是否具有可写权限(指的是正在运行这个测试命令的用户是否具有可写权限) -x 文件是否具有可执行权限(指的是正在运行这个测试命令的用户是否具有可执行权限) -g set-group-id(sgid)标记被设置的文件或目录上 -k 设置粘贴位 -O 判断是否是文件的拥有者 -G 文件的group-id 是否与你的相同 -N 从文件上一次被读取到现在为止,文件是否被修改过 f1 -nt f2 文件f1比文件f2新 f1 -ot f2 文件f1比文件f2旧 f1 -ef f2 文件f1和文件f2是相同文件的硬链接 ! 非,反转上面的所有测试结果 脚本: #!/bin/bash file="/home/shiyanlou/test.sh" if [ -r $file ] then echo "The file is readable" else echo "The file is not readable" fi if [ -e $file ] then echo "File exists" else echo "File not exists" fi 流程控制: if-else 语句 if 语法格式: if condition then command1 command2 ... commandN fi if else 语法格式 if condition then command1 command2 ... commandN else command fi if-elif-else 语法格式 if condition1 then command1 elif condition2 then command2 else command3 fi 脚本: 判断两个变量是否相等 a=10 b=20 if [ $a == $b ] then echo "a == b" elif [ $a -gt $b ] then echo "a > b" elif [ $a -lt $b ] then echo "a < b" else echo "Ineligible" fi 输出: a<b if else 语句经常与test 结合使用 脚本: num1=$[2*3] num2=$[1+5] if test $[num1] -eq $[num2] then echo "Two numbers are equal!" else echo "The two numbers are not equal!" fi 输出: Two numbers are equal! for循环: for var in item1 item2 .. itemN do command1 command2 ... commandN done 脚本: for loop in 1 2 3 4 5 do echo "The value is: $loop" done 输出: The value is: 1 The value is: 2 The value is: 3 The value is: 4 The value is: 5 脚本: for str in This is a string do echo $str done 输出: This is a string while 语句:不断执行一系列命令,也用于输入文件中读取数据;命令通产为测试条件 while condition do command done 脚本: #!/bin/bash int=1 while(( $int<=5 )) do echo $int let "int++" done 使用了 Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量 输出: 1 2 3 4 5 while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量MAN,按结束循环。 echo ‘press <CTRL-D> exit‘ echo -n ‘Who do you think is the most handsome: ‘ while read MAN do echo "Yes!$MAN is really handsome" done 无限循环: while : do command done 或 while true do command done 或 for(( ; ; )) until循环 循环执行一系列命令直至条件为真时停止,一般while优于until循环,测试发生在循环末尾,至少执行一次 语法: until condition do command done case语句: case 值 in 模式1) command1 command2 ... commandN ;; (用于结束case语句) 模式2) command1 command2 ... commandN ;; *) command1 command2 ... commandN ;; esac 取值后面必须为单词in,每一模式必须以右括号结束,取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。 取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。 echo ‘Enter a number between 1 and 4:‘ echo ‘The number you entered is:‘ read aNum case $aNum in 1) echo ‘You have chosen 1‘ ;; 2) echo ‘You have chosen 2‘ ;; 3) echo ‘You have chosen 3‘ ;; 4) echo ‘You have chosen 4‘ ;; *) echo ‘You did not enter a number between 1 and 4‘ ;; esac 跳出循环 break或continue break跳出所有循环 #!/bin/bash while : do echo -n "Enter a number between 1 and 5:" read aNum case $aNum in 1|2|3|4|5) echo "The number you entered is $aNum!" ;; *) echo "The number you entered is not between 1 and 5! game over" break ;; esac done continue跳出循环 #!/bin/bash while : do echo -n "Enter a number between 1 and 5" read aNum case $aNum in 1|2|3|4|5) echo "The number you entered is $aNum" ;; *) echo "The number you entered is not between 1 and 5!" continue echo "game over" ;; esac done 当输入大于5的数字时,该例中的循环不会结束,语句 echo "Game is over!" 永远不会被执行。 求 100 以内所有偶数之和 #!/bin/bash n=100 awk -v N=$n ‘BEGIN { sum = 0; for (i = 1; i <= N; ++i){ if (!(i % 2)) sum += i } print sum }‘ #!/bin/bah sum=0 for i in `seq 2 2 100` do let "sum+=i" done echo "sum=$sum" 函数: [ function ] funcname [()] { action [return int;] } 可以带function fun()定义,也可以直接fun()定义,不带任何参数 参数返回,可以显示:return返回, 如果不加,将以最后一条命令运行结果,作为返回值,return后跟数值n(0-255) 例子: #!/bin/bash demoFun(){ echo "This is my first shell function!" } echo "---Execution---" demoFun echo "---Finished---" #!/bin/bash funWithReture(){ echo "This function will add the two numbers of the input..." echo "Enter the first number: " read aNum echo "Enter the second number: " read anotherNum echo "The two numbers are $aNum and $anotherNum !" return $(($aNum+$anotherNum)) } funWithReturn echo "The sum of the two numbers entered is $? !" 函数返回值在调用该函数后通过$? 来获得 所有函数在使用前必须定义 函数参数: 在函数体内部通过$n的形式来获取参数的值,如$1表示第一个参数,$2 表示第二个参数,${10}表示第10个参数 #!/bin/bash funWithParam(){ echo "The 1 parameter is $1 !" echo "The 2 parameter is $2 !" echo "The 3 parameter is $3 !" echo "The 10 parameter is ${10} !" echo "The total number of parameters is $# !" echo "Outputs all parameters as a string $* !" } funWithParam 1 2 3 4 5 6 7 8 9 10 11 注: $10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。 猜数字游戏: 首先让系统随机生成一个数字,给这个数字一个范围,让用户猜数字,对输入作出判断,并且给出提示。 请用while语句实现。 #!/bin/bash rand=$(($RANDOM%100+1)) while : do read aNum echo "$rand" if test $aNum -eq $rand then echo "right" else if [ $aNum -gt $rand] then echo "your entered is to big to $rand" else echo "your entered is to small to $rand" fi fi done
这是本人学习笔记,供大家参考学习,如内容有误欢迎大家批评指正,共同进步!
转载随笔/文章务必保留出处和署名,谢谢!!
该内容来自实验楼免费课程,不做任何商业用途, 如有侵权请及时联系本人删除!!!
原文:https://www.cnblogs.com/W-it-H-ou-T/p/11001195.html