变量 含义

$0:shell脚本的名字;

$1 位置参数 #1

$2 - $9 位置参数 #2 - #9

${10} 位置参数 #10

"$*" :代表"$1c$2c$3 ..."形式保存所有参数,c为分隔符,默认为空格。如"$1 $2 $3 ..."

$@:代表"$1"、"$2"、“$3”...,将各个参数分别加双引号返回。

$# :传入的参数个数

$?:代表上一个命令执行后的退出状态,返回值0表成功。其他任何值表明有错误。

shell中用"exit"命令退出,参数n表示带返回值n退出。没有n则返回最后一个命令执行的后的状态,在shell被终止前,将执行exit的陷阱,

这个n值存放在$?中,一般来说, exit 0表示成功,exit 1表示失败。echo $?去查看返回的结果。

其他不常用的:

$$ 脚本运行的进程ID(PID)

$- 传递到脚本中的标志(和使用set相同效果) ,显示shell使用的当前选项

$_ 之前命令的最后一个参数

$!:运行在后台的最后一个作业的进程ID(PID),也就是上一个命令的PID

为了结合实例方便理解,下面给出详细的文章:

以下大部分引自网络:

0.引言

写程序常要处理命令行参数,在Bash下的命令行处理方式:

选项与参数:

如下一个命令行:

./test.sh -f config.conf -v --prefix=/home

我们称-f为选项,它需要一个参数,即config.conf, -v 也是一个选项,但它不需要参数。

--prefix我们称之为一个长选项,即选项本身多于一个字符,它也需要一个参数,用等号连接,当然等号不是必须的,/home可以直接写在--prefix后面,即--prefix/home,更多的限制后面具体会讲到。

在bash中,可以用以下三种方式来处理命令行参数,每种方式都有自己的应用场景。

* 手工处理方式

* getopts

* getopt

下面我们依次讨论这三种处理方式。

1. 手工处理方式

在手工处理方式中,首先要知道几个变量,还是以上面的命令行为例:

* $0 : ./test.sh,即命令本身,相当于C/C++中的argv[0]

* $1 : -f,第一个参数.

* $2 : config.conf

* $3, $4 ... :类推。

* $# 参数的个数,不包括命令本身,上例中$#为4.

* $@ :参数本身的列表,也不包括命令本身,如上例为 -f config.conf -v --prefix=/home

* $* :和$@相同,但"$*" 和 "$@"(加引号)并不同,"$*"将所有的参数解释成一个字符串,而"$@"是一个参数数组。如下例所示:

1 #!/bin/bash

2

3 for arg in "$*"

4 do

5 echo $arg

6 done

7

8 for arg in "$@"

9 do

10 echo $arg

11 done

12

执行./test.sh -f config.conf -n 10 会打印:

-f config.conf -n 10 #这是"$*"的输出

#以下为$@的输出:

-f

config.conf

-n

10

所以,手工处理的方式即对这些变量的处理。因为手工处理高度依赖于你在命令行上所传参数的位置,所以一般都只用来处理较简单的参数。如

./test.sh 10

而很少使用./test -n 10这种带选项的方式。 典型用法为:

#!/bin/bash

if [ x$1 != x ]

then

#...有参数

else

then

#...没有参数

fi

为什么要使用 x$1 != x 这种方式来比较呢?想像一下这种方式比较:

if [ -n $1 ] #$1不为空

但如果用户不传参数的时候,$1为空,这时 就会变成 [ -n ] ,所以需要加一个辅助字符串来进行比较。

手工处理方式能满足大多数的简单需求,配合shift使用也能构造出强大的功能,但在要处理复杂选项的时候建议用下面的两种方法。

2. getopts/getopt

处理命令行参数是一个相似而又复杂的事情,为此,C提供了getopt/getopt_long等函数,

C++的boost提供了Options库,在shell中,处理此事的是getopts和getopt.

getopts和getopt功能相似但又不完全相同,其中getopt是独立的可执行文件,而getopts是由Bash内置的。

先来看看参数传递的典型用法:

* ./test.sh -a -b -c : 短选项,各选项不需参数

* ./test.sh -abc : 短选项,和上一种方法的效果一样,只是将所有的选项写在一起。

