Linux开发基础:Shell编程入门(一)

来源:互联网 发布:毕业生自我鉴定知乎 编辑:程序博客网 时间:2024/06/05 09:19

转载至:http://blog.csdn.net/lovehuangjiaju/article/details/48827923


本节主要内容

  1. shell编程简介
  2. 变量定义
  3. 常用特殊变量

1. shell编程简介

学习Linux操作系统最让人着迷的事情莫过于shell脚本编程,这是因为如果要完成某些复杂的功能,单纯地通过GUI操作不可能达到,shell脚本可以直接与操作系统内核打交道,从而完成任意复杂的任务。shell有很多种,最常用的是Bash (Bourne Again Shell),它是Linux操作系统默认的shell环境。

在linux环境中,需要区分一下root用户与一般用户的命令行显示:

//root用户与一般用户显示有一些差异//root用户命令行以#结尾root@sparkmaster:~# su zhouzhihu//一般用户命令行以$符号结尾zhouzhihu@sparkmaster:/root$ exitexitroot@sparkmaster:~# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如下图: 
这里写图片描述

现在让我们来编写第一个shell程序吧

root@sparkmaster:~/ShellLearning/chapter09# vi HelloWorld.sh 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

这里写图片描述 
就两行内容:

#!/bin/bashecho "Hello Shell"
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

那完成后如果执行shell脚本程序呢?有两种方式,一种是通过sh命令,另外一种是自执行方式。下面给出了具体演示

//完成后直接利用sh命令执行root@sparkmaster:~/ShellLearning/chapter09# sh HelloWorld.sh Hello Shell//自执行(self execute)方式,由于没有给文件加执行权限,所以执行失败root@sparkmaster:~/ShellLearning/chapter09# ./HelloWorld.shbash: ./HelloWorld.sh: Permission deniedroot@sparkmaster:~/ShellLearning/chapter09# ls -ltotal 4-rw-r--r-- 1 root root 31 2015-09-30 06:29 HelloWorld.sh//chmod给文件加执行权限root@sparkmaster:~/ShellLearning/chapter09# chmod a+x HelloWorld.sh //再通过自执行方式root@sparkmaster:~/ShellLearning/chapter09# ./HelloWorld.shHello Shellroot@sparkmaster:~/ShellLearning/chapter09# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

前面提到,脚本第一行是#!/bin/bash,它的作用是提示该脚本的执行路径是/bin/bash,对自执行方式有用,自执行方式最终是通过/bin/bash HelloWorld.sh 执行脚本,而利用sh HelloWorld.sh命令执行脚本时,#!/bin/bash 不起作用。

HelloWorld.sh文件中的echo “Hello Shell”是一条语句,一般习惯于一行一条语句,如:

#!/bin/bashecho "Hello Shell"echo "Hello World"
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

如果要将上述语句放在一行,则需要用;隔开

echo "Hello Shell";echo "Hello World"
  • 1
  • 1

echo命令用于输出一行内容(包括行符),后面的输出内容除可以用”“双引号之外,也可以不加,也可以用单引号”例如:

root@sparkmaster:~/ShellLearning/chapter09# echo "Hello World"Hello Worldroot@sparkmaster:~/ShellLearning/chapter09# echo Hello WorldHello Worldroot@sparkmaster:~/ShellLearning/chapter09# echo 'Hello World'Hello World
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这三种方式看上去似乎相同,但其实它们之间还是有差异的,具体如下:

