当前位置: 首页 > news >正文

南京市高淳区城乡建设局网站asp.net 微网站开发

南京市高淳区城乡建设局网站,asp.net 微网站开发,长春建站优化加徽信xiala5,科技网站 网站建设文章目录 使用getopt处理参数1. shift 命令1.1 删除一个参数1.2 删除多个参数1.3 多次执行 shift 参数1.4 参数解析示例1.5 优化处理1.6 问题处理 2. getopt 命令2.1 常用参数及示例2.2 脚本参数优化示例2.3 参数校验 3. 示例展示4. eval 命令4.1 示例示例 1示例 2示例 3示例 4…

文章目录

  • 使用getopt处理参数
    • 1. shift 命令
      • 1.1 删除一个参数
      • 1.2 删除多个参数
      • 1.3 多次执行 shift 参数
      • 1.4 参数解析示例
      • 1.5 优化处理
      • 1.6 问题处理
    • 2. getopt 命令
      • 2.1 常用参数及示例
      • 2.2 脚本参数优化示例
      • 2.3 参数校验
    • 3. 示例展示
    • 4. eval 命令
      • 4.1 示例
        • 示例 1
        • 示例 2
        • 示例 3
        • 示例 4
        • 示例 5

使用getopt处理参数

getopt是用来解析,整理传入shell的命令行参数的命令

参考地址:B站传送门

1. shift 命令

shift 的作用就是从头部删除参数,它可以在后面各跟一个数字参数表示删除几个参数

示例:

shift 2 表示删除两个参数

常见参数使用,可以使用 $@ 输入所有参数

[root@105 dongxx]# cat a.sh 
#!/bin/bash# 输入所有参数
echo $@[root@105 dongxx]# sh a.sh a b c
a b c

在这里插入图片描述

1.1 删除一个参数

使用 shift 命令之后会发现第一个参数 a 没了

[root@105 dongxx]# cat a.sh 
#!/bin/bashshift# 输入所有参数
echo $@
[root@105 dongxx]# sh a.sh a b c
b c

在这里插入图片描述

1.2 删除多个参数

使用 shift 2 删除两个参数

[root@105 dongxx]# cat a.sh 
#!/bin/bashshift 2# 输入所有参数
echo $@
[root@105 dongxx]# sh a.sh a b c d
c d

在这里插入图片描述

1.3 多次执行 shift 参数

shift 参数还可以多次执行,可以多次执行删除多个参数

[root@105 dongxx]# cat a.sh 
#!/bin/bashshift 2
shift# 输入所有参数
echo $@
[root@105 dongxx]# sh a.sh a b c d e
d e

在这里插入图片描述

1.4 参数解析示例

需求:处理参数 -a -name zhangsan -age 18,需要分开输出为 -a -name zhangsan -age 18

[root@105 dongxx]# cat a.sh 
#!/bin/bash
# 参数:-a -name zhangsan -age 18# -a 为第一个参数,可以直接使用 $1
echo $1# 输出 $1 之后,使用 shift 删除第一个参数,那么后面的参数就是从 $1 开始了,所以这里的 $1 和 $2 就是 -name 和 zhangsan
shift
echo $1 $2# 因为 -name 选项和它的参数 zhangsan 占了两个位置,那么就需要 shift 两次了,同理,这里的 $1 就是 -age 选项 $2 就是 18 了
shift 2
echo $1 $2
[root@105 dongxx]# sh a.sh -a -name zhangsan -age 18
-a
-name zhangsan
-age 18

在这里插入图片描述

1.5 优化处理

上述案例中没有考虑参数顺序问题,如果参数顺序有不一样输出结果也就乱了,所以在脚本中不仅要能挨个拿到选项和参数,还要根据选项是有参还是无参来控制 shift 的数量,而且也并不是每个选项参数一定要用,也就是说选项参数数量是不固定的。这样我们可以使用循环来处理。

示例:

[root@105 dongxx]# cat a.sh 
#!/bin/bash
# 参数:-a -name zhangsan -age 18while true; docase "$1" in-a)echo "-a 选项"shift;;-name)echo "-name 选项,参数为 $2"shift 2;;-age)echo "-age 选项,参数为 $2"shift 2;;*)echo "非法参数"exit 1esac
done
[root@105 dongxx]# sh a.sh -a -name zhangsan -age 18
-a 选项
-name 选项,参数为 zhangsan
-age 选项,参数为 18
非法参数