* ./test.sh -a args -b -c :短选项,其中-a需要参数,而-b -c不需参数。

* ./test.sh --a-long=args --b-long :长选项

我们先来看getopts,它不支持长选项。

使用getopts非常简单:

代码

#test.sh

#!/bin/bash

while getopts "a:bc" arg #选项后面的冒号表示该选项需要参数

do

case $arg in

a)

echo "a's arg:$OPTARG" #参数存在$OPTARG中

;;

b)

echo "b"

;;

c)

echo "c"

;;

?) #当有不认识的选项的时候arg为?

echo "unkonw argument"

exit 1

;;

esac

done

现在就可以使用:

./test.sh -a arg -b -c



./test.sh -a arg -bc

来加载了。

应该说绝大多数脚本使用该函数就可以了,如果需要支持长选项以及可选参数,那么就需要使用getopt.

下面是getopt自带的一个例子:

#!/bin/bash

# A small example program for using the new getopt(1) program.

# This program will only work with bash(1)

# An similar program using the tcsh(1) script language can be found

# as parse.tcsh

# Example input and output (from the bash prompt):

# ./parse.bash -a par1 'another arg' --c-long 'wow!*/?' -cmore -b " very long "

# Option a

# Option c, no argument

# Option c, argument `more'

# Option b, argument ` very long '

# Remaining arguments:

# --> `par1'

# --> `another arg'

# --> `wow!*/?'

# Note that we use `"$@"' to let each command-line parameter expand to a

# separate word. The quotes around `$@' are essential!

# We need TEMP as the `eval set --' would nuke the return value of getopt.

#-o表示短选项,两个冒号表示该选项有一个可选参数,可选参数必须紧贴选项

#如-carg 而不能是-c arg

#--long表示长选项

#"$@"在上面解释过

# -n:出错时的信息

# -- :举一个例子比较好理解:

#我们要创建一个名字为 "-f"的目录你会怎么办?

# mkdir -f #不成功,因为-f会被mkdir当作选项来解析,这时就可以使用

# mkdir -- -f 这样-f就不会被作为选项。

TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: /

-n 'example.bash' -- "$@"`

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

# Note the quotes around `$TEMP': they are essential!

#set 会重新排列参数的顺序,也就是改变$1,$2...$n的值,这些值在getopt中重新排列过了

eval set -- "$TEMP"

#经过getopt的处理,下面处理具体选项。

while true ; do

case "$1" in

-a|--a-long) echo "Option a" ; shift ;;

-b|--b-long) echo "Option b, argument /`$2'" ; shift 2 ;;

-c|--c-long)

# c has an optional argument. As we are in quoted mode,

# an empty parameter will be generated if its optional

# argument is not found.

case "$2" in

"") echo "Option c, no argument"; shift 2 ;;

*) echo "Option c, argument /`$2'" ; shift 2 ;;

esac ;;

--) shift ; break ;;

*) echo "Internal error!" ; exit 1 ;;

esac

done

echo "Remaining arguments:"

for arg do

echo '--> '"/`$arg'" ;

done

比如我们使用

./test -a -b arg arg1 -c

你可以看到,命令行中多了个arg1参数,在经过getopt和set之后,命令行会变为:

-a -b arg -c -- arg1

$1指向-a,$2指向-b,$3指向arg,$4指向-c,$5指向--,而多出的arg1则被放到了最后。