//对于一些特殊字符,双引号可能不会正常输出root@sparkmaster:~/ShellLearning/chapter09# echo "Hello World!"bash: !": event not found//不带引号的参数不会出现这种情况root@sparkmaster:~/ShellLearning/chapter09# echo 'Hello World!'Hello World!//单引号也能正常输出root@sparkmaster:~/ShellLearning/chapter09# echo Hello World!Hello World!//不带引号的参数使用如果带特殊字符,两条语句不能放在同一行root@sparkmaster:~/ShellLearning/chapter09# echo Hello World!;echo Hellobash: !: event not found//不带引号,输出的是变量内容root@sparkmaster:~/ShellLearning/chapter09# echo $JAVA_HOME/hadoopLearning/jdk1.7.0_67//双引号,输出的也是变量内容root@sparkmaster:~/ShellLearning/chapter09# echo "$JAVA_HOME"/hadoopLearning/jdk1.7.0_67//单引号的话,内容原样输出,不会解析变量值root@sparkmaster:~/ShellLearning/chapter09# echo '$JAVA_HOME'$JAVA_HOME
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

2. 变量定义

前一小节提到$JAVA_HOME,这是配置的Java环境变量,这一小节我们将介绍如何进行变量定义,如何配置环境变量。同任何的编程语言一样,变量是用来存储可变数据的,即在程序运行过程中变量中的数据可能随时发生变化。shell脚本中的变量同其它脚本语言一样,在使用时不需要进行类型定义,不管是加引号还是不加引号定义变量,其类型都为String,例如:

//t1为String类型root@sparkmaster:~/ShellLearning/chapter09# t1="123"root@sparkmaster:~/ShellLearning/chapter09# $t1123: command not foundroot@sparkmaster:~/ShellLearning/chapter09# echo $t1//t1为String类型root@sparkmaster:~/ShellLearning/chapter09# t1=123root@sparkmaster:~/ShellLearning/chapter09# echo $t1123
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

上面的变量是我们自己定义的,它具有一定的局部性,例如:

root@sparkmaster:~/ShellLearning/chapter09# t1=123//在当前进程中能够正常输出内容root@sparkmaster:~/ShellLearning/chapter09# echo $t1123//开启一个子进程root@sparkmaster:~/ShellLearning/chapter09# bash//无内容输出root@sparkmaster:~/ShellLearning/chapter09# echo $t1//退出,返回原父进程root@sparkmaster:~/ShellLearning/chapter09# exitexit//内容又能够正常输出root@sparkmaster:~/ShellLearning/chapter09# echo $t1123
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

从上面的代码可以看到,自定义变量具有只能在当前进程中使用,当开启子进程时,变量在子进程中不起作用,如果需要父进程中定义的变量在子进程中也能够使用,则需要将其设置为环境变量,环境变量使用export命令进行定义,代码如下:

//采用export命令将t1设置为环境变量root@sparkmaster:~/ShellLearning/chapter09# export t1root@sparkmaster:~/ShellLearning/chapter09# bash//子进程中现在可能使用root@sparkmaster:~/ShellLearning/chapter09# $t1123: command not foundroot@sparkmaster:~/ShellLearning/chapter09# echo $t1123
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

不过,这样定义的环境变量,在命令行窗口关闭或系统重新启动时会丢失,如果需要在机器启动时环境变量就自动生效的话,可以将环境变量定义在~/.bashrc或/etc/profile文件中,其中~/.bashrc只对当前用户(例如当前用户是zhouzhihu,则只对本用户有效),如果想对所有用户都有效,则将其放置在/etc/profile文件中。 
下图给出了java、Scala语言等环境变量配置演示: 
这里写图片描述

3. 常用特殊变量

在linux脚本编程中,有几个非常重要的特殊变量,说它特殊是因为它变量无需程序员自己定义,系统默认会帮我们进行初始化等相关操作,常用特殊变量如下:

$# 是传给脚本的参数个数$0 是脚本本身的名字$1 是传递给该shell脚本的第一个参数$2 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9$$ 是脚本运行的当前进程ID$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

下面我们举例进行演示:

root@sparkmaster:~/ShellLearning/chapter09# vi SpecialVariable.sh
  • 1
  • 1

这里写图片描述 
root@sparkmaster:~/ShellLearning/chapter09# ./SpecialVariable.sh 1 2 3 4 

./SpecialVariable.sh 


1 2 3 4 
1 2 3 4 
17138 
0

0 0