shell编程 (2) —— 基础

网友投稿 249 2022-08-31

shell编程 (2) —— 基础

shell 语法

for循环

#!/bin/bashfor language in c c++ java python shell_script; do echo "my ${language} #变量左右加上{}done

变量

变量的二次赋值

#!/bin/bashname="Elena" # = 左右不能有空格echo "hello, my name is ${name}"name="Demon" echo "hello, my name is ${name}"

删除变量

str="Hello World!"unset str #删除变量 本程序没有任何的输出echo ${str}

只读变量 【 不能更改,不能删除】

str="Hello World!"readonly strstr="haha" # /usercode/file.sh: line 4: str: readonly variableunset str # /usercode/file.sh: line 4: unset: str: cannot unset: readonly variable

引号

单双引号区别

单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的; 单引号字串中不能出现单引号(对单引号使用转义符后也不行)。

双引号里可以有变量 双引号里可以出现转义字符

反引号的使用

反引号”`”可以将指令括起来,然后交给shell

for file in `ls `; dofile ${file}

字符串部分

连接

#!/bin/bashname="linux"str="I love ${name}"echo $strstr="I love "${name}echo $str

字符串的长度

#!/bin/bashstr='Hello World!'echo ${#str} #12

或者使用expr工具 (evalution expression)

#!/bin/bashstr="Hello World!"echo `expr length "${str}"`

字符串的截取

#!/bin/bashstr='Hello World!'echo ${str:6:6} #截取第7个字符后的长度是6的字符串 World!

查找字符

expr 可以用于模式匹配。它有一种用法:index string char 用于求解char在string中的位置,记住是从1开始的,如果不存在相应的字符,那么我们返回0.

#!/bin/bashstr="I love linux"echo `expr index "${str}"

数组

#!/bin/basharray=("C" "C++" "java" "python" "shell script")echo ${array[@]} #输出所有的元素echo ${#array[@]} #输出数组的长度

注释

单行注释是”#” shell中没有像C那样方便的多行注释,只能一行一行的添加#,不过我们也可以将需要多行注释的地方写成一个函数,想要使用的时候加上就行。

3个fd

从shell中运行一个进程,默认会有3个文件描述符存在(0、1、2), 0与进程的标准输入相关联, 1与进程的标准输出相关联,2与进程的标准错误输出相关联,一个进程当前有哪些打开 的文件描述符可以通过/proc/进程ID/fd目录查看.

shell处理参数

参数处理

说明

$#

传递到脚本的参数个数

$*

以一个单字符串显示所有向脚本传递的参数

$$

脚本运行的当前进程ID号

$!

后台运行的最后一个进程的ID号

$@

与$*相同,但是使用时加引号,并在引号中返回每个参数

$-

显示Shell使用的当前选项,与set命令功能相同

$?

显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误

数值计算

利用工具expr可以实现数值计算。比如:

val=`expr 2 \* 4`echo "calculate 2 * 4: "${val}

关系运算符

运算符

说明

举例

-eq

检测两个数是否相等,相等返回 true。

[ $a -eq $b ] 返回 false。

-ne

检测两个数是否相等,不相等返回 true。

[ $a -ne $b ] 返回 true。

-gt

检测左边的数是否大于右边的,如果是,则返回 true。

[ $a -gt $b ] 返回 false。

-lt

检测左边的数是否小于右边的,如果是,则返回 true。

[ $a -lt $b ] 返回 true。

-ge

检测左边的数是否大于等于右边的,如果是,则返回 true。

[ $a -ge $b ] 返回 false。

-le

检测左边的数是否小于等于右边的,如果是,则返回 true。

[ $a -le $b ] 返回 true。

布尔运算符

operator

meaning

!


-o


-a


str="I love linux"length=`expr length "${str}"`if [ ${length} -gt 20 -o ${length} -lt 0 ]; then echo "this is bad string"elif [ ${length} -lt 20 -a ${length} -gt 10 ]; thenecho "the length > 10 and < 20"fi

逻辑运算符

operator

meaning

||


&&


str="I love linux"length=`expr length "${str}"`if [[ ${length} -gt 20 || ${length} -lt 0 ]]; then echo "this is bad string"elif [[ ${length} -lt 20 && ${length} -gt 10 ]]; thenecho "the length > 10 and < 20"

逻辑与、或和布尔与、或在形式上的差别是逻辑的if多了一对[]

字符串运算

#!/bin/bashs1="jordan"s2="james"if [ $s1 = $s2 ]; then #字符串相等echo "s1 = s2"fiif [ $s1 != $s2 ]; then #字符串不相等echo "s1 != s2"fiif [ -n $s1 ]; then #字符串非空echo "the length of s1 is not zero"fi if [ -z $s1 ]; thenecho "the length of s1 is zero" #字符串为空fi if [ $s2 ]; thenecho "the s2 is not empty" #字符串非空fi# output:# s1 != s2# the length of s1 is not zero# the s2 is not empty