在这里插入图片描述

上述脚本中有个问题,在没有参数时会提示非法参数,且参数为-a -name zhangsan -age 18时,仍提示非法参数

[root@105 dongxx]# sh a.sh 
非法参数

问题解析:

#!/bin/bash
# 参数:-a -name zhangsan -age 18while true; docase "$1" in-a)echo "-a 选项"shift;;-name)echo "-name 选项,参数为 $2"shift 2;;-age)echo "-age 选项,参数为 $2"shift 2;;*)echo "非法参数"exit 1esac
done# 当前脚本在匹配完成会后删除了所有参数,最后 $1 匹配为空会走到最后的 * 匹配,所以就会输出“非法参数”

问题处理:

#!/bin/bash
# 参数:-a -name zhangsan -age 18# 这里我们可以使用 set 命令来处理,set 命令可以用来指定一个结束标记
set -- "$@" --
# 参数说明:
# set -- 为删除所有参数,在 -- 后面可以设置自定义参数,最后在添加一个 -- 作为结束标记
# 输出查看
echo "\$@: "$@while true; docase "$1" in-a)echo "-a 选项"shift;;-name)echo "-name 选项,参数为 $2"shift 2;;-age)echo "-age 选项,参数为 $2"shift 2;;--)break;;*)echo "非法参数"exit 1esac
done

测试

[root@105 dongxx]# cat a.sh 
#!/bin/bash
# 参数:-a -name zhangsan -age 18# 这里我们可以使用 set 命令来处理,set 命令可以用来指定一个结束标记
set -- "$@" --
# 参数说明:
# set -- 为删除所有参数,在 -- 后面可以设置自定义参数,最后在添加一个 -- 作为结束标记
# 输出查看
echo "\$@: "$@while true; docase "$1" in-a)echo "-a 选项"shift;;-name)echo "-name 选项,参数为 $2"shift 2;;-age)echo "-age 选项,参数为 $2"shift 2;;--)break;;*)echo "非法参数"exit 1esac
done
[root@105 dongxx]# sh a.sh 
$@: --
[root@105 dongxx]# sh a.sh -a -name zhangsan -age 18
$@: -a -name zhangsan -age 18 --
-a 选项
-name 选项,参数为 zhangsan
-age 选项,参数为 18

在这里插入图片描述

1.6 问题处理

上述测试脚本参数都是约定好的,但是在实际使用过程中可能会出现没有安装约定的方式传参的问题

示例:-a aaa -name zhangsan -age 18,那这时候参数的顺序位置就会有问题。这时我们就可以使用 getopt 来处理了

2. getopt 命令

2.1 常用参数及示例

常用命令参数

参数说明
-o指定解析段格式选项
-l指定要解析的长格式选项
分割真正需要解析的参数

示例:

[root@105 dongxx]# getopt -o a -l name:,age: -- -a --name zhangsan --age 18-a --name 'zhangsan' --age '18' --# 参数说明:-o 后跟上短格式选项-l 后跟上长格式选择,对于有参数的选项需要再参数后加个冒号,多个长格式选项用逗号隔开-- 后跟上真正需要解析的参数,而且 getopt 要求长格式选项需要使用 -- ,所以需要在选项前加上 --解析成功后会在参数最后默认加上 -- 的结束标记

测试给段格式选项 -a 增加参数 aaa,结果是没有参数输出,因为 getopt 知道 -a 选项是无参选项,所以它将跟在 a 后面的参数移动到了结束标记之后,在之前的脚步中是需要 -- 则跳出循环,所以结束标记之后的参数是不会被处理的

[root@105 dongxx]# getopt -o a -l name:,age: -- -a aaa --name zhangsan --age 18-a --name 'zhangsan' --age '18' -- 'aaa'

在这里插入图片描述

2.2 脚本参数优化示例

使用 getopt 处理一下就能解决参数位置错误导致的参数解析错乱的问题

