shell学习三十天----break,continue,shift,getopts

break和continue

这两个命令分别用来退出循环,或跳到循环体的其他地方.

使用while与break,等待用户登录

bash代码:

printf “Enter username: ”

read user

while true

do

if who | grep “$user” >/dev/null

then

break;

fi

sleep 30

done

等待特定用户,每30秒确认一次

true命令什么事也不必做,只是成功的退出.这用于编写无限循环,即会永久的执行循环.在编写无限循环时,必须放置一个退出条件在循环体内,正如这里所作的.另有一个false命令和它有点相似,只是很少的用到,也不做人和事,仅表示不成功的状态.false命令常见于无线的until false..循环中.

continue命令则用于提早的开始下一段重复动作,也就是在到大循环体的底部之前.

break与continue命令都可以接受可选的数值参数,可分别用来之处要中断(break)或继续多少个被包含的循环(如果循环技术需要的是一个在运行时可被计算的表达式时,可以使用$((...)) ).案例:

while condition1 //外循环

do...

while condition2 //内循环

do..

break; 外循环的终端

done

done

break与continue特别具备终端或继续多个循环层的能力.从而以简洁的形式弥补了shell语言里缺乏goto关键字的不足.

使用continue的案例:

#!/bin/bash

limit=19

echo "printing Number 1 throught 20"

a=0

while [ $a -le "$limit" ]

do

let a++

#let a+=1

#a=$(($a+1))

if [ "$a" -eq 3 ] || [ "$a" -eq 11 ]

then

continue

fi

echo -n "$a "

done

输出结果:

printing Number 1 throught 20

1 2 4 5 6 7 8 9 10 12 13 14 15 16 17 18 19 20

由此可见continue的作用是结束本次循环,执行下一次循环

使用break的案例:

#!/bin/bash

limit=19

echo "printing Number 1 throught 20"

a=0

while [ $a -le "$limit" ]

do

let a++

#let a+=1

#a=$(($a+1))

if [ "$a" -eq 3 ] || [ "$a" -eq 11 ]

then

break

fi

echo -n "$a "

done

输出结果:

printing Number 1 throught 20

1 2

由此可见,break的作用是退出当前循环.

shift

我们知道,对于位置变量或命令行参数,其个数必须是确定的,或者当 Shell 程序不知道其个数时,可以把所有参数一起赋值给变量$*。若用户要求 Shell 在不知道位置变量个数的情况下,还能逐个的把参数一一处理,也就是在 $1 后为 $2,在 $2 后面为 $3 等。在 shift 命令执行前变量 $1 的值在 shift 命令执行后就不可用了。

案例:

#!/bin/bash

until [ $# -eq 0 ]

do

echo "第一个参数为: $1 参数个数为: $#"

shift

done

执行命令:./shift.sh 1 2 3 4

输出为:

第一个参数为: 1 参数个数为: 4

第一个参数为: 2 参数个数为: 3

第一个参数为: 3 参数个数为: 2

第一个参数为: 4 参数个数为: 1

分析:从上可知 shift 命令每执行一次,变量的个数($#)减一,而变量值提前一位.

shift可以用来向左移动位置参数。

Shell的名字 $0

第一个参数 $1

第二个参数 $2

第n个参数 $n

所有参数 [email protected] 或 $*

参数个数 $#

案例:

bash代码:

until [ -z "$1" ]  # Until all parameters used up

do

echo "[email protected] "

shift

done

命令: ./shift1.sh 1 2 3 4 5 6 7 8 9 10

输出:

1 2 3 4 5 6 7 8 9 10

2 3 4 5 6 7 8 9 10

3 4 5 6 7 8 9 10

4 5 6 7 8 9 10

5 6 7 8 9 10

6 7 8 9 10

7 8 9 10

8 9 10

9 10

10

getopts命令

语法:

getopts option_spec variable [ arguments...]

线来看一个简单的例子:

#!/bin/bash

echo $*

while getopts ":a:bc:" opt

do

case $opt in

a)

echo $OPTARG

echo $OPTIND

;;

b)

