Linux——Shell编程

Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操作。在Linux GUI日益完善的今天,在系统管理等领域,Shell编程仍然起着不可忽视的作用。

Shell脚本可以让我们管理Linux操作系统变得更加方便,自动化。学会Shell编程可以让我们对Linux理解更加深入。


目前发行版一般使用的Shell是Bash。

Bash变量

bash变量是一种弱类型,默认为字符串类型。

分类

1.自定义变量

2.环境变量

3.预定义变量


变量的查看:set(查看所有变量)

[root@localhost myShell]# set | more
ABRT_DEBUG_LOG=/dev/null
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d
BASH_LINENO=()
BASH_REMATCH=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
...
变量的删除:unset(删除指定变量)


自定义变量

自定义变量只对当前shell有效。

例如:

[root@localhost myShell]# var=var1
[root@localhost myShell]# echo var
var
等号前后不能存在空格。

变量叠加:

[root@localhost myShell]# echo $var
var1
[root@localhost myShell]# var="$var"23
[root@localhost myShell]# echo $var
var123


环境变量

对当前shell和其子shell都有效的变量。

我们需要注意的是系统自定义的环境变量,这些变量会对我们的操作系统环境产生变化。

有两种设置环境变量的方法:1.export

[root@localhost myShell]# var2=var2
[root@localhost myShell]# export var2
[root@localhost myShell]# bash

[root@localhost myShell]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
        ├─abrt-watch-log
        ├─abrtd
        ├─anacron
        ├─atd
        ├─auditd───{auditd}
        ├─crond
        ├─dbus-daemon───{dbus-daemon}
        ├─firewalld───{firewalld}
        ├─login───bash
        ├─lsmd
        ├─lvmetad
        ├─master─┬─pickup
        │        └─qmgr
        ├─polkitd───5*[{polkitd}]
        ├─rngd
        ├─rsyslogd───2*[{rsyslogd}]
        ├─smartd
        ├─sshd─┬─sshd───sshd───bash
        │      └─sshd───bash───bash───pstree
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        ├─tuned───4*[{tuned}]
        └─wpa_supplicant

[root@localhost myShell]# set | grep var2
var2=var2
在子shell中可以找到var2,但是找不到var变量。所以是环境变量。

2.declare声明变量类型为环境变量

[root@localhost myShell]# declare -x var3=var3
选项-x表示环境变量。export实际上也是调用了这条命令,简化了语句。

默认的系统变量一般都是全大写。

常见环境变量:PATH, PS1等。

[root@localhost myShell]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PATH为命令的搜寻路径。

[root@localhost myShell]# echo $PS1
[\u@\h \W]\$
PS1为命令行提示符的信息,也就是[root@localhost myShell]#。\u为显示当前用户,以此类推,修改PS1即可修改命令行提示符的信息。

[root@localhost myShell]# echo $LANG
en_US.UTF-8
LANG为当前语系,这里是美国英文。

预定义变量

$0,$1,$2...: $0表示当前文件名。$1为第一个参数,$2为第二个,以此类推。

$*: 表示所有参数,当成一个参数对待。

$@: 表示所有参数,根据空格分开来对待。

$#: 表示参数的个数

$?: 表示最后命令运行的返回值,返回值为0为正常运行,否则出错。

$$: 表示当前进程的PID。

$!: 表示最近运行的后台进程的PID。


运算符
因为变量中默认为字符串类型,如果希望数据进行数值计算,直接加减乘除是不行的。

[root@localhost myShell]# opt1=1
[root@localhost myShell]# opt2=2
[root@localhost myShell]# opt3=$opt1+$opt2
[root@localhost myShell]# echo $opt3
1+2
可以看到,并不会直接相加,而是字符串的加减。

那么需要他们进行运算需要怎么样呢?

可以使用declare声明变量的类型

declare  [+/-] [选项] 变量

我们可以有两种方式进行运算:

1.expr:

[root@localhost myShell]# opt3=$(expr $opt1 + $opt2)
[root@localhost myShell]# echo $opt3
3
2.使用$(())或者$[]

[root@localhost myShell]# opt4=$(($opt1+$opt2))
[root@localhost myShell]# echo $opt4
3


