Skip to content

Commit 5bf5cd8

Browse files
committed
docs: edit script
1 parent 703f037 commit 5bf5cd8

1 file changed

Lines changed: 64 additions & 13 deletions

File tree

docs/script.md

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,7 @@ $ /bin/sh ./script.sh
3838
$ bash ./script.sh
3939
```
4040

41-
## 执行权限和路径fn () {
42-
local foo
43-
foo=1
44-
echo "fn: foo = $foo"
45-
}
46-
47-
fn
48-
echo "global: foo = $foo"
41+
## 执行权限和路径
4942

5043
前面说过,通过 Shebang 行指定解释器的脚本,可以直接执行。这有一个前提条件,就是脚本需要有执行权限。可以使用下面的命令,赋予脚本执行权限。
5144

@@ -161,6 +154,8 @@ $ script.sh word1 word2 word3
161154

162155
如果脚本的参数多于9个,那么第10个参数可以用`${10}`的形式引用,以此类推。
163156

157+
注意,如果命令是`command -o foo bar`,那么`-o``$1``foo``$2``bar``$3`
158+
164159
下面是一个脚本内部读取命令行参数的例子。
165160

166161
```bash
@@ -198,6 +193,10 @@ done
198193

199194
上面例子中,`$@`返回一个全部参数的列表,然后使用`for`循环遍历。
200195

196+
## shift 命令
197+
198+
`shift`命令可以改变脚本参数,每次执行都会移除脚本当前的第一个参数(`$1`),使得后面的参数向前一位,即`$2`变成`$1``$3`变成`$2``$4`变成`$3`,以此类推。
199+
201200
`while`循环结合`shift`命令,也可以读取每一个参数。
202201

203202
```bash
@@ -206,13 +205,61 @@ done
206205
echo "一共输入了 $# 个参数"
207206

208207
while [ "$1" != "" ]; do
209-
echo "剩下 $# 个参数"
210-
echo "参数:$1"
211-
shift
208+
echo "剩下 $# 个参数"
209+
echo "参数:$1"
210+
shift
211+
done
212+
```
213+
214+
上面例子中,`shift`命令每次移除当前第一个参数,从而通过`while`循环遍历所有参数。
215+
216+
`shift`命令可以接受一个整数作为参数,指定所要移除的参数个数,默认为`1`
217+
218+
```bash
219+
shift 3
220+
```
221+
222+
上面的命令移除前三个参数,原来的`$4`变成`$1`
223+
224+
## getopts 命令
225+
226+
`getopts`命令用来解析复杂的命令行参数,通常与`while`循环一起使用,取出所有的带有前置连词线(`-`)的参数。
227+
228+
它带有两个参数。第一个参数是字符串,给出所有的连词线参数。如果该参数带有参数值,则后面必须带有一个冒号(`:`)。比如,某个命令可以有三个参数`-l``-h``-a`,其中只有`-a`可以带有参数值,那么`getopts`的第一个参数写成`lha:`,顺序不重要,注意`a`后面有一个冒号。`getopts`的第二个参数是一个变量名,用来保存参数。
229+
230+
下面是一个例子。
231+
232+
```bash
233+
while getopts 'lha:' OPTION; do
234+
case "$OPTION" in
235+
l)
236+
echo "linuxconfig"
237+
;;
238+
239+
h)
240+
echo "h stands for h"
241+
;;
242+
243+
a)
244+
avalue="$OPTARG"
245+
echo "The value provided is $OPTARG"
246+
;;
247+
?)
248+
echo "script usage: $(basename $0) [-l] [-h] [-a somevalue]" >&2
249+
exit 1
250+
;;
251+
esac
212252
done
253+
shift "$(($OPTIND - 1))"
213254
```
214255

215-
上面例子中,`shift`命令的作用是移除当前第一个参数,即`$2`变成`$1``$3`变成`$2``$4`变成`$3`,以此类推。
256+
上面例子中,`while`循环不断执行`getopts 'lha:' OPTION`命令,每次执行就会读取一个连词线参数(以及对应的参数值),然后进入循环体。变量`OPTION`保存的是,当前处理的那一个连词线参数(即`l``h``a`)。如果用户输入了没有指定的参数(比如`-x`),那么`OPTION`等于`?`。循环体内使用`case`判断,处理这四种不同的情况。
257+
258+
如果某个连词线参数带有参数值,比如`-a foo`,那么处理`a`参数的时候,变量`$OPTARG`保存的就是参数值。
259+
260+
注意,只要遇到不带连词线的参数,`getopts`就会执行失败,从而退出`while`循环。比如,`getopts`可以解析`command -l foo`,但不可以解析`command foo -l`。另外,多个连词线参数写在一起的形式,比如`command -lh``getopts`也可以正确处理。
261+
262+
变量`$OPTIND``getopts`开始执行前是`1`,然后每次执行就会加`1`。等到退出`while`循环,就意味着连词线参数全部处理完毕。这时,`$OPTIND - 1`就是已经处理的连词线参数个数,使用`shift`命令将这些参数移除,保证后面的代码可以用`$1``$2`等处理命令的主参数。
216263

217264
## 别名
218265

@@ -351,7 +398,7 @@ fi
351398

352399
## 命令执行结果
353400

354-
命令执行结束后,会有一个返回值。`0`表示执行成功,非`0`(通常是`1`)表示执行失败。
401+
命令执行结束后,会有一个返回值。`0`表示执行成功,非`0`(通常是`1`)表示执行失败。环境变量`$?`可以读取前一个命令的返回值。
355402

356403
利用这一点,可以在脚本中对命令执行结果进行判断。
357404

@@ -388,3 +435,7 @@ cd $some_directory && rm *
388435
cd $some_directory || exit 1
389436
```
390437

438+
## 参考链接
439+
440+
- [How to use getopts to parse a script options](https://linuxconfig.org/how-to-use-getopts-to-parse-a-script-options), Egidio Docile
441+

0 commit comments

Comments
 (0)