文件测试运算符

操作符

说明

举例

-b file

检测文件是否是块设备文件,如果是,则返回 true。

[ -b $file ] 返回 false。

-c file

检测文件是否是字符设备文件,如果是,则返回 true。

[ -c $file ] 返回 false。

-d file

检测文件是否是目录,如果是,则返回 true。

[ -d $file ] 返回 false。

-f file

检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。

[ -f $file ] 返回 true。

-g file

检测文件是否设置了 SGID 位,如果是,则返回 true。

[ -g $file ] 返回 false。

-k file

检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。

[ -k $file ] 返回 false。

-p file

检测文件是否是有名管道,如果是,则返回 true。

[ -p $file ] 返回 false。

-u file

检测文件是否设置了 SUID 位,如果是,则返回 true。

[ -u $file ] 返回 false。

-r file

检测文件是否可读,如果是,则返回 true。

[ -r $file ] 返回 true。

-w file

检测文件是否可写,如果是,则返回 true。

[ -w $file ] 返回 true。

-x file

检测文件是否可执行,如果是,则返回 true。

[ -x $file ] 返回 true。

-s file

检测文件是否为空(文件大小是否大于0),不为空返回 true。

[ -s $file ] 返回 true。

-e file

检测文件(包括目录)是否存在,如果是,则返回 true。

[ -e $file ] 返回 true。

#!/bin/bashcd /tmppwdtouch myfileif [ -e $myfile ]; then #检测存在 echo "myfile exit" if [ -b $myfile ]; then #块设备 echo "myfile is block file" elif [ -c $myfile ]; then #字符设备 echo "myfile is character file" elif [ -f $myfile ]; then #普通文件 echo "myfile is normal file" elif [ -d $myfile ]; then #路径 echo "myfile is a dir" fi if [ -r $myfile ]; then #读,写,可执行属性 echo "myfile can be read" fi if [ -w $myfile ]; then echo "myfile can be wrote" fi if [ -x $myfile ]; then echo "myfile can be excuted" fifi

输入和输出

read 从标准输入读取一行,赋予相应的变量 echo -e开启转义功能

echo:

echo -e "this is a story about hero.\n" #没有-e, 就没有多一行echo "end"echo -e "this is a story about hero." #正常换行echo "end"echo -e "this is a story about hero.\c" #不换行echo "end"

printf: printf 和C里面的printf()相似。printf format-string [arguments…]

#!/bin/bashprintf "Hello World\n"printf "%s %d\n" Jordan 23name="Jordan"age=23printf "%s %d\n" $name $age

关于分支

在shell编程(1)的基础上增加一些补充。 bash里的分支不能是空的。 case分支:

case value inmod1) command1 command2 ... commandN ;;mod2) command1 command2 ...

比如:

echo "enter a number: "read numbercase $number in1) echo "you enter 1." ;;2) echo "you enter 2." ;;esac

函数

下面[]中的function 可有可无。

