命令行参数


$0, $1, …, $9, ${10}, …
其中, $0表示程序名, 后面依次为第n个参数

特殊参数变量:
$# 参数的个数
${!#} 输出最后一个参数
$* 所有的参数当做一个单词
$@ 所有参数当做同一个字符串的多个独立的单词

特殊情况:

  • 传参时每个参数按照空格进行分割, 所以对于包含空格的字符串使用’’包含

    1. ./sh 'Rich me'
  • 对于$0读取脚本名, 有时命令和脚本会混合在一起, 使用basename $0处理

    ./test.sh # $0为 ./test.sh
    
  • 使用参数注意使用-n校验参数是否存在

  • 移动参数使用shift命令. shift -n 向前移除n个参数

选项


示例:
处理基本选项如./test.sh -a -b -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" ;; 
 *) echo "$1 is not an option" ;; 
 esac 
 shift 
done

分离参数和选项如 ./test.sh -c -a -b — test1 test2 test3

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

shell会自动将选项和参数使用 — 分隔开

处理带值的选项如: ./test.sh -a -b test1 -d

while [ -n "$1" ] 
do 
 case "$1" in 
 -a) echo "Found the -a option";; 
 -b) param="$2" 
 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

处理合并选项: ./test.sh -a -b -test1 -cd test2 test3 test4
使用getopt命令识别命令行参数

getopt optstring paramaters
# optstring 定义了命令行有效的字母
# 字母加冒号表明该选项后可以加参数
# -q 表示转换时不报错
set -- $(getopt -q ab:cd "$@") 
while [ -n "$1" ] 
do 
 case "$1" in 
 -a) echo "Found the -a option" ;; 
 -b) param="$2" 
 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

对于./test.sh -a -b test1 -cd test2 test3 test4 getopt -q ab:cd “$@”会处理成 ./test.sh -a -b test1 -c -d test2 — test3 test4

问题: getopt难以处理带空格和引号的参数值

getopts处理选项
语法:

getopts optstring variable
# 在optstring前加:去掉错误
# getopts会处理命令行检测的一个参数并赋给variable
# getopts会使用两个环境变量, OPTARG保存选项带的参数值, OPTIND保存正在处理的参数位置
while getopts :a:b:cd opt
do
    case "$opt" in
    a) echo "-a option param $OPTARG" ;;
    b) echo "-b option, param $OPTARG" ;;
    c) echo "-c option" ;;
    d) echo "-d option" ;;
    *) echo "Unknown Option: $opt";;
    esac
done

echo $OPTIND
shift $(( OPTIND - 1 ))

for param in "$@"
do
    echo "$param"
done

获取用户输入


示例:

read -r name 
# 等待用户输入name, -r 表示\不转义

read -p "Please enter your name" name 
# 提示用户输入数据 

read -p "Multi variable: " var1 var2 var3
# read 读取多个空格分割的参数

read -p "REPLY变量: "
echo "REPLY: $REPLY"
# $REPLY可以获取参数

read -t 5 -p "5s内输入参数"
# read设置读取时间

# read -n1 接收单个字符
# read -s 隐藏数据(实质是数据的文本色与背景色一致)
# read 读取文件中的数据, 每次读取一行, 直到没有数据返回非零退出状态码
cat test | while read -r line
do
    echo "$line"
done # 最后一行数据遗失