环境变量配置文件:

系统自定义的环境变量就在这些变量中保存和声明。

首先我们需要知道一个简单的命令。

当我们修改了环境变量配置文件之后,配置文件并不是马上就生效的,因为配置文件的加载是在用户登录的时候。

如果我们需要在修改了之后让其马上生效,需要重新登陆才可以。但这么做非常麻烦。

source  配置文件
使用这个命令即可让配置文件马上生效。

常用的配置文件:

/etc/profile
/etc/profile.d/
~/.bash_profile
~/.bashrc
/etc/bashrc
在登陆的时候,会加载这些配置文件,声明定义环境变量。

那么他们的执行顺序是怎么样的呢?

1.登录shell配置文件执行顺序
/etc/profile
  ->  /etc/profile.d/*.sh
    ->  /etc/profile.d/lang.sh
      ->  /etc/locale.conf
  ->  ~/.bash_profile
    ->  ~/.bashrc
      ->  /etc/.bashrc
2.非登录shell配置文件执行顺序
->  /etc/.bashrc
  ->  /etc/profile.d/*.sh
    ->  /etc/profile.d/lang.sh
      ->  /etc/locale.conf
这里可能看起来有点乱,如果画成流程图会稍微好点,大家可以画一下。
也就是说,我们的环境变量在哪里声明都可以,只要在这个流程中某个部分声明定义好了就可以了,只要没被覆盖,就能生效。


其他环境变量配置文件:

注销时候会执行的配置文件:

~/.bash_logout
历史命令配置文件:

~/.bash_history
本地shell登陆之前提示信息:

/ect/issue
远程shell登陆之前提示信息:

/etc/issue.net
登陆之后提示信息:

/etc/motd




说了这么多,那么shell到底如何进行编程呢?

要进行编程,首先要了解shell的流程控制语句。

if语句

if []
then
  ...
elif []
then
  ...
else
  ...
fi
在这里,[]返回true或者false,也可以使用test得到值。

case语句

case 值 in
匹配1)
  ...
  ;;
匹配2)
  ...
  ;;
...
*)
  ...
  ;;
esac
for语句
for 变量 in {列表i}
do
  ...
done
while语句

while []
do
    ...
done
until语句

until []
do
  ...
done


其中,上面遇到很多[],用于返回判断真或假。

可以对很多东西进行判断。

1.文件类型

-d  文件    文件是否存在,且文件是否为目录
-e  文件    文件是否存在
-f  文件    文件是否存在,且文件是否为普通文件
2.文件权限

-r  文件    是否具有读权限
-w  文件    是否具有写权限
-x  文件    是否具有执行权限
这个有点缺陷,因为判断权限不区分用户,只要有某个权限就会返回。

3.文件之间的比较

文件1 -nt 文件2     文件1是否比文件2新
文件1 -ot 文件2     文件1是否比文件2旧
文件1 -ef 文件2     文件1和文件2源是否一致,可以判断软硬链接
4.整数比较

操作数1  -eq   操作数2      操作数1和操作数2是否相等
操作数1  -nq   操作数2      操作数1和操作数2是否不等
操作数1  -gt   操作数2      操作数1是否大于操作数2
操作数1  -lt   操作数2      操作数1是否小于操作数2
操作数1  -ge   操作数2      操作数1是否大于等于操作数2
操作数1  -le   操作数2      操作数1是否小于等于操作数2
5.字符串比较

-z  字符串     字符串是否为空
-n  字符串     字符串是否不为空
字符串1  ==  字符串2     是否相等
字符串1  !=  字符串2     是否不等
6.多条件判断

判断1 -a  判断2     逻辑与
判断1 -o  判断2     逻辑或
! 判断1             取反

利用上面的知识我们就可以写一些简单的脚本了:

例如:

打印出当前使用Linux的用户。

用过截取环境变量中的USER变量的第二个参数,得到当前的用户。

当然也可以直接使用$USER访问就可以了。

#!/bin/bash

name=$( env | grep USER | cut -d "=" -f 2 )

if [ "$name" == "root" ]
then
        echo you are root
else
        echo you are not root,you are $name             
fi

你可能感兴趣的:(linux)