处理用户输入(位置变量)
#命令行参数
位置参数特殊变量
$1,$2...$9,${10},${12} -- 超过9个需要添大括号
sh sw_cs.sh 2 3 4 5 6 7 8 9 10 11 12 -- 传递的参数值以空格分隔
读取脚本名($0)
当前执行
sh sw_cs.sh -- sw_cs.sh
返回不含路径的文件名(basename)
name=$(basename $0)
echo The script name is: $name
sh /home/ly_ibas/test/sw_cs.sh -- sw_cs.sh
测试参数
if [ -n "$1" ]
then
echo Hello $1, glad to meet you.
else
echo "Sorry, you did not identify yourself. "
fi -- 避免未传参数也不提示
#特殊参数变量
传入参数统计($#)
echo ${!#} -- 打印传入参数最后一个变量的值
抓取所有参数($* $@)
$* 变量会将所有参数当成单个参数,而 $@ 变量会单独处理每个参数
#移动变量(shift)
默认变量 $2 的值会移到 $1 中,而变量 $1 的值则会被删除,所以统计 S# 会少一条数据
shift 2 -- $3变量的值移动到$1
#处理选项
处理简单选项
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) echo "Found the -b option" ;;
-c) echo "Found the -c option" ;;
*) echo "$1 is not an option" ;;
esac
shift
done -- 处理方式与处理参数一致
sh sw_cs.sh -b -a -c -d
分离参数和选项(--)
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) echo "Found the -b option";;
-c) echo "Found the -c option" ;;
--) shift
break ;;
*) echo "$1 is not an option";;
esac
shift
done
#
count=1
for param in $@
do
echo "Parameter #$count: $param"
count=$[ $count + 1 ]
done
sh sw_cs.sh -c -a -b -- test1 test2 test3
处理带值的选项
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option";;
-b) param="$2" -- 增加了位置变量$2,针对-b选项的test1参数
echo "Found the -b option, with parameter value $param"
shift ;;
-c) echo "Found the -c option";;
--) shift
break ;;
*) echo "$1 is not an option";;
esac
shift
done
#
count=1
for param in "$@"
do
echo "Parameter #$count: $param"
count=$[ $count + 1 ]
done
sh sw_cs.sh -a -b test1 -d
#使用getopt命令(处理命令行和参数的工具,无法正常处理带空格的字符串如"test1 test2")
基本用法
getopt ab:cd -a -b test1 -cd test2 test3
-- ab:cd定义了4个选项以及-b选项后有参数
-- -a -b test1 -c -d -- test2 test3 ( : )表示-b选项后有参数,-cd表示-c、-d选项后是参数以--分隔
忽略错误信息提示(当插入一个没有定义的选项-q)
getopt -q abcd -a -b -e -cd test2 test3
在脚本中的使用
set -- $(getopt -q ab:cd "$@") -- 格式化命令行参数
#
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option";;
-b) param="$2" -- 增加了位置变量$2,针对-b选项的test1参数
echo "Found the -b option, with parameter value $param"
shift ;;
-c) echo "Found the -c option";;
--) shift
break ;;
*) echo "$1 is not an option";;
esac
shift
done
#
count=1
for param in "$@"
do
echo "Parameter #$count: $param"
count=$[ $count + 1 ]
done
sh sw_cs.sh -a -b test1 -d
getopts可以解决gotopt无法处理带空格字符串参数,并且可以将选项和参数放在一起不加空格
getopts :ab:c opt -- 开始的:不显示错误信息,opt是一个变量用于存储参数行
while getopts :ab:c opt -- getopts解析完参数传给opt变量返回大于0的状态码结束,实际上循环是对opt变量的处理
do
case "$opt" in
a) echo "Found the -a option" ;; -- 选项-a不需要单破绽线,getopts自识别
b) echo "Found the -b option, with value $OPTARG";; -- $OPTARG作为getopts参数的内置变量
c) echo "Found the -c option" ;;
*) echo "Unknown option: $opt";;
esac
done
#
shift $[ $OPTIND - 1 ] -- OPTIND环境变量初始值是1,getopts处理每个选项时增1。处理后面的参数
#
echo
count=1
for param in "$@"
do
echo "Parameter $count: $param"
count=$[ $count + 1 ]
done
sw_cs.sh .sh -a -btest1 -d "test2 test3" test4
-- -b选项的test1能够识别,因为脚本中定义了a、b、c选项所以-ab选项不会将b识别为参数会认为是-ab这个选项
-- "test2 test3"被识别为一个参数
#Linux中用到的一些命令行选项的常用含义
选 项 描 述
-a 显示所有对象
-c 生成一个计数
-d 指定一个目录
-e 扩展一个对象
-f 指定读入数据的文件
-h 显示命令的帮助信息
-i 忽略文本大小写
-l 产生输出的长格式版本
-n 使用非交互模式(批处理)
-o 将所有输出重定向到的指定的输出文件
-q 以安静模式运行
-r 递归地处理目录和文件
-s 以安静模式运行
-v 生成详细输出
-x 排除某个对象
-y 对所有问题回答yes
#获得用户输入
读取(read)
基本的读取
echo -n "Enter your name: "
read name -- 执行该步骤时从键盘输入
echo "Hello $name, welcome to my program. "
-p 加入提示符
read -p "Please enter your age: " age -- 不需要使用echo打印
days=$[ $age * 365 ]
echo "That makes you over $days days old! "
不指定变量,会将所有的输入输出到特殊环境表里REPLY
read -p "Enter your name: "
echo
echo Hello $REPLY, welcome to my program.
超时(-t)
if read -t 5 -p "Please enter your name: " name -- -t 5 等待5秒未键入返回非0状态码
then echo "Hello $name, welcome to my script"
else
echo
echo "Sorry, too slow! "
fi
输入指定字符退出
read -n1 -p "Do you want to continue [Y/N]? " answer
case $answer in
Y | y) echo
echo "fine, continue on…";;
N | n) echo
echo OK, goodbye
exit;;
esac
echo "This is the end of the script"
隐藏方式读取(-s)
read -s -p "Enter your name: "
echo
echo Hello $REPLY, welcome to my program.
从文件中读取(通过cat和管道以及循环实现)
count=1
cat test | while read line --每次调用 read 命令,它都会从文件中读取一行文本
do
echo "Line $count: $line"
count=$[ $count + 1]
done
echo "Finished processing the file"
生活就要逢山开路遇水搭桥,愿共勉!