[root@105 dongxx]# cat a.sh 
#!/bin/bash
# 参数:-a -name zhangsan -age 18# 使用 $(getopt -o a -l name:,age: -- "$@") 获取 getopt 处理后的参数信息,在使用 set -- 把这个结果设置后脚本的参数,由于 getopt 本身就有 -- 的结束标记,所以下面的 set -- "$@" -- 就不需要了
set -- $(getopt -o a -l name:,age: -- "$@")# 这里我们可以使用 set 命令来处理,set 命令可以用来指定一个结束标记
# set -- "$@" --
# 参数说明:
# set -- 为删除所有参数,在 -- 后面可以设置自定义参数,最后在添加一个 -- 作为结束标记
# 输出查看
echo "\$@: "$@while true; docase "$1" in-a)echo "-a 选项"shift;;# 为了兼容 getopt 长格式的设置,这里需要改成 --name--name)echo "-name 选项,参数为 $2"shift 2;;--age)echo "-age 选项,参数为 $2"shift 2;;--)break;;*)echo "非法参数"exit 1esac
done
[root@105 dongxx]# sh a.sh -a --name zhangsan --age 18
$@: -a --name 'zhangsan' --age '18' --
-a 选项
-name 选项,参数为 'zhangsan'
-age 选项,参数为 '18'
[root@105 dongxx]# sh a.sh -a aa --name zhangsan --age 18
$@: -a --name 'zhangsan' --age '18' -- 'aa'
-a 选项
-name 选项,参数为 'zhangsan'
-age 选项,参数为 '18'

执行测试

在这里插入图片描述

2.3 参数校验

当我们正常传参时,示例:sh a.sh -a --name zhangsan --age 18 没有问题。如果我们将有参的选项的参数去掉 sh a.sh -a --name zhangsan --age 那么就会报错

[root@105 dongxx]# sh a.sh -a --name zhangsan --age
getopt: option '--age' requires an argument
$@: -a --name 'zhangsan' --
-a 选项
-name 选项,参数为 'zhangsan'

在这里插入图片描述

问题:

​ 上述脚本中也有个问题,就是报错之后仍然会继续执行。

解决:

​ 修改脚本,在开头设置一个 set -e 让他需要非 0 状态吗自动退出。如果单纯只增加 set -e 命令,脚本同样会继续往下执行,因为在上述脚本中 getopt 是在 set -- 中执行的,getopt 报错,但是 set -- 是正常执行的,所以结果就不是一个非 0 状态。所以需要将 getopt 提取出来单独处理。

[root@105 dongxx]# cat a.sh 
#!/bin/bash
# 参数:-a -name zhangsan -age 18set -e# 将 getopt 提取出来赋值变量,那么校验失败后,set -e 就会检测到非 0 状态从而退出脚本
args=$(getopt -o a -l name:,age: -- "$@")
set -- $args# 使用 $(getopt -o a -l name:,age: -- "$@") 获取 getopt 处理后的参数信息,在使用 set -- 把这个结果设置后脚本的参数,由于 getopt 本身就有 -- 的结束标记,所以下面的 set -- "$@" -- 就不需要了
# set -- $(getopt -o a -l name:,age: -- "$@")# 这里我们可以使用 set 命令来处理,set 命令可以用来指定一个结束标记
# set -- "$@" --
# 参数说明:
# set -- 为删除所有参数,在 -- 后面可以设置自定义参数,最后在添加一个 -- 作为结束标记
# 输出查看
echo "\$@: "$@while true; docase "$1" in-a)echo "-a 选项"shift;;# 为了兼容 getopt 长格式的设置,这里需要改成 --name--name)echo "-name 选项,参数为 $2"shift 2;;--age)echo "-age 选项,参数为 $2"shift 2;;--)break;;*)echo "非法参数"exit 1esac
done
[root@105 dongxx]# sh a.sh -a --name zhangsan --age
getopt: option '--age' requires an argument

在这里插入图片描述

3. 示例展示

命令展示示例:

[root@105 dongxx]# getopt -o a:bc: -l name:,age:,man -- -a 1 -b -c 2 --name zhangsan --age 18 --man-a '1' -b -c '2' --name 'zhangsan' --age '18' --man --

脚本展示示例:

