shell脚本与Windows/Dos下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。相对于Perl、Python等脚本语言优势在于它能处理底层业务,因为有大量Linux命令作为支撑,如“报警业务”,“一键安装”等用shell脚本写就会非常简单。
Linux下的shell脚本默认为bash ,sh其实是bash的一个链接。
查看默认shell的两种方法:
>echo $SHELL@H_403_9@
/bin/bash
>grep root /etc/passwd
root:@H_403_9@x:@H_403_9@0@H_403_9@:@H_403_9@0@H_403_9@:root@H_403_9@:/root@H_403_9@:/bin/bash@H_403_9@
一个简单的脚本:
之前在这篇文章中配置桥接的静态IP的时候是手动操作的,下次换了一个网络又要重新配置,所以写了个脚本来自动配置。基于这个脚本来学习一下简单的shell脚本。
#!bin/bash @H_403_9@
ETC_DIR=/etc/sysconfig/network-scripts
NET_DIR=/etc/sysconfig
ROOT_UID=0@H_403_9@
if@H_403_9@ [ "$UID@H_403_9@"@H_403_9@ -ne@H_403_9@ "$ROOT_UID@H_403_9@"@H_403_9@ ] #判断是否为root权限@H_403_9@
then@H_403_9@
echo@H_403_9@ "Must be root to run this script"@H_403_9@
exit@H_403_9@ 1@H_403_9@
fi@H_403_9@
cd@H_403_9@ $ETC_DIR@H_403_9@ || {
echo@H_403_9@ "Cannot change to necessary directory,"@H_403_9@>&2@H_403_9@
exit@H_403_9@ 1@H_403_9@
}
cat /dev/null >ifcfg-eth0 && echo@H_403_9@ "clean ifcfg-eth0 ok!"@H_403_9@
#写入eth配置:@H_403_9@
cat /home/yangni/staticip/myip >ifcfg-eth0 && echo@H_403_9@ "write eth0 sucessfully"@H_403_9@
cd@H_403_9@ $NET_DIR@H_403_9@ || {
echo@H_403_9@ "Cannot change to necessary directory,"@H_403_9@>&2@H_403_9@
exit@H_403_9@ 1@H_403_9@
}
cat /dev/null >network #清空network@H_403_9@
#将默认网关相关配置写入network@H_403_9@
cat /home/yangni/staticip/mynetwork > network && echo@H_403_9@ "write network sucessfully"@H_403_9@
service network restart #重启网络命令@H_403_9@
exit@H_403_9@ 0@H_403_9@
1、UID是一个系统变量,当前是root权限 UID=0,当前非root权限UID不等于0
所以我们在这设置了一个变量ROOT_UID=0
,来判断当前是否为root状态,因为我们对系统的配置文件进行修改必须使用root权限。所以执行的时候必须加sudo。
2、清空文件的三种方法:
清空日志的三种方法:
1@H_403_9@、echo ""@H_403_9@>test.log@H_403_9@
2@H_403_9@、echo >test.log@H_403_9@
3@H_403_9@、cat /dev/null@H_403_9@ >test.log@H_403_9@
在改代码中我们用的是第三种方法:cat /dev/null >network
3、&&与||的使用:
cat /dev/null@H_403_9@ >ifcfg-eth0 && echo@H_403_9@ "clean ifcfg-eth0 ok!"@H_403_9@
这里&&表示,只有当前面的命令执行成功以后才执行后面的命令。
而 || 则是表示前面执行不成功就执行后面命令。
cd@H_403_9@ $NET_DIR@H_403_9@ || {
echo@H_403_9@ "Cannot change to necessary directory,"@H_403_9@>&2@H_403_9@
exit@H_403_9@ 1@H_403_9@
}
所以如果不能够进入到该目录下,就打印错误信息。&2表示标准出错,&0表示表示标准输入。&1表示标准输出。
脚本执行:
脚本执行时候会先调用环境变量,去找相关变量,有的变量是系统已经定义可直接使用,如上文用到的UID。
cat /etc/profile (全局)
cat /etc/profile.d@H_403_9@ (全局)可以把变量放在这里面就可以直接用
.bashrc@H_403_9@:用户环境变量
脚本执行的三种方法:
>bash xxx.sh
>bash >xxx.sh
bash或sh 指定的bash执行脚本,然后启动子shell去执行。如果没有在脚本第一行指定使用哪一种脚本命令(`#!/bin/bash
,只能放在第一行,放在其他行就作注释处理),则需要用使用第一种方法。但是在Linux系统默认是bash,所以无需指定也可以,但是在其他系统就不行了。
>source xxx.sh
>. xxx.sh
source或者.命令是Shell的内建命令,这种方式也不会创建子Shell,直接在当前的shell中执行,并且调用系统默认的shell去执行脚本,不管脚本中是不是指定shell命令解析器。
所以用 . 和sh运行时就会出现如下现象:
因为 . 不启动子shell,所以会直接执行子shell里的语句,并把变量传给父shell。脚本里面所有新建、改变变量的语句都会保存在当前shell里面。
执行结果截图:
如果没有使用root权限:
加上sudo之后:
贴上myip和mynetwork两个文件:
myip:
DEVICE=eth0@H_403_9@@H_403_9@
HWADDR=00@H_403_9@:0@H_403_9@C:29@H_403_9@:03@H_403_9@:4@H_403_9@D:EC #物理地址无需修改@H_403_9@@H_403_9@
BOOTPROTO=static@H_403_9@@H_403_9@
NM_CONTROLLED=yes@H_403_9@ #实时生效,修改后无需要重启网卡立即生效@H_403_9@@H_403_9@
IPADDR=192.168@H_403_9@.0.27@H_403_9@@H_403_9@@H_403_9@
BROADCAST=192.168@H_403_9@.0.255@H_403_9@@H_403_9@@H_403_9@
NETMASK=255.255@H_403_9@.255.0@H_403_9@@H_403_9@@H_403_9@
GATEWAY=192.168@H_403_9@.0.1@H_403_9@@H_403_9@@H_403_9@
ONBOOT=yes@H_403_9@ #开机启用网络配置。@H_403_9@@H_403_9@
TYPE=Ethernet@H_403_9@@H_403_9@
DNS1=8.8@H_403_9@.8.8@H_403_9@@H_403_9@@H_403_9@
IPV6INIT=no@H_403_9@@H_403_9@@H_403_9@
USERCTL=no@H_403_9@@H_403_9@@H_403_9@
mynetwork:
NETWORKING=yes@H_403_9@@H_403_9@@H_403_9@
HOSTNAME=yangni@H_403_9@@H_403_9@
GATEWAY=192.168@H_403_9@.0.1@H_403_9@ #添加网关地址@H_403_9@@H_403_9@