echo "b $OPTIND"

;;

c)

echo "c $OPTIND"

;;

?)

echo "error"

exit 1

esac

done

echo $OPTIND

shift $(( $OPTIND-1 ))

echo $0

echo $*

如果执行命令:./getopts.sh -a 11 -b -c 6

结果为:

-a 11 -b -c 6

11

3

b 4

c 6

6

./getopts.sh

看分析:

getopts后面的字符串就是可以使用的选项列表,每个字母代表一个选项,后面带:的意味着选项除了定义本身之外,还会带上一个参数作为选项的值,比如a:在实际的使用中就会对应-a 11,选项的值就是11;getopts字符串中没有跟随:的是开关型选项,不需要再指定值,相当于true/false,只要带了这个参数就是true。如果命令行中包含了没有在getopts列表中的选项,会有警告信息,如果在整个getopts字符串前面也加上个:,就能消除警告信息了。

使用getopts识别出各个选项之后,就可以配合case来进行相应的操作了。

optarg这个变变,getopts修改了这个变量。

这里变量$optarg存储相应选项的参数,而$optind总是存储原始$*中下一个要处理的元素(不是参数,而是选项,此处值得的是a,b,c这三个选线,而不是那些数字,当然数字也是会占有位置的)位置。

while getopts ":a:bc:" opt  #第一个冒号表示忽略错误;字符后面的冒号表示该选项必须有自己的参数.

使用getopts处理参数虽然是方便,但仍然有两个小小的局限:

1.选项参数的格式必须是-d val,而不能是中间没有空格的-dval。

2.所有选项参数必须写在其它参数的前面,因为getopts是从命令行前面开始处理,遇到非-开头的参数,或者选项参数结束标记--就中止了,如果中间遇到非选项的命令行参数,后面的选项参数就都取不到了。

3.不支持长选项, 也就是--debug之类的选项

案例:

#!/bin/bash

while getopts "ab:cd:" opt

do

case $opt in

a)

echo $OPTIND

;;

b)

echo $OPTIND

echo $OPTARG

;;

c)

echo $OPTIND

;;

d)

echo $OPTIND

echo $OPTARG

esac

done

shift $(($OPTIND-1))

使用命令:./getopts1.sh -a -b foo -c -d haha

得到结果:

2

4

foo

5

7

haha

最后使用shift $(($OPTIND-1))的作用是:通过shift $(($OPTIND - 1))的处理,$*中就只保留了除去选项内容的参数,可以在其后进行正常的shell编程处理了。 貌似不用也可以.

如果出现这种情况:

getopts “:ab:c”第一个冒号代表的含义是:第一个冒号表示忽略错误,即当出现没有的选项是会忽略;字符后面的冒号表示该选项必须有自己的参数,

时间: 2025-01-06 19:07:42

shell学习三十天----break,continue,shift,getopts的相关文章

shell学习三十四天----printf详解

printf 先来看一个简单的例子:使用命令printf "hello,world\n", 输出:hello,world 再使用echo "hello,world\n",输出为:hello,world\n 案例二:使用命令printf "%s\n" hello,world 输出结果为:hello,world printf命令的完整语法有两个部分: printg format-string [arguments] 第一部分为描述格式规格的字符串,他

shell学习三十五天----波浪号展开与通配符

波浪号展开与通配符 shell中两种与文件名相关的展开.第一种是波浪号展开,第二种是通配符展开式. 波浪号展开 如果命令行字符串的第一个字符为波浪号(~),或者变量指定(例如PATH或CDPATH变量)的值里任何未被引号括起来的冒号之后的第一个字符为波浪号(~)时,shell变回执行波浪号展开. 波浪号展开的目的,将用户根目录的符号型表示方式,改为实际的目录路径.可以采用直接或间接的方式指定执行此程序的用户,如未明白指定,则为当前的用户: 命令:vi ~/.profile       与vi $