#!/bin/bash# 问题:在没有 -o 参数时会报错,这是为什么
# args=$(getopt -l name:,age:,address:,user:,passwd: -- "$@")args=$(getopt -o -a: -l name:,age:,address:,user:,passwd: -- "$@")if [[ $? != 0 ]]; thenecho "请输出正确参数"exit 1
fiecho "args: "$args
# 问题:这里为什么需要使用 eval ,暂时还不知道
eval set -- "$args"# set -- "$args"while true ;doecho "\$1: "$1case "$1" in--name)if [[ -z "$NAME" ]]; thenNAME=$2fishift 2;;--age)if [[ -z "$AGE" ]]; thenAGE=$2fishift 2;;--address)if [[ -z "$ADDRESS" ]]; thenADDRESS=$2fishift 2;;--user)if [[ -z "$USER" ]]; thenUSER=$2fishift 2;;--passwd)if [[ -z "$PASSWD" ]]; thenPASSWD=$2fishift 2;;--)break;;*)echo "参数错误,请检查"exit 1;;esac
doneecho "name: " $NAME ", age: " $AGE ", address: "$ADDRESS ", user: "$USER ", passwd: "$PASSWD

在这里插入图片描述

4. eval 命令

参考地址1

参考地址2

eval内置命令:
功能:当Shell程序执行到eval语句的时候,Shell读入参数args,并将它们组合成一个新的命令,然后执行。也就是重新运算求出参数的内容。eval可以读取一连串的参数,然后依据参数本身的特性来执行。参数不限数目,彼此之间用分号分开。

​ eval会对后面的命令进行两遍的扫描,如果第一遍扫描后,命令是普通命令,则执行此命令;如果命令中含有变量的间接引用,则保证间接引用的语义。也就是说,eval语句将会首先扫描命令行进行所有的置换,然后再进行该命令。因此,eval命令适合用于那些一次扫描无法实现其功能的变量。

eval执行分两个步骤:

​ 第一步:执行变量的替换。

​ 第二步:执行替换后的命令

4.1 示例

示例 1
[root@105 1]# cat a.sh 
#!/bin/bashecho "111 "\$$#
echo -e "\n"
echo "=============="
echo -e "\n"
eval "echo 2222 \$$#"
[root@105 1]# sh a.sh aa bb
111 $2==============2222 bb

在这里插入图片描述

脚本说明:

\$$#$# 是表示传参个数,\$ 表示转义,显示为普通字符 $ 所以第一次输出 \$$# 只进行了第一步的变量替换, 结果为 $2

​ 使用 eval 之后则进行了两次扫描,第一次是 $# 变量的替换,结果为 $2 ,然后再执行替换后的命令 $2,则结果显示 $2 的值 bb

如果我们知道参数的个数,输入两个参数 aa bb,我们可以使用 $2 来查看最后一个参数 bb。但是如果我们不知道参数个数,还想查看最后一个参数怎么办呢?我们想到 $#,传给Shell脚本的个数,echo $# 显示的其实是参数个数,而使用 eval echo "$$#" 才显示最后一个参数。和上述示例一样。

示例 2
[root@105 1]# cat test 
Hello World
[root@105 1]# aa="cat test"
[root@105 1]# echo $aa
cat test
[root@105 1]# eval $aa
Hello World

在这里插入图片描述

脚本说明:

  1. eval 命令对后面的命令进行了两次扫描,第一次将 $aa 替换为 cat test,第二次执行 cat test
  2. 这些需要进行两次扫描的变量有时也称为复杂变量。不过这些变量并不复杂。
示例 3

file 文件中,有两列数据,第一列对应 KEY ,第二列对应 VALUE ,使用 eval 命令将 KEYVALUE 的值对应起来,从文件中读取。

[root@105 1]# cat file 
NAME chang
AGE  28
SEX  nan
[root@105 1]# cat a.sh 
#!/bin/bash
while read KEY VALUE
doeval "${KEY}=${VALUE}"
done < file
echo "NAME: "$NAME", AGE: "$AGE", SEX:" $SEX
[root@105 1]# sh a.sh 
NAME: chang, AGE: 28, SEX: nan
[root@105 1]# 
[root@105 1]# sh -x a.sh 
+ read KEY VALUE
+ eval NAME=chang
++ NAME=chang
+ read KEY VALUE
+ eval AGE=28
++ AGE=28
+ read KEY VALUE
+ eval SEX=nan
++ SEX=nan
+ read KEY VALUE
+ echo 'NAME: chang, AGE: 28, SEX:' nan
NAME: chang, AGE: 28, SEX: nan

在这里插入图片描述

脚本说明:

eval "${KEY}=${VALUE}"eval 第一次扫描获取变量 ${KEY}=${VALUE} 的值,第二次进行赋值操作