Shell script 传参数处理(默认变量)的更多相关文章

  1. shell script针对参数已经有配置好变量名称

    /path/to/scriptname opt1 opt2 opt3 opt4 $ $ $ $ $ 这样够清楚了吧?运行的脚本档名为 $0 这个变量,第一个接的参数就是 $1 啊- 所以,只要我们在 ...

  2. [2019.03.20]Linux Shell 执行传参数和expr

    前不久入职实习生,现在在帮着组里面dalao们跑Case,时不时要上去收一下有木有Dump,每次敲命令太烦人于是逼着自己学写Shell脚本.一开始真的是很痛苦啊,也没能搞到书,只能凭网上半真半假的消息 ...

  3. shell命令传参数(参数长度不定)

    脚本 sudo echo "[mysqlMaster<$1>]" >> /home/admin/hostrecord count= ];do >> ...

  4. shell 文件传 参数

    n cross-platform, lowest-common-denominator sh you use: #!/bin/sh value=`cat config.txt` echo " ...

  5. python中函数的参数:必传参数(位置参数)、默认值参数、参数组传参、关键字传参

    1.必传参数也叫做位置参数,因为必填,也必须对应位置 2.默认值参数如上图的word 3.参数组参数:传进去的是0个.或多个value的形式,,,和位置参数有点像,只传value值,但是没有限制个数 ...

  6. 第13章 学习shell script

    由于博客园中dollar符号有别的意义,所以文中的dollar符号使用¥表示 第一个script [root@localhost script]# cat -n sh01.sh #!/bin/bash ...

  7. shell及脚本4——shell script

    一.格式 1.1 开头 必须以 "# !/bin/bash"  开头,告诉系统这是一个bash shell脚本.注意#与!中间有空格. 二.语法 2.1 数值运算 可以用decla ...

  8. shell脚步传参

    linux系统除了提供位置参数还提供内置参数,内置参数如下: $# ----传递给程序的总的参数数目 $? ----上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0,反之为非 ...

  9. shell编程 Shell script 的默认变量($0, $1...)

    Shell script 的默认变量($0, $1...) 我们知道指令可以带有选项与参数,例如 ls -la 可以察看包含隐藏文件的所有属性与权限.那么 shell script 能不能在脚本文件名 ...

随机推荐

  1. JAVA生成数字0~9字母A~Z混合编码0000、0001...0009、000A...000Z、0010......

    分别是求下一个编码 和 输出所有编码 /** * 用1--9加A--Z混合编码 使用ASCII码判断 * LYL * 传一个值 求下一个编码 */ public String getABCDCode( ...

  2. Dynamics CRM2016 WebApi查询之alternate key

    本篇继续来分享web api查询中的一条,利用alternate key进行查询. alternate key是个什么东西这里就不解释了如果有不知道的可以去看sdk.这里以房号信息实体为例,新建一个键 ...

  3. 操作系统内核Hack:(一)实验环境搭建

    操作系统内核Hack:(一)实验环境搭建 三四年前,心血来潮,入手<Orange's:一个操作系统的实现>学习操作系统内核,还配套买了王爽的<汇编语言(第二版)>和<80 ...

  4. Linux SWAP 交换分区配置说明

    一.SWAP 说明1.1 SWAP 概述        当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用.那些被释放的空间可能来自一些很长时间没有什么操作的 ...

  5. 激活第一个CPU

    回到start_kernel,559行,boot_cpu_init函数,跟start_kernel位于同一文件: 494static void __init boot_cpu_init(void) 4 ...

  6. Zookeeper动态更新服务器列表

    -------------------------------------------------------------------------------------- [版权申明:本文系作者原创 ...

  7. [CSDN_Markdown]Markdown基本语法2

    简介 前文 Markdown基本语法 中介绍了Markdown的基本语法,知道那些基本的语法,实际上已经可以写纯文本的博客了.对我们这群写代码的人或者将要写代码的人来说,貌似这些还不够,我们还希望能插 ...

  8. 给定一个实数数组,按序排列(从小到大),从数组从找出若干个数,使得这若干个数的和与M最为接近,描述一个算法,并给出算法的复杂度。

    有N个正实数(注意是实数,大小升序排列) x1 , x2 ... xN,另有一个实数M. 需要选出若干个x,使这几个x的和与 M 最接近. 请描述实现算法,并指出算法复杂度. #define M 8 ...

  9. java泛型总结(类型擦除、伪泛型、陷阱)

    JDK1.5开始实现了对泛型的支持,但是java对泛型支持的底层实现采用的是类型擦除的方式,这是一种伪泛型.这种实现方式虽然可用但有其缺陷. <Thinking in Java>的作者 B ...

  10. Hazelcast集群原理分析

    简介 hazelcast其中一个很重要的应用就是可以将多个应用服务器组成一个分布式环境的应用,形成一个cluster.这个cluster可以选举出一个master来对外工作.而cluster中的各台服 ...