export可以让一个用户自定义的变量变为环境变量
定义(导入)环境变量的方式 :export abc='ab'
export可以查看(导出)系统所有的环境变量:直接输入export
附: 一些内置环境变量的含义:
DISPLAY:定义图形界面所显示到的位置
HISTSIZE:定义保存的历史记录数量
HOME:定义用户家目录
HOSTNAME:主机名
LANG:定义使用的语言
LOGNAME:登录系统的用户名
PWD :当前目录
SHELL:定义当前使用的shell
3.特殊变量
用于调用BASHELL特殊的执行结果
$? 上一命令的执行结果:是否成功
0:成功
1-255:失败
4.位置变量
可以直接向脚本传递参数并可以被脚本调用的变量
位置变量指的是shell程序在运行时传入的参数。程序中可以用变量的形式来调用这些参数。这些参数被存放到1~9的9个变量名中,被形象的称为位置变量。同普通变量一样,位置变量用$前缀加这个数字来表示。例如,第5个参数,表示为$5。例如要向shell程序传递参数“Beijing is a beautiful city”
eg1:vim test1.sh
#! /bin/bash
echo "$1"
echo "$2"
echo "$3"
echo "$4"
echo "$5"
chmod +x ./test.sh
./test1.sh beijing is a beautiful city
eg2:vim test.sh
#!/bin/bash
echo "$1"
echo "$2"
:wq
chmod +x ./test.sh
./test wangxing lizhiqiang(给shell传俩参数)
eg3:传递两个整数给脚本,让脚本分别计算并显示这两个整数的和,差,积,商
vim test.sh
#!/bin/bash
echo "first number $1" (表示输出第一个数)
echo "second number $2" (表示输出第二个数)
echo " $(($1+$2))" (输出两数之和)
echo "$[$1-$2]" (输出两数之差)
echo "$[$1*$2]" (输出两数之积)
5.算数运算
echo "$[$A+$B]"
echo `expr "$A+$B"`
$(( ))或$[ ]
eg:写一个脚本,内容为:echo "the sum is:$[$1+$2]"。它会接收你从键盘输入的数据,例如你输入:10 25,结果会显示:the sum is:35
注意:shell本身只有字符类型,要想进行数字运算必须使用算数运算表达式
二,命令别名
`别名在bashrc里存放,使用alias命令
`命令别名:alias ll='ls -l'
`撤销别名:unalias ll
`自己通过命令的别名只对当前shell有效
`除非把其保存到对应的配置文件里,否则重启后别名失效
三,环境变量的配置文件类型
1.作用范围划分:
1.全局
/etc/profile, /etc/profile.d/* , /etc/bashrc
2.局部
~/.bash_profile, ~/.bashrc, ~/.bash_logout
2.功能方面划分:
1.profile类
功能:1)设置环境变量
2)运行用户登录要执行的一些命令
2.bashrc类
功能:1)设置别名
2)设置本地变量
三.shell:(1)交互式登录shell
调用的文件依次为:
/etc/profile -->/etc/profile.d/*-->~/.bash_profile-->~/.bashrc-->/etc/bashrc
(2)非交互式登录shell(系统启动时自动执行)
调用的文件依次为:
~/.bashrc-->/etc/bashrc-->/etc/profile.d/*
修改过配置文件后,若想立即生效,则使用source或者.。例如:source /etc/profile
. /etc/profile
例如:让用户登录进来时,显示“hi,I know you,you are...”
因为让所有用户都能看到,因此要设置全局有效地文件,修改/etc/profile,在最后输入echo -e "hi,I know you,you are $LOGNAME",然后用source让其生效就可以了。
四.source/etc/profile(重读该配置文件)
修改过配置文件后,若想立即生效,则使用source或者.。
例如:source /etc/profile
. /etc/profile(重读该配置文件)
例如:让用户登录进来时,显示“hi,I know you,you are...”
因为让所有用户都能看到,因此要设置全局有效地文件,修改/etc/profile,在最后输入echo -e "hi,I know you,you are $LOGNAME",然后用source让其生效就可以了。
五,输入/输出重定向
1. 标准输入:/dev/stdin, 0 默认:从keyboard(键盘)输入
标准输出:/dev/stdout, 1 默认:从monitor(显示器)输出
错误输出:/dev/stderr, 2 默认:从monitor(显示器)输出
重定向:是指不由系统提供的标准输入或输出端口输入或输出,而进行重新的指定
输出重定向:eg:默认要从显示器输出,指定让他不从显示器输出,而把他保存到某个文件,或丢弃
输入重定向:eg:不从键盘输入,而进行重新指定(CP覆盖)
输入重定向 <
输出重定向 > >>(追加输出重定向,不覆盖原来内容而是追加在后面)
eg: ls –l /etc >/tmp(将 ls -l列出的内容覆盖输出到/tmp而不是通过显示器显示出来)
ls –l /etc >>/tmp (追加输出到/tmp)
ls /tec >/tmp/etc.out 2>/tmp/etc.err
(如果正确则输出到/tmp/etc.out,如果错误则输出到/tmp/etc.err)
错误输出重定向 2> 2>>(追加错误输出重定向)
&> 将正确的和错误的输出重定向到一个文件里
2>& 将标准错误重定向到标准输出
set -C 避免使用覆盖重定向(拒绝覆盖重定向)
set +C 解除禁止使用重定向
2.自定义输出重定向:
·不使用0,1,2
eg.
exec 3> /tmp/myout.out
(定义3这个描述符,适用于想多次向某个文件中重定向,避免多次打开关闭/tmp/myout.out文件 )
ls –l /etc >&3
exec 3>&- (撤销3这个描述符)
·无底洞:/dev/null,将错误信息输入到此设备下,此文件将消失。
例如:find /home -name .bashrc 2> /dev/null,屏幕上是会显示正确信息,而错误信息被丢弃了。
六,管道 |
1.管道:将前一个命令的输出结果作为后一个命令的输入内容。
使用方法:command1 | command2 | command3 | ……
eg:echo redhat | passwd –stdin student(将student的密码改为redhat)
(ps:我们之前有了解到passwd 命令中有一个参数--stdin,作用是将标准输入改为别的
例如:echo "123456"|passwd --stdin redhat,将redhat的密码改为123456)
2.双向重定向命令tee
功能说明:读取标准输入的数据,并将其内容输出成文件。
tee命令会同时将数据流送与文件与屏幕;而输出到屏幕的,其实就是stdout,可以让下个命令继续处理。一个输入流保存两分,一份保存到文件当中,一份送到屏幕上。
eg: ls /etc |tee /tmp/ls.out|less
(tee将ls /etc出来的内容变成两份,一份输出到/tmp/ls.out一份使用less查看)
七, shell
1.程序执行流:
·顺序执行
·选择分支
·循环执行:1+...+100
2.for循环格式:
for VAR in LIST;do
statement;
statement;
...
done
for 变量名 in 变量范围;do
statement1
statement2
done
如果我要创建10个用户user1,......,user10,利用for进行循环
eg:for I in 1 2 3 4 5 6 7 8 9 10;do
useradd user$I
echo user$I |passwd --stdin user$I
done
其中in的内容可以简写为seq 1 10,所以就可以改写为for I in `seq 1 10`;do
另外还可以简写为{1..10},则for I in {1..10};do
for循环的列表的几种方式:
简单列表: 1 2 3 4
复制列表:this is tom’s cat
变量:`seq 1 $lines`
命令:`ls /var`
通配符 for I in /var/*
eg:添加五个用户(user1,user2,...user5)并设置密码
for I in 1 2 3 4 5;do
useradd user$I
echo user$I|passwd --stdin user$I
done
3.表示从一到十的方法:
1.`seq 1 10`
2.{1..10}
3. &(seq 1 10)
eg:显示/etc/passwd中的用户名,并且向所有用户问好,形如:Hello,root。并且统计用户数量,就可以使用上面命令的列表格式。但是必须声明一下,以换行符作为一行的结束,在linux中,默认会有多种结束符,因此,我们需要加以说明,用IFS=$'\n'来设定。
#!/bin/bash
IFS=$'\n' 只识别换行符
let SUM=0
for LINE in `cat /etc/passwd`;do
user=echo $LINE |cut -d ":" -f1
echo "Hello,$user"
SUM=$[$SUM+1]
done
echo "$SUM users."
4.一次取一行
for LINE in `cat /etc/passwd`;do
但空格,换行,分隔都会被认为是换行
解决方法:修改内置变量:IFS=$'\n'
IFS=$'\n' 表示分隔符只是换行符(IFS由或或三者之一组成)
八,cut命令
定义:cut命令是用来剪下文本文件里的数据,文本文件可以是字段类型或是字符类型,
后一种数据类型在遇到需要从文件里剪下特定的列时,特别方便。
语法:cut -c list [file ...]
cut -f list [-d delim] [file...]
用途:从输入文件中选择一或多个字段或者一组字符,配合管道,可再做进一步处理
-c list
以字符为主,做剪下的操作。list为字符编号或一段范围的字符
-d delim
通过-f选项,指定delim作为定界符。
eg:cut -d: -f1 /etc/passwd(以冒号为定界符切割)
cut -d" " /etc/passwd(以空格作为定界符切割)
-f list
以字段为主,做剪下的操作
九,grep:全面搜索正则表达式并打印出来
1.grep:
grep(最常用),egrep(扩展的grep),fgrep
用法:grep [options] ‘PATTERN’ file...
eg:grep ‘root’ /etc/passwd
正则表达式,元字符 re
grep 'root' /etc/passwd
搜索正则表达式并打印出来
-i 不在意大小写
-v 跟默认动作相反,反向显示
-n 显示匹配的行在文中所处的行号
-An 多显示后面的几行
-Bn 多显示前面的两行
-Cn 多显示前后的两行
--color 高亮显示
正则表达式:基本,扩展,更多的元字符
2.选项: -i不区分大小写
-v反向显示,和默认动作相反
-n显示匹配的行在原文中所处的行号
-An(after)把匹配到的行后的n行也显示出来
-Bn(before)把匹配到的行前的n行也显示出来
-Cn(context)把匹配到的行前行后的n行也显示出来
--color 高亮显示
3.模式:由正则表达式组成
正则表达式:基本,扩展,更多的元字符
元字符:
^脱字符 ---行首定位符
&---行尾匹配符
.---用于匹配单个字符
*---匹配0或多个位于*号前的字符 root* 匹配roo,roott,roottt,,,
\词首词尾同时定位
\{root\{1\}
\( \) eg:\(root\).*\1able \1引用了root
[]匹配一组字符中任一个 eg:/[Ll]ove/
[x-y]匹配指定范围内的一个字符 eg:/[A-Z]ove/
[^]匹配不在指定组内的字符 eg:[^A-Z]
\ 用来转义元字符 ,去除其后紧跟的元字符或通配符的特殊意义。eg: love\.
\< 词首定位符 eg:\ \>词尾定位符 eg:love\>
\(...\)匹配稍后将要使用的字符的标签 eg:\(love\)able\1able 匹配的是 loveableloveable字符串
x\{m,\} 字符x重复出现至少m次
x\{m,n} 字符x重复出现m到n次
-E =egrep
egrep新增的元字符:
+ = \{1,\}
匹配一个或多个加号前的字符 eg:‘[a-z]+ove'匹配一个或多个小写字母后跟ove的字符串
? = \{0,1\}
匹配另个或一个前导字符,即它前面的那个字符可有可无
a|b 匹配a或b eg :’love|hate‘ 匹配love或hate
() 字符组 eg:love(able|ly)匹配loveable或lovely
{m} 前导字符或字符组出现m次 eg:(love){m} 匹配m个love
$?:上一个命令执行状态结果
0:success
1-255:failure
&&
||
command && command(前面的成功后才执行后面的)
command || command (前面的失败了才执行后面的)
短路操作符:
1 && 1 = 1
习题答案
alias grep='grep --color'
1.grep --color "^[Ss]" /proc/meminfo
2.grep "nologin$" /etc/passwd
3.grep "^#[[:space:]]\{1,\}.*" /etc/inittab
4.grep ":[[:digit:]]:" /etc/inittab
5.grep "^[[:space:]]\{1,\}.*" /boot/grub/grub.conf
6.grep "^\([[:digit:]]\).*\1" /etc/inittab
7.ifconfig | grep "inet addr" | grep -v "127.0.0.1" | cut -d: -f2 |cut -d" " -f1
8.grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' /etc/sysconfig/network- scripts/ifcfg-eth0
疑问?? 为什么第二种方法行不通呢?
1.ifconfig | grep "inet addr" | grep -v "127.0.0.1" | cut -d: -f2 |cut -d" " -f1
2.ifconfig | grep "inet addr" | grep -v "127.0.0.1" | cut -d" " -f2 |cut -d: -f2
eg:小练习:1,创建一个别名只在局部有效且在交互式登录shell时有效
2,创建一个别名全局有效且在非交互式登录shell时自动执行
3,永久有效声明一个别名
4,传递两个整数给脚本,让脚本分别计算并显示这两个整数的和,差,积,商
答案如下: vim test.sh
#!/bin/bash
echo "first number $1" (表示输出第一个数)
echo "second number $2" (表示输出第二个数)
echo " $(($1+$2))" (输出两数之和)
echo "$[$1-$2]" (输出两数之差)
echo "$[$1*$2]" (输出两数之积)
echo "$[$1/$2]" (输出两数之商)
:wq (表示保存并退出vi编辑器)
chmod +x test.sh (给test.sh执行的权限)
./test.sh 2 3 (传递两个参数并执行脚本)
把数字赋值给变量的方法
1)把变量的名字命名为数字
eg:1=‘2’
echo $1
作业一:写一个脚本
添加10个用户user1到user10,但要求只有用户不存在的情况下才能添加
答案:
#!/bin/bash
for I in `seq 1 10`;do
cut -d: -f1 /etc/passwd |grep "user$I" 2>>/tmp/etc.err || useradd user$I
done
作业二:写一个脚本
通过ping命令测试192.168.0.151到192.168.0.254之间的所有主机是否在线
如果在线,就显示“ip is up”
如果不在线,就显示“ip is down”
#!/bin/bash
for I in `seq 151 254`;do
ping -c1 -w1 192.168.0.$I &>/dev/null && echo "192.168.0.$I is up" || echo "192.168.0.$I is down"
done