Bash入门教程
Posted 程序员爱学习
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bash入门教程相关的知识,希望对你有一定的参考价值。
shell的种类:
sh - Bourne shell
csh or tcsh - C shell
korn - Korn shell
bash - GNU Bourne-Again shell
1.最简单的列子
1例子
2#!/bin/bash
3# This is a very simple example echo Hello World
4echo Hello World
解释:
在 BASH 中 第一行的 "#!" 及后面的 "/bin/bash" 就表明该文件是一个 BASH 程序,需要由 /bin 目录下的 bash 程序来解释执行。
在 BASH 程序中从“#”号(注意:后面紧接着是“!”号的除外)开始到行尾的多有部分均被看作是程序的注释
echo 语句的功能是把 echo 后面的字符串输出到标准输出中去
执行该程序:
$ bash hello 或 $ sh hello
将 hello 文件改为可以执行的文件,然后直接运行它,此时由于 hello 文件第一行的 "#! /bin/bash" 的作用,系统会自动用/bin/bash 程序去解释执行 hello 文件的:
1$ chmod u+x hello
2$ ./hello
2.关于输入、输出和错误输出
在 Linux 系统中:
标准输入(stdin)默认为键盘输入;
标准输出(stdout)默认为屏幕输出;
标准错误输出(stderr)默认也是输出到屏幕(上面的 std 表示 standard)。
1$ ls > ls_result
2$ ls -l >> ls_result
ls 命令的结果输出 重定向到 ls_result 文件中和 追加到 ls_result 文件中,而不是输出到屏幕上。
">"就是输出(标准输出和标准错误输出)重定向的代表符号,连续两个 ">" 符号,即 ">>" 则表示不清除原来的而追加输出
1$ find /home -name lost* 2> err_result
这个命令在 ">" 符号之前多了一个 "2","2>" 表示将标准错误输出重定向。由于 /home 目录下有些目录由于权限限制不能访问,因此会产生一些标准错误输出被存放在 err_result 文件中
1$ find /home -name lost* > all_result 2>& 1
首先将标准错误输出也重定向到标准输出中,再将标准输出重定向到 all_result 这个文件中。这样我们就可以将所有的输出都存储到文件中了
更简单的写法:
1$ find /home -name lost* >& all_result
可以让你避开众多无用出错信息的干扰:
1$ find /home -name lost* 2> /dev/null
另外一个非常有用的重定向操作符是 "-"
1$ (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xvfp -)
该命令表示把 /source/directory 目录下的所有文件通过压缩和解压,快速的全部移动到 /dest/directory 目录下去
3.变量
1例子:
2#!/bin/bash
3# give the initialize value to
4STR STR="Hello World"
5echo $STR
注意点:
变量赋值时,'='左右两边都不能有空格;
BASH 中的语句结尾不需要分号(";");
除了在变量赋值和在FOR循环语句头中,BASH 中的变量使用必须在变量前加"$"符号,
由于 BASH 程序是在一个新的进程中运行的,所以该程序中的变量定义和赋值不会改变其他进程或原始 Shell 中同名变量的值,也不会影响他们的运行。
一个变量即可以被定义为一个字符串,也可以被再定义为整数。如果对该变量进行整数运算,他就被解释为整数;如果对他进行字符串操作,他就被看作为一个字符串
1例子:
2#!/bin/bash
3x=1999
4let "x = $x + 1"
5echo $x
6x="olympic'"$x
7echo $x
整数运算一般通过 let 和 expr 这两个指令来实现,如对变量 x 加 1 可以写作:
1let "x = $x + 1" 或者 x=`expr $x + 1`
BASH 中用于判断文件属性的操作符:
局部变量
在变量首次被赋初值时加上 local 关键字就可以声明一个局部变量
1例子:
2#!/bin/bash
3HELLO=Hello
4function hello {
5 local HELLO=World
6 echo $HELLO
7 }
8echo $HELLO
9hello
10echo $HELLO
11该程序的执行结果是:
12Hello
13World
14Hello
4.基本流程控制语法
1if...then...else
2if 语句用于判断和分支,其语法规则和 C 语言的 if 非常相似。其几种基本结构为:
3if [ expression ]
4then
5 statments
6fi
7或者==========================
8if [ expression ]
9then
10 statments
11else
12 statments
13fi
14或者==========================
15if [ expression ]
16then
17 statments
18else if [ expression ]
19 then
20 statments
21 else
22 statments
23fi
24或者==========================
25if [ expression ]
26then
27 statments
28elif [ expression ]
29then
30 statments
31else
32 statments
33fi
注:如果你将 if 和 then 简洁的写在一行里面,就必须在 then 前面加上分号,如:if [ expression ]; then …
for循环
1for $var in [list]
2do
3 statments
4done
注:do 和 for 被写在同一行,必须在 do 前面加上 ";"。如: for $var in [list]; do
1例子:
2#!/bin/bash
3for day in Sun Mon Tue Wed Thu Fri Sat
4do
5 echo $day
6done
如果列表被包含在一对双引号中,则被认为是一个元素
1例子:
2#!/bin/bash
3for day in “Sun Mon Tue Wed Thu Fri Sat “
4do
5 echo $day
6done
如果写成 for day 而没有后面的 in [list] 部分,则 day 将取遍命令行的所有参数
1例子:
2#!/bin/bash
3for param
4do
5 echo $param
6done
7exit 0
8while
9while [ condition ]
10do
11 statments
12done
13util
14until [ condition is TRUE ]
15do
16 statments
17done
18case
19case "$var" in
20 condition1 )
21 statments1;;
22 condition2 )
23 statments2;;
24 ...
25 * )
26 default statments;;
27esac
例子
1#!/bin/bash
2echo "Hit a key, then hit return."
3read Keypress
4case "$Keypress" in
5 [a-z] ) echo "Lowercase letter";;
6 [A-Z] ) echo "Uppercase letter";;
7 [0-9] ) echo "Digit";;
8 * ) echo "Punctuation, whitespace, or other";;
9esac
10exit 0
"read Keypress" 一句中的 read 语句表示从键盘上读取输入
支持break/continue
你懂得
5.函数
1function my_funcname {
2 code block
3}
4 或者
5my_funcname() {
6 code block
7}
BASH 中函数参数的定义并不需要在函数定义处就制定,而只需要在函数被调用时用 BASH 的保留变量 $1 $2 ...
来引用就可以了;
BASH 的返回值可以用 return 语句来指定返回一个特定的整数,如果没有 return 语句显式的返回一个返回值,则返回值就是该函数最后一条语句执行的结果(一般为 0,如果执行失败返回错误码)。
函数的返回值在调用该函数的程序体中通过 $? 保留字来获得。
1例子
2#!/bin/bash
3square() {
4 let "res = $1 * $1"
5 return $res
6}
7square $1
8result=$?
9echo $result
10exit 0
6.BASH 中的特殊保留字
保留变量$IFS
这个变量中保存了用于分割输入参数的分割字符,默认是空格。 $HOME
这个变量中存储了当前用户的根目录路径。 $PATH
这个变量中存储了当前 Shell 的默认路径字符串。 $PS1
表示第一个系统提示符。 $PS2
表示的二个系统提示符。 $PWD
表示当前工作路径。 $EDITOR
表示系统的默认编辑器名称。 $BASH
表示当前 Shell 的路径字符串。 $0, $1, $2, ...
表示系统传给脚本程序或脚本程序传给函数的第0个、第一个、第二个等参数。 $#
表示脚本程序的命令参数个数或函数的参数个数。 $$
表示该脚本程序的进程号,常用于生成文件名唯一的临时文件。 $?
表示脚本程序或函数的返回状态值,正常为 0,否则为非零的错误号。$*
表示所有的脚本参数或函数参数。 $@
和 $* 涵义相似,但是比 $* 更安全。 $!
表示最近一个在后台运行的进程的进程号。 $UID
用户uid $set |grep UID 获取
随机数 $RANDOM
:随机产生一个大小在 1 到 65536 之间的整数。
变量的特殊操作${var-default}
表示如果变量 $var 还没有设置,则保持 $var 没有设置的状态,并返回后面的默认值 default。 ${var=default}
表示如果变量 $var 还没有设置,则取后面的默认值 default。 ${var+otherwise}
表示如果变量 $var 已经设置,则返回 otherwise 的值,否则返回空( null )。 ${var?err_msg}
表示如果变量 $var 已经设置,则返回该变量的值,否则将后面的 err_msg 输出到标准错误输出上。
这些用法主要用于从文件路径字符串中提取有用信息:
${var#pattern}, ${var##pattern}
用于从变量 $var 中剥去最短(最长)的和 pattern 相匹配的最左侧的串。 ${var%pattern}, ${var%%pattern}
用于从变量 $var 中剥去最短(最长)的和 pattern 相匹配的最右侧的串。
另外 BASH 2 中还加入下面一些操作:
${var:pos}
表示去掉变量 $var 中前 pos 个字符。 ${var:pos:len}
表示变量 $var 中去掉前 pos 个字符后的剩余字符串的前 len 个字符。 ${var/pattern/replacement}
表示将变量 $var 中第一个出现的 pattern 模式替换为 replacement 字符串。 ${var//pattern/replacement}
表示将变量 $var 中出现的所有 pattern 模式全部都替换为 replacment 字符串。
7.BASH 中的其他高级问题
BASH 中对返回值的处理
无论是在 Shell 中对 BASH 脚本返回值的处理,还是在脚本中对函数返回值的处理,都是通过 "$?" 系统变量来获得。
BASH 要求返回值必须为一个整数,不能用 return 语句返回字符串变量
用 BASH 设计简单用户界面
1select var in [list]
2do
3 statments use $var
4done
BASH 会将 [list] 中的所有项加上数字列在屏幕上等待用户选择,在用户作出选择后,变量 $var 中就包含了那个被选中的字符串
1例子
2#!/bin/bash
3OPTIONS="Hello Quit"
4select opt in $OPTIONS; do
5 if [ "$opt" = "Quit" ]; then
6 echo done
7 exit
8 elif [ "$opt" = "Hello" ]; then
9 echo Hello World
10 else
11 clear
12 echo bad option
13 fi
14done
15exit 0
BASH 程序的调试
用 bash -x bash-script 命令,可以查看一个出错的 BASH 脚本到底错在什么地方,可以帮助程序员找出脚本中的错误。
另外用 trap 语句可以在 BASH 脚本出错退出时打印出一些变量的值,以供程序员检查。
trap 语句必须作为继 "#!/bin/bash" 后的第一句非注释代码,一般 trap 命令被写作:
1trap 'message $checkvar1 $checkvar2' EXIT
以上是关于Bash入门教程的主要内容,如果未能解决你的问题,请参考以下文章