示例 4
[root@105 1]# cat >a.sh<<EOF""
> #!/bin/bash
> x=100
> y=x
> eval echo \$$y
> eval $y=50
> echo $x
> eval echo \$$y
> EOF
[root@105 1]# cat a.sh 
#!/bin/bash
x=100
y=x
eval echo \$$y
eval $y=50
echo $x
eval echo \$$y
[root@105 1]# 
[root@105 1]# sh a.sh 
100
50
50

在这里插入图片描述

上面例子中的eval echo \$$y首先被读取,然后被执行:在读取的过程中,$y会被替换成x,所以读取的结果是echo $x;执行echo $x的输出就是打印了变量x的值。同理,eval $y=50会被解析成x=50,然后执行x=50的结果就是为变量x赋值。

示例 5

执行复杂的字符串形式的命令

[root@105 1]# cat a.sh 
#!/bin/bash
dirpath=/root/1
simple_cmd="ls -l $dirpath"
complex_cmd="ls -l $dirpath | awk -F ' ' '{print \$9}'"
echo '=========================='
echo '========Simple Cmd========='
echo '=========================='
eval $simple_cmd
echo '-----------------------------------'
$simple_cmd
echo '==========================='
echo '========Complex Cmd========='
echo '==========================='
eval $complex_cmd
echo '-----------------------------------'
$complex_cmd
[root@105 1]# 
[root@105 1]# sh a.sh 
==========================
========Simple Cmd=========
==========================
total 8
-rw-r--r-- 1 root root 467 Jul 11 21:28 a.sh
-rw-r--r-- 1 root root   5 Jul 11 21:28 test
-----------------------------------
total 8
-rw-r--r-- 1 root root 467 Jul 11 21:28 a.sh
-rw-r--r-- 1 root root   5 Jul 11 21:28 test
===========================
========Complex Cmd=========
===========================a.sh
test
-----------------------------------
ls: cannot access |: No such file or directory
ls: cannot access awk: No such file or directory
ls: cannot access ': No such file or directory
ls: cannot access ': No such file or directory
ls: cannot access '{print: No such file or directory
ls: cannot access $9}': No such file or directory
/root/1:
total 8
-rw-r--r-- 1 root root 467 Jul 11 21:28 a.sh
-rw-r--r-- 1 root root   5 Jul 11 21:28 test

在这里插入图片描述

可以看到,在执行$simple_cmd时,是否使用eval的效果是相同的。但是当我们执行一个稍微复杂一点(比如包含管道(Pipe))的字符串形式的命令时,如果不使用eval,执行会报错!

 
 
 
 
 

http://www.yayakq.cn/news/999512/

相关文章:

  • 个人做网站需要什么资料wordpress国外社交插件
  • 四川省住房和城乡建设厅网站首页提高工作效率的方法
  • 网站建设公司需要具备什么智能建站平台z
  • 郴州网站建设哪里比较好我想在家给工厂加工活
  • 房山区做网站seo类目链接优化
  • 宁波网站建设销售做网站的技术支持
  • 提交网站的入口地址网站登录模板下载
  • 怎么建网站教程视频贵阳专业建网站
  • 网站设计风格怎么写中国建盏大师排名表
  • 网站开发语言识别伪静态 wordpress
  • 网站跟客户端推广怎么做水墨背景风格企业网站模板
  • 上海网站制作优化新媒体h5是什么
  • 电子商务网站和普通网站的区别wordpress手机模板插件
  • 空间站做网站有什么深圳公司注册地址变更
  • 行业网站建设方案网络广告投放方案
  • 信阳建设企业网站公司曹妃甸建设工程招投标网站
  • 网站架构优化 amp重庆建设工业公司官网
  • 佛山智唯网站建设中国华能集团电子商务平台
  • 佛山制作网站公司哪家好上海网站域名注册价格
  • 网站搭建需要服务器吗怎样优化网站 优帮云
  • 营销单页模板网站学网站开发的总结
  • 广州市天河区住房和建设局网站dz网站模板
  • 保定网站 优建网站到底需要多少钱
  • 电子商务网站建设报告分析国外企业招聘网站
  • 农业网站怎么做百度推广应用软件下载app
  • 商城网站做推广方案淘宝网页设计价格
  • 济南网站seo怎么把服务器做网站
  • 哈尔滨专门做网站中投建设官方网站
  • 专业定制网站系统网站建设国培心得体会
  • 网站建设江苏题材挖掘机网站怎么做