Shell基础

来源:互联网 发布:解决sql挂起 编辑:程序博客网 时间:2024/06/05 20:05

一、Shell中的变量

  任何编程语言中,有关变量的定义,作用范围,赋值等都是最最基础的知识。

0、默认变量

  首先介绍几个shell中的默认变量。 
  

变量含义$0当前脚本名称$1脚本接收的第一个参数$2脚本接收的第二个参数$#脚本接收的所有参数个数$@脚本接收的所有参数$*脚本接收的所有参数$?前一行命令的执行状态

  示例如下:

hadoop@client:~$ bash default_var.sh a b c d$0 ==>  default_var.sh$1 ==>  a$2 ==>  b$# ==>  4$@ ==>  a b c d$* ==>  a b c d$? ==>  0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

1、变量定义及赋值

hadoop@client:~$ v1=hellohadoop@client:~$ echo $v1hello
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  但是要注意的是,赋值处必须为一个整体,不能有空格。

hadoop@client:~$ v2=hello worldNo command 'world' found, did you mean: Command 'tworld' from package 'tworld' (universe)world: command not found
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  想要包含空格,需要用单引号或双引号包围,如

hadoop@client:~$ v2="hello world"hadoop@client:~$ echo $v2hello worldhadoop@client:~$ v3='hello world'hadoop@client:~$ echo $v3hello world
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、单引号(')和双引号(")的区别

  上面的示例中看到hello world使用单引号或双引号包围再赋值给变量时,两者效果相同,但是其中的区别在哪里?

hadoop@client:~$ a="hello"hadoop@client:~$ b="$a world"hadoop@client:~$ echo $bhello worldhadoop@client:~$ c='$a world'hadoop@client:~$ echo $c$a world
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  可以看到,单引号中的$a保持原样输出。而双引号中的$a会替换成其变量值。

3、`符号

  这个符号在数字键1的左侧,与单引号很类似。但是其功能与单引号双引号都有不同。在该符号中的命令会被执行。

hadoop@client:~$ d=`date`hadoop@client:~$ echo $dWed Dec 28 06:31:13 PST 2016
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  如果不想使用这个符号,可以用$()替换

hadoop@client:~$ e=$(date)hadoop@client:~$ echo $eWed Dec 28 06:31:48 PST 2016
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

4、命令行交互read

  有时候我们希望在脚本运行时能根据用户的输入决定脚本后续执行逻辑,比如在安装插件的时候经常会让用户选择输入[N/Y]的时候。 
  比如有一个脚本script_test.sh

read -p "Please input [Y/N]: " ynif [ "$yn" == "N" -o "$yn" == "n" ]; then  echo "NO"elif [ "$yn" == "Y" -o "$yn" == "y" ]; then  echo "YES"fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  在运行时根据用户的输入决定if分支的走向。运行结果如下

hadoop@client:~$ sh script_test.shPlease input [Y/N]: yYES
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  read命令的使用形式为

read [-pt] variable  参数p:后面可以接提示符  参数t:后面可以接秒数
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  例如,

read -p "please input your name" -t 5 name
  • 1
  • 1

  表示将输入内容赋值给变量name,用户有5秒钟的输入时间。

5、定义变量类型declare

  默认情况下,变量的赋值内容都是字符类型的。例如下面的代码,我们期望的是输出一个求和值,但是输出的是一个求和表达式。

hadoop@client:~$ sum=100+300+500hadoop@client:~$ echo $sum100+300+500
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  如果想要输出求和后的值,可以使用declare命令。

hadoop@client:~$ declare -i sum=100+300+500hadoop@client:~$ echo $sum900
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  declare命令的使用形式如下:

declare [-aixr] variable  参数a:将variable定义为数组  参数i:将variable定义为整型(integer)  参数x:将variable设置成环境变量,类似于export的作用  参数r:variable为readonly类型,值不能被更改
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

二、Shell中的集合类型

1、数组(array)

(1)数组定义和赋值

  数组中的元素用括号包围,各元素之间用空格隔开。例如

hadoop@client:~$ array_name=(v0 v1 v2 v3)
  • 1
  • 1

  
  可以重新设置指定元素的内容,如下所示

hadoop@client:~$ array_name[2]=v22hadoop@client:~$ echo ${array_name[2]}v22
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

   
(2)数组元素访问

  输出该数组中所有元素:

hadoop@client:~$ echo ${array_name[*]}v0 v1 v22 v3hadoop@client:~$ echo ${array_name[@]}v0 v1 v22 v3
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  数组元素下标从0开始,想要访问指定位置的元素,使用[]指定下标值,如下所示

hadoop@client:~$ echo ${array_name[0]}v0hadoop@client:~$ echo ${array_name[1]}v1hadoop@client:~$ echo ${array_name[3]}v3hadoop@client:~$ echo ${array_name[2]}v2hadoop@client:~$ echo ${array_name[4]}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

  
(3)获取数组长度

  获取数组长度使用如下命令

hadoop@client:~$ echo ${#array_name[@]}4hadoop@client:~$ echo ${#array_name[*]}4
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  获取数组中单个元素的长度使用如下命令

hadoop@client:~$ echo ${#array_name[2]}3
  • 1
  • 2
  • 1
  • 2

2、map

  map类型中存储的都是键值对。 
  在Shell中定义map变量如下所示:

declare -A m=(["a"]="1" ["b"]="2")
  • 1
  • 1

  输出所有的key

hadoop@client:~$ echo ${!m[@]}a b
  • 1
  • 2
  • 1
  • 2

  输出所有的value

hadoop@client:~$ echo ${m[@]}1 2
  • 1
  • 2
  • 1
  • 2

  输出指定key对应的value

hadoop@client:~$ echo ${m["a"]}1hadoop@client:~$ echo ${m["c"]}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  添加元素

hadoop@client:~$ m["c"]="3"hadoop@client:~$ echo ${m["c"]}3
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  map中键值对的个数

hadoop@client:~$ echo ${#m[@]}3
  • 1
  • 2
  • 1
  • 2

三、Shell中的字符操作

  在任何语言中对字符串的操作都是非常频繁的。字符串的操作主要包括,字符串截取,字符串替换等。 
  接下来的示例中,都以字符串http://blog.csdn.NET/dabokele作为初始字符串。

str="http://blog.csdn.net/dabokele"
  • 1
  • 1

1、字符串删除

  删除前面的http://

hadoop@client:~$ echo ${str#http://}blog.csdn.net/dabokele
  • 1
  • 2
  • 1
  • 2

  删除后面的dabokele

hadoop@client:~$ echo ${str%/dabokele}http://blog.csdn.net
  • 1
  • 2
  • 1
  • 2

  #从前往后截取,%从后往前截取。

  示例中表示将符合的最短数据删除,如果使用两个#,或者两个%,则表示将符合的最长数据删除。

  如下所示,匹配最短时,会将https://csdn.ne删除,匹配最长时,会将全部字符删除。

hadoop@client:~$ echo ${str#http://b*e}t/dabokelehadoop@client:~$ echo ${str##http://b*e}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2、字符串截取

  可以从字符串的指定位置开始截取,同时可以指定截取的位数,如下所示:

hadoop@client:~$ echo ${str:2}     // 从第二位开始截取到最末尾,第一个字符下标为0tp://blog.csdn.net/dabokelehadoop@client:~$ echo ${str:2:3}     // 从第二位开始顺序截取三个字符tp:hadoop@client:~$ echo ${str:(-6):3}     // 从倒数第六位开始,截取三个字符,最后一个字符下标为-1bok
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3、字符串替换

  将http替换成HTTP

hadoop@client:~$ echo ${str/http/HTTP}HTTP://blog.csdn.net/dabokele
  • 1
  • 2
  • 1
  • 2
  • 使用一个斜杠(/)表示只替换第一个遇到的字符。
  • 使用两个斜杠(//)则表示替换全部符合的字符。
  • 使用#匹配以指定字符开头的字符串。
  • 使用%匹配以指定字符开头的字符串。
hadoop@client:~$ echo ${str/e/E}http://blog.csdn.nEt/dabokelehadoop@client:~$ echo ${str//e/E}http://blog.csdn.nEt/dabokElEhadoop@client:~$ echo ${str/#h/H}     // 匹配开头的那个hHttp://blog.csdn.net/dabokelehadoop@client:~$ echo ${str/e/E}http://blog.csdn.nEt/dabokelehadoop@client:~$ echo ${str/%e/E}     // 匹配最后那个E,前一个匹配中匹配的是net中的ehttp://blog.csdn.net/dabokelE
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4、字符串默认值

  假设以下这个场景,如果变量name没有赋过值,则给一个默认值default,否则使用指定的值。

hadoop@client:~$ echo $namehadoop@client:~$ echo ${name-default}defaulthadoop@client:~$ name="ckm"hadoop@client:~$ echo ${name-default}ckm
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  但是,如果已经将变量name设置成“”,则结果如下:

hadoop@client:~$ name=""hadoop@client:~$ echo ${name-default}
  • 1
  • 2
  • 1
  • 2

  如果变量内容为“”或者变量未初始化则给默认值,可以在-前加个冒号,使用:-

hadoop@client:~$ name=""hadoop@client:~$ echo ${name-default}hadoop@client:~$ echo ${name:-default}default
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

5、字符串拼接

  字符串拼接如下所示

hadoop@client:~$ echo "aaa""bbb"aaabbbhadoop@client:~$ echo "aaa"$straaahttp://blog.csdn.net/dabokelehadoop@client:~$ echo "aaa$str"aaahttp://blog.csdn.net/dabokele
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

6、字符串长度

  求字符串长度用#操作,如下所示

hadoop@client:~$ echo ${#str}29
  • 1
  • 2
  • 1
  • 2

7、字符串split成数组

  在以空格为分隔符分割字符串成数组时操作最简单。

hadoop@client:~$ s="a b c d e"hadoop@client:~$ a=($s)hadoop@client:~$ echo ${a[*]}a b c d ehadoop@client:~$ echo ${a[2]}c
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  所以,如果需要指定特定字符进行分割,而原字符串中又没有空格时,可以先将特定字符替换成空格,然后按照上述进行分割,如下所示,

hadoop@client:~$ s="a,b,c,d,e"hadoop@client:~$ a=(${s//,/ })hadoop@client:~$ echo ${a[*]}a b c d ehadoop@client:~$ echo ${a[2]}c
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  如果字符串中本身已有空格,并且期望的分隔符不是空格,按如下方法进行分割。首先将IFS变量替换成指定字符,分割后再将IFS更新为原字符。

hadoop@client:~$ s="a b,c,d,e"hadoop@client:~$ old_ifs="$IFS"hadoop@client:~$ s="a b,c,d,e"hadoop@client:~$ OLD_IFS="$IFS"hadoop@client:~$ IFS=","hadoop@client:~$ a=($s)hadoop@client:~$ IFS="$OLD_IFS"hadoop@client:~$ echo ${a[*]}a b c d ehadoop@client:~$ echo ${a[0]}a bhadoop@client:~$ echo ${#a[*]}4
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

8、字符串包含

  有时候需要判断字符串str1中是否包含字符串str2,使用=~操作符。 
  

str1="hello"str2="ell"if [[ $str1 =~ $str2 ]];then echo "$str1 contains $str2"fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

  查看运行结果 
  

hadoop@client~$ sh script_test.sh hello contains ell
  • 1
  • 2
  • 1
  • 2

四、Shell中的控制结构

0、循环接收脚本参数shift

  测试脚本如下:

echo '原始参数: ' $*shiftecho 'shift后参数: ' $*shift 2echo 'shift 2后参数: ' $*
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

  查看脚本运行结果

hadoop@client:~$ sh script_test.sh a b c d e f g原始参数:  a b c d e f gshift后参数:  b c d e f g     // 移除第一个参数ashift 2后参数:  d e f g     // 继续移除前两个参数b和c
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

1、条件表达式

(1)if … then 
  判断表达式是经常用到的。整体结构如下所示,其中iffi是必须的,中间的elifelse是可选的。

if [ 判断条件1 ]; then  执行内容1elif [ 判断条件2 ]; then  执行内容2else  执行内容3fi
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

   
a)算术运算符

  算术运算符的使用格式如下

a=10b=20val=expr $a + $b
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  常用的算术运算符包括

运算符说明举例+加法expr $a + $b 结果为 30。-减法expr $a - $b 结果为 10。*乘法expr $a \* $b 结果为 200。/除法expr $b / $a 结果为 2。%取余expr $b % $a 结果为 0。=赋值a=$b将把变量 b 的值赋给 a。==相等用于比较两个数字,相同则返回 true。[ $a == $b ] 返回 false。!=不相等用于比较两个数字,不相同则返回 true。[ $a != $b ] 返回 true。

   
b)关系运算符 
  关系运算符的使用格式如下

a=10b=20$a -eq $b
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

  常用的关系运算符包括

运算符说明举例-eq检测两个数是否相等,相等返回 true。[ $a -eq $b ] 返回 true。-ne检测两个数是否相等,不相等返回 true。[ $a -ne $b ] 返回 true。-gt检测左边的数是否大于右边的,如果是,则返回 true。[ $a -gt $b ] 返回 false。-lt检测左边的数是否小于右边的,如果是,则返回 true。[ $a -lt $b ] 返回 true。-ge检测左边的数是否大等于右边的,如果是,则返回 true。[ $a -ge $b ] 返回 false。-le检测左边的数是否小于等于右边的,如果是,则返回 true。[ $a -le $b ] 返回 true。

   
c)布尔运算符 
  常用的布尔运算符如下

运算符说明举例!非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。-o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ] 返回 true。-a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。

   
d)字符串运算符 
  常用的字符串运算符如下

运算符说明举例=检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。!=检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回 true。-z检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。-n检测字符串长度是否为0,不为0返回 true。[ -n $a ] 返回 true。str检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。

   
e)文件测试运算符 
  常用的文件测试运算符如下

运算符说明举例-b file检测文件是否是块设备文件,如果是,则返回 true。[ -b $file ] 返回 false。-c file检测文件是否是字符设备文件,如果是,则返回 true。[ -b $file ] 返回 false。-d file检测文件是否是目录,如果是,则返回 true。[ -d $file ] 返回 false。-f file检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。[ -f $file ] 返回 true。-g file检测文件是否设置了 SGID 位,如果是,则返回 true。[ -g $file ] 返回 false。-k file检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。[ -k $file ] 返回 false。-p file检测文件是否是具名管道,如果是,则返回 true。[ -p $file ] 返回 false。-u file检测文件是否设置了 SUID 位,如果是,则返回 true。[ -u $file ] 返回 false。-r file检测文件是否可读,如果是,则返回 true。[ -r $file ] 返回 true。-w file检测文件是否可写,如果是,则返回 true。[ -w $file ] 返回 true。-x file检测文件是否可执行,如果是,则返回 true。[ -x $file ] 返回 true。-s file检测文件是否为空(文件大小是否大于0),不为空返回 true。[ -s $file ] 返回 true。-e file检测文件(包括目录)是否存在,如果是,则返回 true。[ -e $file ] 返回 true。

   
(2)case … esac 
  case表达式的使用格式如下

case $变量 in  "内容1")      程序1  ;;  "内容2")      程序2  ;;  *)     #匹配其他所有情况      程序3  ;;esac
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

  看一个示例,如果第一个参数为hello,则打印hello world。如果第一个参数是bye,则打印bye bye。如果是另外的情况,则输出该参数。

case $$1 in  "hello")      echo "hello world"  ;;  "bye")      echo "bye bye"  ;;  "*")      echo $1  ;;esac
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

  运行结果

hadoop@client:~$ sh script_test.sh hellohello worldhadoop@client:~$ sh script_test.sh byebye byehadoop@client:~$ sh script_test.sh hehehehe
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、循环表达式

(1)while do done, untile do done 
  while循环的格式如下

while [ condition ]do  程序done
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  与while循环相反的是until循环。

while [ condition ]do  程序done
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  在while循环中,当条件满足使,就执行其中的程序。而until循环中,当条件不成立时就终止循环。

  下面举例用两种循环来实现当输入为yes时跳出循环。 
   
a) while循环示例如下

while [ "$yn" != "yes" ]do  read -p "Please input yes to stop: " yndoneecho "Stop!"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  运行结果

hadoop@client:~$ sh script_test.shPlease input yes to stop: noPlease input yes to stop: noPlease input yes to stop: yesStop!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

   
b) until循环示例如下

until [ "$yn" == "yes" ]do  read -p "Please input yes to stop: " yndoneecho "Stop!"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

  运行结果如下

hadoop@client:~$ sh script_test.shPlease input yes to stop: noPlease input yes to stop: yesStop!
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

   
(2)for … do … done 
  for循环的格式如下

for var in con1 con2 con3 ...do  程序done
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  下面这个示例循环打印输入参数列表

for arg in $*do  echo $argdone
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  运行结果如下

hadoop@client:~$ sh script_test.sh a b c d eabcde
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

   
(3)for … do … done的另一种形式 
  for循环的另一种个数如下

for ((初始值; 目标值; 步长))do  程序done
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  循环输出110中的奇数

for ((i=1; i<=10; i=i+2))do  echo $idone
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

  运行结果如下

hadoop@client:~$ bash script_test.sh13579
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

五、Shell中的函数

  在Shell中也可以像其他编程语言那样,将代码块封装成函数。Shell中的函数,需要注意以下两点: 
  

1、函数定义

  由于Shell是从上往下执行的,所以在定义函数之前就调用该函数的话,会提示command not found,例如 
  

echo "Before :" `printFunc`function printFunc() {  echo "print function !"}echo "After :" `printFunc`
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  运行结果如下,前一个函数调用处提示command not found  

hadoop@client:~$ sh script_test.sh 2_script_test.sh: line 3: printFunc: command not foundBefore :After : print function !
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2、函数参数与shell参数

  在Shell中定义的函数,是可以传递和接收参数的。在子函数中,$1表示接收的第一个参数…,这里需要注意与shell参数的区别。 
  但是测试后发现$0表示的仍然是shell名称。如果想要显示当前函数名,可以使用$FUNCNAME参数,如下所示,  

function printStr() {  echo "printStr function print: $FUNCNAME"  echo "printStr function print: $*"}echo "main print: $0"echo "main print: $*"printStr f1 f2 f3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

  运行结果如下,

[hadoop@client ~]$ sh script_test.sh m1 m2 m3shell name : script_test.shshell params : m1 m2 m3function name : printStrfunction params : f1 f2 f3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

六、vi快捷操作

  下面操作中出现大写字母,比如G表示需要同时按住ShiftG键。n表示输入的数字。其他比如text则表示字符串。

1、跳转

按键说明gg跳转到第一行G跳转到最后一行ngg / nG跳转到最后一行Ctrl+f向下翻页Ctrl+b向上翻页h光标左移j光标下移k光标上移l光标右移w移到下一个单词的开头W移到下一个单词的开头,忽略标点b移到上一个单词的开头B移到上一个单词的开头,忽略标点e移到下一个单词的末尾E移到下一个单词的末尾,忽略标点nw/nW/nb/nB跳转n个单词L移到当前屏幕最后一行M移到当前屏幕中间行$到当前行最后一个字符^到当前行第一个字符0到当前行第一个字符n (到句子开头)到句子结尾{到段落开头}到段落结尾

2、查找和替换

(1)查找

按键说明/text向后查找text字符?text向前查找text字符n跳转至下一个text字符N跳转至上一个text字符:set ic查找时忽略大小写:set noic查找时对大小写敏感

(2)替换

按键说明:s/oldtext/newtext/替换当前行第一个oldtext为newtext:s/oldtext/newtext/g替换当前行所有oldtext为newtext:m,ns/oldtext/newtext/在m行到n,用newtext替换第一个oldtext:1,$s/oldtext/newtext/在1行到最后一行,用newtext替换第一个oldtext:m,ns/oldtext/newtext/g在m行到n,用newtext替换oldtext:1,$s/oldtext/newtext/g在1行到最后一行,用newtext替换oldtext

  在最后输入一个(confirm),表示替换前弹出确认提示。按y则逐一替换当前光标处匹配的字符,n则跳过当前光标处字符,a替换全部匹配的字符。

3、复制、删除、撤销、重复

(1) 复制

按键说明yy复制当前行nyy复制当前及向下n行p将复制内容黏贴到下一行P将复制内容黏贴到上一行

  另外,输入y+跳转中的操作,可以为复制指定方向。比如yw,从当前位置复制到下一个单词的开头。这样可以进行复制一个单词的操作。

(2)删除

按键说明dd删除当前行(按p可黏贴)ndd从当前行向下删除n行dG从当前行删除到最后一行dgg从当前行删除到第一行:n,md从第n行删除到第m行x删除当前字符nx删除当前向后n个字符X删除光标前的字符nx删除当前向前n个字符

  另外,输入d+跳转中的操作,可以为删除指定方向。比如dw,从当前位置删除至下一个单词的开头。

(3)撤销

按键说明u撤销上一次操作U撤销当前行所有操作.重复最后一次操作

(4)重复

按键说明.重复最后一次操作

4、其他

按键说明J将下一行连接到本行末尾nJ将下n行连接到本行末尾~将当前字符切换大小写n~将当前向后n个字符切换大小写~将当前字符切换大小写g~~切换当前行大小写u列编辑模式下,选中列转换成小写U列编辑模式下,选中列转换成大写guu当前行转换成小写gUU当前行转换成大写guw当前单词转换成小写gUw当前单词转换成大写

5、列编辑

  按Ctrl + v,进入列编辑模式。 
   
(1)删除列 
  进入列编辑模式, 
  移动光标,选中需要删除的列, 
  按d,则会删除选中内容。

(2)插入列 
  进入列编辑模式, 
  移动光标选中需要插入内容的列。 
  按shift + i,会在选中列的第一行输入想要插入的内容。 
  连续按两次ESC,则会在选中的列处全部插入输入字符。

2
 
原创粉丝点击