[ function ] funname [()]{ action; [return

参数

在函数的内部,我们可以使用​​$n​​​来获取第n个参数的值。在函数外部,函数的返回值则可以通过​​$?​​来获得.

func(){ echo "first arg is "$1; echo "second arg is "$2; return $(($1 + $2));}func 3 4echo "the sum of two args is "$?

output:

first arg is 3second arg is 4the sum of two args is 7

其他参数

参数

说明

$#

传递到脚本的参数个数

$*

以一个单字符串显示所有向脚本传递的参数

$$

脚本运行的当前进程ID号

$!

后台运行的最后一个进程的ID号

$@

与$*相同,但是使用时加引号,并在引号中返回每个参数。

$-

显示Shell使用的当前选项,与set命令功能相同。

$?

显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

输入输出重定向

文件描述符 0对应标准输入(STDIN),1 对应标准输出(STDOUT),2对应标准错误输出(STDERR)。

command > file #stdout 重定向到 filecommand < file #stdin 重定向到 filecommand > file file1>&file2 #将输出文件file2和file1合并后重定向到file

例子:

#func.sh:func(){ echo "first arg is "$1; echo "second arg is "$2; return $(($1 + $2));}func 3 4echo "the sum of two args is "$?func();#正常执行:./func.shfirst arg is 3second arg is 4the sum of two args is 7./func.sh: line 8: syntax error near unexpected token `;'./func.sh: line 8: `func();'

特殊的重定向:

command << delimiter

将两个 delimiter 之间的内容作为输入传递给 command。

练习

二分查找

10 20 30 40 50 60 70 80 90 100) bsearch(){ l=0 r=9 ans=-1 while (( $l <= $r )); do mid=`expr $(( $l + $r )) / 2` if [[ ${array[$mid]} -lt $1 ]]; then l=`expr $mid + 1` elif [[ ${array[$mid]} -eq $1 ]]; then ans=$mid break else r=`expr $mid - 1` fi done #return $ans } while true; do echo "enter a key number to find, -1 will kill program." read key if [ $key -eq -1 ]; then break fi bsearch key if [ $ans -eq -1 ]; then echo "not found." else echo "the index of key is "$ans fi done

enter a key number to find, -1 will kill program.23not found.enter a key number to find, -1 will kill program.30the index of key is 2enter a key number to find, -1 will kill program.10the index of key is 0enter a key number to find, -1 will kill program.100the index of key is 9enter a key number to find, -1 will kill program.2244not found.enter a key number to find, -1 will kill program.50the index of key is 4enter a key number to find, -1 will kill program.-1

快速排序

#!/bin/basharray=(1 5 3 9 4 8 6 2 7 10)partion(){ i=$1; j=$2 tmp=${array[$1]} while [[ $i -lt $j ]]; do while [[ $i -lt $j && ${array[$j]} -ge $tmp ]]; do j=`expr $j - 1` done array[$i]=${array[$j]} while [[ $i -lt $j && ${array[$i]} -le $tmp ]]; do i=`expr $tmp + 1` done array[$j]=${array[$i]} done array[$i]=$tmp return $i}quick_sort(){ if [ $1 -lt $2 ]; then partion $1 $2 mid=$? quick_sort $1 $mid quick_sort `expr $mid + 1` $2 fi}quick_sort 0 9echo "${array[@]}"

codingame之飞行着陆

飞行着陆 ​​​ 大意:每一次削低最高的山峰,避免飞行器撞上山峰。 分析:每一次找出最高的山峰即可。

while true; do max_h=-1 ans=0 for (( i=0; i<8; i++ )); do # mountainH: represents the height of one mountain. read mountainH if [ ${max_h} -lt ${mountainH} ]; then ans=$i; max_h=${mountainH} fi done # Write an action using echo # To debug: echo "Debug messages..." >&2 echo ${ans} # The index of the mountain to fire on.done

codingame之reach the light of power

reach the light of power ​​​ 大意:游戏人物从初始位置需要走到power位置,每一次可以转身,上、下、左、右、斜一共8个方向的转向选择,在给定转身次数的情况下输出转身方向。 分析:向量判断,就近原则。

# Auto-generated code below aims at helping you parse# the standard input according to the problem statement.# ---# Hint: You can use the debug stream to print initialTX and initialTY, if Thor seems not follow your orders.# lightX: the X position of the light of power# lightY: the Y position of the light of power# initialTX: Thor's starting X position# initialTY: Thor's starting Y positionread lightX lightY initialTX initialTY# game loopwhile true; do # remainingTurns: The remaining amount of turns Thor can move. Do not remove this line. read remainingTurns # Write an action using echo # To debug: echo "Debug messages..." >&2 # A single line providing the move to be made: N NE E SE S SW W or NW dx=`expr $lightX - $initialTX` dy=`expr $lightY - $initialTY` if [ $dx -gt 0 -a $dy -gt 0 ]; then string="SE" initialTX=`expr $initialTX + 1` initialTY=`expr $initialTY + 1` elif [ $dx -gt 0 -a $dy -eq 0 ]; then string="E" initialTX=`expr $initialTX + 1` elif [ $dx -gt 0 -a $dy -lt 0 ]; then string="NE" initialTX=`expr $initialTX + 1` initialTY=`expr $initialTY - 1` elif [ $dx -eq 0 -a $dy -lt 0 ]; then string="N" initialTY=`expr $initialTY - 1` elif [ $dx -lt 0 -a $dy -lt 0 ]; then string="NW" initialTX=`expr $initialTX - 1` initialTY=`expr $initialTY - 1` elif [ $dx -lt 0 -a $dy -eq 0 ]; then string="W" initialTX=`expr $initialTX + 1` elif [ $dx -lt 0 -a $dy -gt 0 ]; then string="SW" initialTX=`expr $initialTX - 1` initialTY=`expr $initialTY + 1` elif [ $dx -eq 0 -a $dy -gt 0 ]; then string="S" initialTY=`expr $initialTY + 1` else break fi echo $stringdone

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:简单的多线程数据传输
下一篇:公关界的007:重庆百货、肯德基...9个数字化服务品牌,攒了个“爆”局!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~