网站开发 怎么才能发表情,建设银行交罚款网站,三台建设局网站,上海专上海专业网站制作公司目录
一、传递参数
1.1 读取参数
1.2 读取脚本名
二、跟踪参数
三、移动参数
四、处理选项
4.1 查找选项
4.1.1 处理简单选项
4.1.2 分离参数和选项 4.1.3 处理含值的选项
五、选项标准化
5.1 使用 getopt 命令
5.1.1 命令格式
5.1.2 在脚本中使用getopt 5.2 使用…目录
一、传递参数
1.1 读取参数
1.2 读取脚本名
二、跟踪参数
三、移动参数
四、处理选项
4.1 查找选项
4.1.1 处理简单选项
4.1.2 分离参数和选项 4.1.3 处理含值的选项
五、选项标准化
5.1 使用 getopt 命令
5.1.1 命令格式
5.1.2 在脚本中使用getopt 5.2 使用getopts命令
六、获取用户输入
6.1 read读取
6.2 从文件中读取 一、传递参数 向 shell 脚本传递数据的最基本方法是使用命令行参数。bash shell 会将所有的命令行参数都指派给称作位置参数的特殊变量。这也包括shell脚本名称。位置变量的名称都是标准数字$0 对应脚本名$1 对应第一个命令行参数$2 对应第二个命令行参数以此类推直到 $9第9个之后必须在变量名两侧加上花括号比如 ${10} 。 1.1 读取参数 如果需要 输入更多的命令行参数则参数之间必须用空格分开 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat position.sh
#! /bin/bashvalue$[ ${10} * ${11} ]
echo 第10个参数是${10}
echo 第11个参数是${11}
echo $value
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# ./position.sh 1 2 3 4 5 6 7 8 9 10 12
第10个参数是10
第11个参数是12
120
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#1.2 读取脚本名 可以使用位置变量 $0 获取在命令行中运行的脚本名。 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat position.sh
#! /bin/bashvalue$[ ${10} * ${11} ]
echo 第10个参数是${10}
echo 第11个参数是${11}
echo $value
echo 脚本名是$0
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash position.sh 1 2 3 4 5 6 7 8 9 10 12
第10个参数是10
第11个参数是12
120
脚本名是position.sh
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# 但是这会有一个问题如果使用另一个命令运行shell脚本则命令名会和脚本名混在一起 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat position.sh
#! /bin/bashvalue$[ ${10} * ${11} ]
echo 第10个参数是${10}
echo 第11个参数是${11}
echo $value
echo 脚本名是$0
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash position.sh 1 2 3 4 5 6 7 8 9 10 12
第10个参数是10
第11个参数是12
120
脚本名是position.sh
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# ./position.sh 1 2 3 4 5 6 7 8 9 10 12
第10个参数是10
第11个参数是12
120
脚本名是./position.sh
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#这还不是唯一的问题如果运行脚本时使用的是绝对路径那么位置变量 $0 就会包含整个路径 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# pwd
/root
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# ~/position.sh
/root/position.sh: line 3: * : syntax error: operand expected (error token is * )
第10个参数是
第11个参数是脚本名是/root/position.sh
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# basename 命令可以返回不包含路径的脚本名 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat position.sh
#! /bin/bashvalue$[ ${10} * ${11} ]
echo 第10个参数是${10}
echo 第11个参数是${11}
echo $value
name$(basename $0)
echo 脚本名是$name
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# ./position.sh 1 2 3 4 5 6 7 8 9 10 12
第10个参数是10
第11个参数是12
120
脚本名是position.sh
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#利用此技术可以编写一个脚本生成能标识脚本运行时间的日志信息 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat position.sh
#! /bin/bashvalue$[ ${10} * ${11} ]
echo 第10个参数是${10}
echo 第11个参数是${11}
echo $value
name$(basename $0)
echo 脚本名是$name
echo The $name ran at $(date) ~/scripttrack.log
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# date
Fri May 10 15:42:54 CST 2024
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# ./position.sh 1 2 3 4 5 6 7 8 9 10 12
第10个参数是10
第11个参数是12
120
脚本名是position.sh
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# ll
total 12
-rwxr--r-- 1 root root 210 May 10 15:42 position.sh
drwxr-xr-x 2 root root 4096 May 9 23:36 script
-rw-r--r-- 1 root root 52 May 10 15:43 scripttrack.log
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat scripttrack.log
The position.sh ran at Fri May 10 15:43:01 CST 2024
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#二、跟踪参数 特殊变量 $# 含有脚本运行时携带的命令行参数的个数${!#} 代表最后一个位置变量$* 和 $ 各自包含了所有的命令行参数。$* 将所有参数视为一个整体$ 会将所有命令行参数视为同一字符串中的多个独立的单词可以用 for 遍历所有参数。 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat params.sh
#! /bin/bash
echo
echo \$*用法$*
count1
for param in $*
doecho \$* #$count $paramcount$[ $count 1 ]
done########
echo
echo \$用法$
count1
for param in $
doecho \$ #count $paramcount$[ $count 1 ]
done
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash params.sh 1 2 3$*用法1 2 3
$* #1 1 2 3$用法1 2 3
$ #count 1
$ #count 2
$ #count 3
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#
三、移动参数 shift 命令会根据命令行参数的相应位置进行移动默认情况下会将每个位置的变量值都向左移动一个位置。因此变量 $3 的值会移入 $2 变量 $2 的值会移入 $1 而变量 $1 的值会被删除变量 $0 是脚本名不会变。这是遍历命令行参数的另一种好方法尤其在不知道到底有多少参数的时候。 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat shift.sh
#! /bin/bash
echo
echo shift的用法
count1
while [ -n $1 ]
doecho #$count $1count$[ $count 1 ]shift
done
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash shift.sh ab cd 12 34 dfshift的用法
#1 ab
#2 cd
#3 12
#4 34
#5 df
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#四、处理选项
4.1 查找选项 在命令行中选项紧跟在脚本名之后就跟其他命令行参数一样 。你可以像处理命令行参数一样处理命令行选项 4.1.1 处理简单选项 在提取单个参数时使用 case 语句来判断某个参数是否为选项 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# vim option.sh
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat option.sh
#! /bin/bash
echo
while [ -n $1 ]
docase $1 in-a) echo a是一个选项;;-b) echo b是一个选项;;-c) echo c是一个选项;;*) echo $1不是一个选项;;esacshift
done
echo
exit
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash option.sh -b -a e -fb是一个选项
a是一个选项
e不是一个选项
-f不是一个选项[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#
4.1.2 分离参数和选项 经常会碰到同时使用选项和参数的情况。在Linux系统中处理这个问题的标准做法是使用特殊字符将两者分隔该字符告诉脚本选项何时结束普通字符何时开始。在Linux系统中这个特殊字符是双连字符--。 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat option.sh
#! /bin/bash
echo
while [ -n $1 ]
docase $1 in-a) echo -a是一个选项;;-b) echo -b是一个选项;;-c) echo -c是一个选项;;--) shiftbreak;;*) echo $1不是一个选项;;esacshift
done
#
echo
count1
for param in $
doecho 参数#$count $paramcount$[ $count 1 ]
done
echo
exit
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash option.sh -b -a -d -- 1 21 6-b是一个选项
-a是一个选项
-d不是一个选项参数#1 1
参数#2 21
参数#3 6[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#在遇到双连字符时脚本会用break命令跳出while循环。由于提前结束了循环因此需要再加入另一个shift命令将双连字符移除位置变量 4.1.3 处理含值的选项 有些选项需要一个额外的参数值像下面这样 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat option.sh
#! /bin/bash
echo
while [ -n $1 ]
docase $1 in-a) echo -a是一个选项;;-b) echo -b是一个选项echo 参数$2shift ;;-c) echo -c是一个选项;;--) shiftbreak;;*) echo $1不是一个选项;;esacshift
done
#
echo
count1
for param in $
doecho 参数#$count $paramcount$[ $count 1 ]
done
echo
exit
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash option.sh -b test -a -d -- 1 21 6-b是一个选项
参数test
-a是一个选项
-d不是一个选项参数#1 1
参数#2 21
参数#3 6[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#在这个例子中case语句定义了3个要处理的选项。-b选项还需要一个额外的参数。由于要处理的选项位于 $1 因此额外的参数值就应该位于 $2 因为选项占用了两个位置所以还需要使用 shift 命令多移动一次。 五、选项标准化 现在shell脚本已经拥有处理命令行选项的基本能力了但是当你想合并多个选项时脚本就不管用了。 5.1 使用 getopt 命令
5.1.1 命令格式 getopt 命令可以接受一系列任意形式的命令行选项和参数并自动将其转换为适当格式。getopt 格式如下getopt optstring parameters 首先在 optstring 中列出要在脚本中用到的每个命令行选项字母。然后在每个需要参数值的选项字母后面加一个冒号。如下 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# getopt ab:cd -a -b value -cd 1 2-a -b value -c -d -- 1 2
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# 如果 optstring 未包含制定的选项则会输出一条错误信息如果想忽略可以使用 -q 选项。 5.1.2 在脚本中使用getopt 1可以在脚本中使用 getopt 格式化脚本所携带的任何命令行选项或参数。难点在于使用 getopt 格式化版本替换已有的命令行选项和参数。这得求助于 set 命令 2set 命令有个选项是双连字符--可以将位置变量的值替换为 set 命令所指定的值 3具体做法是将脚本的命令行参数传递给getopt命令然后将getopt命令的输出传递给set命令用getopt格式化后的命令行参数来替换原始的命令行参数如下所示 set -- $(getopt -q ab:cd $) 现在位置变量原先的值会被getopt命令的输出替换掉后者已经是格式化好的命令行参数。 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat option.sh
#! /bin/bashset -- $(getopt -q ab:cd $)
echo
while [ -n $1 ]
docase $1 in-a) echo -a是一个选项;;-b) echo -b是一个选项echo 参数$2shift ;;-c) echo -c是一个选项;;--) shiftbreak;;*) echo $1不是一个选项;;esacshift
done
#
echo
count1
for param in $
doecho 参数#$count $paramcount$[ $count 1 ]
done
echo
exit
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash option.sh -ab bvalue 12 3-a是一个选项
-b是一个选项
参数bvalue参数#1 12
参数#2 3[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#5.2 使用getopts命令 getopt 命令存在一个问题如下代码所示就是不擅长处理带空格和引号的参数值。它会将空格当做参数值的分隔符而不是根据双引号将二者当做一个参数。这是 getopts 就派上用场了。 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash option.sh -ab bvalue 12 3 -c-a是一个选项
-b是一个选项
参数bvalue
-c是一个选项参数#1 12
参数#2 3[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash option.sh -ab bvalue 12 3 -c-a是一个选项
-b是一个选项
参数bvalue
-c是一个选项参数#1 12
参数#2 3 getopts 命令格式如下 getopts optstring variable 1 optstring 值与 getopt 命令中使用的类似。有效的选项字母会在 optstring 中列出如果选项要求参数就在其后面加一个冒号。不想显示错误消息的话可以在 optstring 之前加一个冒号。getopts 会将当前参数保存在命令行中定义的varibales中。 2getopts 会用到两个环境变量。如果选项需要加带参数值那么 OPTARG 环境变量保存的就是这个值。OPTIND 环境变量保存着参数列表中 getopts 正在处理的参数位置。这样在处理完当前选项之后就能继续处理其他命令行参数了。 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat getopts.sh
#! /bin/bash
echo
while getopts :ab:cd opt
docase $opt ina) echo -a是选项;;b) echo -b是一个选项echo -b选项的参数是$OPTARG;;c) echo -c是一个选项;;*) echo 未知选项$opt;;esac
done
exit
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash getopts.sh -ab2-a是选项
-b是一个选项
-b选项的参数是2
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# 1 在解析命令行选项时getopts 会移除起始的连字符所以 case 语句中不用连字符 2可以在参数值中加空格 3可以将选项字母和参数值写在一起两者之间不加空格 4在处理每个选项时getopts 会将OPTIND 环境变量的值增1.处理完选项后可以使用shift命令和OPTIND值来移动参数。 [rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat getopts.sh
#! /bin/bash
echo
while getopts :ab:cd opt
docase $opt ina) echo -a是选项;;b) echo -b是一个选项echo -b选项的参数是$OPTARG;;c) echo -c是一个选项;;*) echo 未知选项$opt;;esac
done
#
shift $[ $OPTIND -1 ]
echo
count1
for param in $
doecho 参数#$count $paramcount$[ $count 1 ]
done
exit六、获取用户输入 尽管命令行选项和参数是从脚本用户处获取输入的一种重要方式但有时候脚本还需要更多 的交互性。为此bash shell 提供了 read 命令。 6.1 read读取
read -p Please enter your age: age
read -t 5 -p Please enter your age: age # 超时
read -s Enter your password: password # 无显示输出
6.2 从文件中读取
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# cat read.sh
#! /bin/bash
echo
count1
cat ~/getopts.sh | while read line
doecho #$count $linecount$[ $count 1 ]
done
echo 处理完文本的所有行
exit
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]# bash read.sh#1 #! /bin/bash
#2 echo
#3 while getopts :ab:cd opt
#4 do
#5 case $opt in
#6 a) echo -a是选项;;
#7 b) echo -b是一个选项
#8 echo -b选项的参数是$OPTARG;;
#9 c) echo -c是一个选项;;
#10 *) echo 未知选项$opt;;
#11 esac
#12 done
#13 #
#14 shift $[ $OPTIND -1 ]
#15 echo
#16 count1
#17 for param in $
#18 do
#19 echo 参数#$count $param
#20 count$[ $count 1 ]
#21 done
#22 exit
处理完文本的所有行
[rootiZbp1ir1vzqwzkdy7mvjthZ ~]#while 循环会持续通过read命令处理文件中的各行直到read命令以非0退出状态码退出