1. Shell入门
- Shell 编程跟 java、PHP 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
- Linux 的 Shell 种类众多,本教程关注的是 Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。
- Shell编程的实质就是将Shell命令添加到脚本文件中吧。并通过命令执行Shell命令。
开发步骤如下:
如下定义了hello.sh文件:
#!/bin/bash ##表示用哪一种解析器来解析执行我们的脚本程序 echo "Hello world"
执行脚本
sh hello.sh ##或者如下:凡是执行命令,系统都会先在Path环境变量里面找,如果找不到,再从下面的指定路径中找 ./hello.sh
如果不是管理员登录,可能对该文件没有执行权限,应该修改脚本执行权限
chmod 755 hello.sh ./hello.sh
2. 变量定义
变量又称为系统变量和自定义变量。所谓的系统变量,则是在系统启动的时候就定义的了,系统变量可以通过set命令查找。如下:
[hadoop@mini shell]$ set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="1" [2]="2" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.1.2(1)-release'
COLORS=/etc/DIR_COLORS
COLUMNS=112
DIRSTACK=()
EUID=500
GROUPS=()
G_BROKEN_FILENAMES=1
HISTCONTROL=ignoredups
HISTFILE=/home/hadoop/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000
HOME=/home/hadoop
HOSTNAME=mini
HOSTTYPE=x86_64
IFS=$' \t\n'
LANG=en_US.UTF-8
LESSOPEN='||/usr/bin/lesspipe.sh %s'
LINES=38
LOGNAME=hadoop
LS_COLORS= ... ##太多了 忽略掉。。。
MACHTYPE=x86_64-redhat-linux-gnu
MAIL=/var/spool/mail/hadoop
MAILCHECK=60
OLDPWD=/home/hadoop
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hadoop/bin
PIPESTATUS=([0]="0")
PPID=3893
PS1='[\u@\h \W]\$ '
PS2='> '
PS4='+ '
PWD=/home/hadoop/shell
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
SELINUX_USE_CURRENT_RANGE=
SHELL=/bin/bash
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
SHLVL=1
SSH_CLIENT='192.168.254.1 54236 22'
SSH_CONNECTION='192.168.254.1 54236 192.168.254.128 22'
SSH_TTY=/dev/pts/0
TERM=vt100
UID=500
USER=hadoop
_=clear
colors=/etc/DIR_COLORS
上面的代码中我们可以看到熟悉的变量,如BASH,PWD,USER 等等,接下来我们可以在客户端直接使用该命令:
[hadoop@mini shell]$ set | grep PWD
OLDPWD=/home/hadoop
PWD=/home/hadoop/shell
[hadoop@mini shell]$ cd ..
[hadoop@mini ~]$ set | grep PWD
OLDPWD=/home/hadoop/shell
PWD=/home/hadoop
自定义变量的读写如下,这里需要注意的是,不同的ssh客户端下,自定义变量是无法共享的,并且在声明变量的时候等号前后不能出现空格,值的使用最好加上双引号,这样可以防止值的内容出现空格造成不必要的麻烦:
[root@mini ~]# hero=luban
[root@mini ~]# echo $hero
luban
[root@mini ~]# str="hello world"
[root@mini ~]# echo $str
hello world
#当取变量的时候发现字符串连在一起:
[root@mini ~]# people=aidisheng
[root@mini ~]# echo "aidisheng's food"
aidisheng's food [root@mini ~]# echo "${people}'s food" aidisheng's food #对于变量的删除 可以使用unset命令 [root@mini ~]# unset people [root@mini ~]# echo "${people}'s food" 's food
#普通的变量是允许修改的,而声明了readonly的变量是不允许修改的
[root@mini ~]# helloworld="hello world"
[root@mini ~]# helloworld="hello world2"
[root@mini ~]# unset helloworld
[root@mini ~]# readonly helloworld="hello world"
[root@mini ~]# helloworld="hello world2"
-bash: helloworld: readonly variable
export: 可以将当前变量修改为本进程的变量,并允许子进程使用(不包括父进程),如下:
[hadoop@mini shell]$ vi a.sh
#!/bin/bash
a=aaaaaa
echo "a=$a"
./b.sh
[hadoop@mini shell]$ vi b.sh
#!/bin/bash
echo "b file--->a=$a"
[hadoop@mini shell]$ ./a.sh
a=aaaaaa
b file--->a=
source: 将当前某个sh文件放到当前进程中运行,也可以使用 . 来代替,如下代码,因为b.sh运行啊a.sh所在的进程里面,当然可以访问a变量的值:
[hadoop@mini shell]$ vi a.sh
#!/bin/bash
a=aaaaaa
echo "a=$a"
source ./b.sh
3. 变量的操作
将一个命令的结果赋给某个变量
[hadoop@mini shell]$ a=`ls -al` [hadoop@mini shell]$ echo $a total 20 drwxrwxr-x. 2 hadoop hadoop 4096 May 15 12:50 . drwx------. 3 hadoop hadoop 4096 May 15 11:45 .. -rwxrw-r--. 1 hadoop hadoop 47 May 15 12:50 a.sh -rwxrw-r--. 1 hadoop hadoop 34 May 15 12:37 b.sh -rwxr-xr--. 1 hadoop hadoop 31 May 15 11:46 hello.sh [hadoop@mini shell]$ b=`date +%Y-%m-%d` [hadoop@mini shell]$ echo $b 2018-05-15
特殊的命令:
表达式:
##expr表达式的值操作前后需要加空格 [root@mini shell]# s=`expr 2 + 3` [root@mini shell]# echo $s 5 [root@mini shell]# expr $s \* 4 20 ##如果要进行多个表达式运算,需要多个expr命令 [root@mini shell]# expr `expr 2 + 3` \* 4 20
上面的代码可以使用如下的形式:
[root@mini shell]# a=$((1+2)) [root@mini shell]# echo $a 3 [root@mini shell]# echo $((1+2)) 3 [root@mini shell]# b=$[3-2] [root@mini shell]# echo $b 1
4. 条件语句
if 条件语句:
shell
#!/bin/bash
read -p "Please input your name:" NAME
if [ $NAME = root ] ##注意这里预留的空格 如果条件是一个字符串,且不为空 都表示条件成立
then
echo "hello${NAME},welcome !"
elif [ $NAME = hadoop ]
then
echo "welcome to ${NAME}'s world !"
else
echo "Sorry,you have no permisson !"
fi
三元运算符:
[ condition ] && echo OK || echo notOK
条件满足,执行&&后面的语句;条件不满足,执行||后面的语句。
对于双重条件的判断,可以使用 [[ ]] 来解决:
shell
#!/bin/bash
loginname=zhangsan
pwd=123
if [[ $loginname = zhangsan && $pwd = 123 ]]
then
echo "you are right \!"
else
echo "you are wrong \!"
fi
字符串:
-z 表示字符串 长度为0 if [ -z “” ]
-n 表示字符串长度不为0 **if [ -n "aa" ]**
整数比较:
-lt 小于
-le 小于等于
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于 if [ 1 -lt 3 ]
文件判断:
-d 是否是目录 if [ -d /bin ]
-f 是否为文件 if [ -f /bin/ls ]
-e 是否存在 if [ -e /bin/ls ]
while语句
#!/bin/bash
i=1
while ((i<=3))
do
echo "current i:$i"
let i++
done
case语句
#!/bin/bash
str=china
case $str in
china)
echo "hello china"
;;
world)
echo "hello world"
;;
*)
echo "Error \!"
esac
for语句
##方式一
#!/bin/bash
str=china
for N in 1 5 4 2
do
echo $N
done
echo "--------------"
##方式二
for ((i = 0;i <= 6;i++))
do
echo "curent i=$i"
done
5. 函数的使用
#!/bin/bash
#func1.sh
hello()
{
echo "hello world"
return 2 ###return code is a status code,it's range is 0-255
}
echo "now going to the function hello"
hello ##函数的调用
echo $? ##get the function return code
echo "back from the function"
如果一个函数需要传递参数 可以在调用的时候在后面传递参数,在函数内部 可以使用
$1 $2 $3 ${10}... ##超过10了要添加{}
同时,使用$#可以查看参数的个数。
[root@mini shell]# vi a.sh
#!/bin/bash
funadd()
{
echo "first arg is $1"
echo "second arg is $2"
echo "the sum is $(($1+$2))"
}
##funadd 18 17
[root@mini shell]# vi b.sh
#!/bin/bash
echo "in b.sh file"
source ./a.sh ##将a.sh代码合并到当前进程下。
funadd 15 15 ##此刻就可以调用到a.sh下面的函数了