(转载)深度学习三十年创新路

转载自:http://36kr.com/p/533832.html 编者注:深度学习火了,从任何意义上,大家谈论它的热衷程度,都超乎想象.但是,似乎很少有人提出不同的声音,说深度学习的火热,有可能是过度的繁荣,乃至不理性的盲从.而这次,有不同的想法出现了. 本篇文章来自依图科技 CEO Leo的投稿,依图科技是一家专注研究CV(Computer Vison,计算机视觉)的以技术驱动的创业公司,Leo自己也在这一领域有深入研究,因此这次写下这篇文章,希望回顾一下深度学习三十年的创新之路. 近期Na

深度学习三十年创新路

深度学习三十年创新路 编者注:深度学习火了,从任何意义上,大家谈论它的热衷程度,都超乎想象.但是,似乎很少有人提出不同的声音,说深度学习的火热,有可能是过度的繁荣,乃至不理性的盲从.而这次,有不同的想法出现了. 本篇文章来自依图科技 CEO Leo的投稿,依图科技是一家专注研究CV(Computer Vison,计算机视觉)的以技术驱动的创业公司,Leo自己也在这一领域有深入研究,因此这次写下这篇文章,希望回顾一下深度学习三十年的创新之路. 近期Nature杂志刊登了Lecun.Bengio.H

python 学习三十五天(socket的更多方法)

1.黏包 2.socket的更多方法介绍 3.验证客户端连接合法性 4.socketserver模块 一.黏包 1.现象: res=subprocess.Popen(cmd.decode('utf-8'), shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) 的结果的编码是以当前所在的系统为准的,如果是windows,那么res.stdout.read()读出的就是GBK编码的,在接收端需要用GBK解码 且只能从管道里读一次结果

鸟书shell学习(三)shell脚本程序设计要点总结

一 注意事项 1.脚本的开头一行为 : #!/bin/bash 声明这个脚本需要的shell的名称 2.程序中出了"#!"之外的其他以#开头的都是注释内容 3.为了方面的使用系统命令,可以在程序的开始部分设置主要环境变量例如PATH 4.脚本程序的运行方法: sh example.sh 或者类似 bash example.sh chmod +x example.sh ; ./example.sh    ################################ 这两种执行方式都是

shell学习五十六天----延迟进程调度

延迟进程调度 前言:大部分时候,我们都希望进程快点開始,开点结束,别卡.而shell的运行,也是在前一个命令后,立即接着运行下一个命令.命令完毕的速度是与资源的限制有关,且不在shell的权限下. 在交谈模式中使用下,有时不必等到命令完毕才干运行还有一个.这是shell提供的一个简单方式:全部的命令仅仅要在最后加上&字符,都可起始于后台运行,无需等待.仅仅有在少数情况下,必须等待后台进程完毕. 稍稍有四种情况须要延时进程事实上,知道未来的某个事件才运行. 第一种 sleep sleep命令经常使

shell学习三十一天----函数问题

函数 案例一: #!/bin/bash hello () { echo "hahahah" } hello 执行函数,结果为:hahaha 案例二: #!/bin/bash funWithReturn() { echo "the function is to get the sum of two number" read -p "input first number" num1 read -p "input second number&

shell学习四十九天----进程建立

进程 前言:进程指的是运行中程序的一个实例.新进程由fork()与execve()等系统调用所起始,然后运行,知道他们下达exit()系统调用为止. linux系统都支持多进程.尽管计算机看起来像是一次做了非常多事,但除非是他拥有多个CPU,否则一次做了好多事仅仅是个错觉.其实,每一个进程仅容许在一个极短的期间运行,我们称为时间片段,之后进程会先临时搁置,让其它等待中进程运行.时间片段极短,通常仅仅有几微妙,所以人们非常少感觉到进程将控制权交回内核,再交给还有一个进程的这样的文本切换.进程本身不