变量初始化:在变量声明的时候给变量一个初始值,初始化相当于给里面放东西。
变量赋值:手动给变量空间中存储数据的过程。
变量类型转换:显式、隐式,比如讲字符型转换成数值型。
变量类型:
本地变量:
set var_name=value
unset var_name
${var_name}
作用范围:当前shell进程。
局部变量:
local var_name=value
unset var_name
${var_name}
作用范围:当前shell进程的局部范围内有效
环境变量:
export var_name=value
unse var_name
${var_name}
作用范围:当前shell及其子shell。
位置变量:$1/$2................
特殊变量:$$/$?/$#/$@...................
脚本的写法格式:
指定脚本运行的shell环境:
独立执行脚本的条件:
1、要有执行权限。
2、定义好shebang,及脚本的第一行:#! /path/to/explainer 例如:/bin/bash ,/usr/bin/python。
3、定义命令的path环境变量。
bash的配置文件:
profile:声明环境变量,执行程序脚本 ,/etc/profile,/etc/profile.d/*.sh,~/bash_profile,交互式登陆
bashrc:定义本地变量、定义命令别名/etc/bashrc,~/.bashrc,非交互式
脚本文件中,除第一行外其他所有已#开头的行均为注释行。
练习一、添加一组用户,并且用户名同密码一样。
#!/bin/bash
#author:gongbing
#time :20150731
#version:1.0
#description:add user
useradd user1
echo user1 |passwd --stdin user1&>/dev/null
echo "add user1 successful!"
useradd user2
echo user2 |passwd --stdin user2 >/dev/null
echo "add user1 successful!"
useradd user3
echo user3 |passwd --stdin user3 >/dev/null
echo "add user1 successful!"
编写完毕保存为.sh文件,并赋予执行权限。
检查脚本的语法错误:
bash -n 脚本路径/脚本名
调试执行脚本语法:
bash -x /path/to/script_file.sh
变量名称取名规则:
1、数字、字母、下划线
2、不能以数字开头
3、区分大小写
4、风格统一,见名知意。
面向过程的编译语言,都有语言控制结构:
1、顺序执行:默认、逐条执行。
2、选择执行:依据条件语句判断来选择执行的步骤。 0:真,非零:假
3、循环执行:依据条件重复执行某一条命令的次数。
控制语句:
不同语句写在同一行里需要用分号;隔开。
bash循环控制语句:
for循环:
事先提供一个元素列表,然后让变量去遍历(挨个提取)此元素列表;每访问一个元素,执行一次循环体,直至元素遍历完毕。
用法: for var_name in 元素列表比如元素1 元素2 元素3
do
语句1;
语句2;
done
while
until
练习二:给练习一调整为循环语句。
#!/bin/bash
for username in user1 user2 user3;
do;
useradd $username ;
echo $username |passwd --stdin $username;
done;
练习三 、显示/et/inittab,/etc/rc.d/rc.sysinit,/etc/fstab三个文件各有多少行。
#!/bin/bash
for PathWc in /etc/inittab /etc/rc.d/rc.sysinit /etc/fstab
do
cat $PathWc |wc -l
done
练习:
1、 使用for循环创建/tmp/1.dir,/tmp/2.dir和/tmp/3.dir,权限为750
#!/bin/bash
for Direc_Gest in 1.dir 2.dir 3.dir
do
mkdir /tmp$Dire_Gest
chmod 750 /tmp/$Dire_Gest
done
2、统计/etc/fstab、/etc/rc.d/rc.sysinit、/etc/inittab文件中各自以#开头的行的行数和空白行行数。
#!/bin/bash
for filecount in /etc/fstab /etc/rc.d/rc.sysinit /etc/inttab
do
egrep ^#|^$ $filecount |wc -l
done
3、将/etc/passwd 、/etc/shadow的最近一次修改时间改为2010年3月12日14:11 3秒
#!/bin/bash
for ModfyTime in /etc/passwd /etc/shadow
do
touch -m -t 201003121411.03 $ModfyTime
#touch -a 修改访问时间 默认当前时间
#touch -m 修改修改时间 当前时间
#touch -m -t yymmddhhmm.ss 修改指定时间。
done
4、将user1、user2、user3加入到testgrp组中,以其为额外组。
#!/bin/bash
groupadd testgrp
for usertogrp in 1 2 3
do
usermod -G testgrp user$usertogrp
done
5、copy /etc/passwd /etc/shadow /etc/inittab 到/tmp/目录下,并将名称已当前时间进行重命名。
#!/bin/bash
for filerename in /etc/passwd /etc/shadow /etc/inittab
do
basefile= `basename $filerename`
cp $filename /tmp/$basefile-`date +%F`
done
6、显示/etc/paswd文件的第1、3、6、12个用户的用户名、id、基本组的组名。
#!/bin/bash
for Line in 1 3 6 12
do
username=`head -n 1 /etc/passwd |tail -n 1 |cut -d : -f 1`
Idname=`head -n 1 /etc/passwd |tail -n 1 |cut -d : -f 3`
Groupname='id -gn $username'
echo "username:$username> done
列表的生成:
1、逐个列出,例如1 2 3 4
2、使用通配符列出,例如 /etc/*
#!/bin/bash
for file in /etc/*
do
file $file
done
3、使用命令生成列表。
#!/bin/bash
for File in `ls /var`
do
file /var/$File
done
4、生成数字序列,
{}:例如生成1到100的数值,{1..100}
equ:equ [起始数字] [步长] [结束数字]
练习:
1、取出每个用户的用户名和shell
思路:首先需要确定行数
#!/bin/bash
line=`wc -l /etc/passwd |cut -d : f 1`
for Line in equ 1 $line
do
head -$Line /etc/passwd |tail -1 |cut -d: -f 1,7
done
如何在shell中进行算术运算
shell不支持浮点数(小数),计算结果中如果有浮点数会被圆整为正数(化零为整)
默认变量使用的是字符变量类型。实现算数运算的方法:
1、 $[变量名]=valume
2、 $((变量名))=valume
3、 let 例如:let a=$a+$b
4、 expr 例如:f=`expr $a + $b`
练习:
随意声明两个变量,并给出整数值,然后计算他们的加减乘除的结果。
#!/bin/bash
Valume1=12
Valume2=43
for suanfa in + - * /
do
echo "$Valume1$suanfa$Valume2= `let $Valume$suanfa$Valume`"
done
选择执行语句
可以独自执行的命令不需要添加[]来完成测试。
bash条件测试方式有以下几种:
1、 [ expression ]:[]里面有空格。表示条件选择的依据。
2、 ` expression `:
3、 test expression:
4、 bash 命令:
bash执行命令后有执行结果的状态返回值:echo $? (0表示成功,其他都是错误)
可以使用exit命令在脚本中自定义脚本执行状态返回值,如果没有定义,脚本执行状态返回值取决于脚本执行结束前的最后一条语句的执行结果。
判断格式:
单分支if语句:
1、 if 条件 ;then
语句1
语句2
fi
练习:
1、查看某用户是否存在,并显示相关信息。
#!/bin/bash
Username=user1
if> then
echo "$Username is living"
fi
2、如果用户存在,显示用户id和shell信息。
3、如果一个设备已经挂载,显示挂载点。
4、 检查某一文件的 的空白行,并统计行数。
2、if 条件
then
语句1
语句2
else
语句1
语句2
fi
练习:
1、检查用户是否存在,并显示相关信息,如果不存在创建用户名,密码。
#!/bin/bash
Username=zhangliang
if> then
echo "$Username is living"
echo "$Username> else
useradd $Username
echo "no this username,please wait....useradding...... "
echo "$Username" |passwd --stdin $Username
bash编程之位置变量
$1.....$11.......:表示可以通过执行程序,然后加常量的方式来执行并替换程序中的$1等相关变量。
$@:表示可以将多个常数按照一个字符串的形式显示出来
$*:将多个常数分别以各自字符串的形式显示出来。
$#:汇总常数的个数。
$0:脚本名称。
#!/bin/bash
echo $1
echo $2
echo $@
echo $*
echo $#
执行程序:./pos.sh a b c d e
执行结果:a
b
a b c d e
a b c d e
5
例:通过参数传递n个正整数给脚本,并求和。
#!/bin/bash
Num=0
Count=0
for n in $@
do
Count=$[$Count+$n]
done
echo "Count is $Count"
shift:对一组数进行重新定位第一个数。shift之前的数被踢掉。
实现位置参数轮替。
#!/bin/bash
echo $1
shift
echo $1
shift
echo $1
执行:./shift.sh a b c d
结果:a
b
c
练习:
添加10个用户,需要先判断用户是否存在,如果不存在才添加,统计添加的用户数,并显示总的用户数。
-m, --modify=acl modify the current ACL(s) of file(s)
setfacl -m u:username:mode /path/to/file #为用户username设定具有mode的权限
setfacl -m g:groupname:mode /path/to/file #为组groupname设定具有mode的权限
-M, --modify-file=file read ACL entries to modify from file
-x, --remove=acl remove entries from the ACL(s) of file(s)
setfacl -x u:username /path/to/file #取消某一个用户的acl权限。
-X, --remove-file=file read ACL entries to remove from file
-b, --remove-all remove all extended ACL entries
-k, --remove-default remove the default ACL
--set=acl set the ACL of file(s), replacing the current ACL
--set-file=file read ACL entries to set from file
--mask do recalculate the effective rights mask
-n, --no-mask don't recalculate the effective rights mask
-d, --default operations apply to the default ACL
-R, --recursive recurse into subdirectories
-L, --logical logical walk, follow symbolic links
-P, --physical physical walk, do not follow symbolic links
--restore=file restore ACLs (inverse of `getfacl -R')
--test test mode (ACLs are not modified)
-v, --version print version and exit
-h, --help this help text
对于新加入的磁盘默认情况下是不支持acl功能的,需要通过在挂载的时候添加挂载选项-o acl才可以。 比如: mount -o acl /dev/sdb1 /mnt/sdb1