变量
- 变量即在程序运行过程中它的值是允许改变的量。
- 变量是用一串固定的字符来标示不固定的值的一种方法。
- 变量是一种使用方便的占位符,用于引用计算机内存地址,该地址可以存储 Script 运行时可更改的程序信息。
- 在 shell 中变量是不能永久保存在系统中的,必须在文件中声明。
在 shell 脚本中变量的种类
在 shell 中变量分为环境级变量,用户级变量,系统级变量
环境级变量
环境级变量只在当前shell 中生效, shell关闭变量丢失
用户级变量
用户级变量写在用户的骨文件中,只针对当前用户生效
系统级变量
系统级变量被写在系统的配置文件 /etc/profile 或者 /etc/profile.d/ 中,对于所有用户都生效
内存空间的地址
变量:用一个字符表示内存空间的位置
ls -a
用户环境设定家目录下的.bash_profile ,是改用户环境的文件
shell环境设定.bashrc
/etc/profile改全局的,系统级的,对所有人生效,
/etc/bashrc su不加-的时候读这个文件, 一个是shell的运行环境
修改两个都会生效,但哪一个后被读的,最终生效
先加载系统,后加载用户,所以同时被修改用户的生效
.bash_history 记录用户在环境中的历史,永久清空历史 >
.bash_logout 退出时执行的命令 clear
env 系统中的所有变量
PS1 系统中的命令行 也是变量值
su - 切换用户身份和用户的环境 login的su
su student 不加载环境设定 nologin的su
shell 脚本中变量的定义方法
环境级变量
export A=1
举例:
用户级变量
vim ~/bash_profile
export A=1
用户家目录和骨架目录下的文件:
系统级变量
vim /etc/profile
export A=1
PATH环境变量指定的系统路径
echo $PATH
如果修改错误,就会导致之前的命令如:ls,vim不能直接用了,这是因为相对路径改变了,我们用绝对路径就可以。
命令行提示符的修改
[root@server10 ~]# echo $PS1
[\u@\h \W]\$
用户 主机名 路径pwd 用户身份
变量名称的规范
变量名称中通常包含大小写字母,数字,下划线(不是必须)
变量名称格式:
WESTOS_LINUX
Westos_Linux
westoS_Linux
字符的转义及变量的声明
\ | 转义单个字符 |
---|---|
" " | 弱引用,批量转义 " " 中出现的字符 |
’ ’ | 强引用,批量转义 ’ ’ 中出现的字符,’ ’ 与 " " 两者的区别在于 " " 不能转义" \ “,” ` “,” ! “,” $ " |
${} | 变量声明 |
元字符 * # ? ! 有自己功能的
转义 一次转义一串
引用 “” 弱引用 ,不能饮用 `` \ ! $
''强引用 引用所有
举例:
变量值传递
$1 | 脚本后的第一串字符串 |
---|---|
$2 | 脚本后的第二串字符串 |
$3 | 脚本后的第三串字符串 |
$# | 脚本后所跟字符串的个数 |
$* | 脚本后跟的所有字符串,模式为“ 1 2 3 ” |
&@ | 脚本后跟的所有字符串,模式为“ 1”“2”“3” |
$ ∗ 和 * 和 ∗和 $@有什么区别?
*一串字符,是一个整体
@ 加了几个字符就是几个
$0 脚本本身的名称
$ $ 当前程序的id
kill -9 $$ 当前运行的shell被结束
#所跟字符串个数
*@所有
举例:
vim test.sh
#!/bin/bash
echo \$0 is $0
echo \$1 is $1
echo \$2 is $2
echo \$3 is $3
echo \$# is $#
echo \$* is $*
echo \$@ is $@
echo \$\$ is $$
watch -n 1 date
执行结果如下:
举例说明 $ @和$ *的区别:
1.$*
#!/bin/bash
for i in "$*"
do
echo $i
done
2.$@
#!/bin/bash
for i in "$@"
do
echo $i
done
对比执行结果可知:$
∗
=
"
1234
"
,
*="1 2 3 4",
∗="1234",$ @="1""2""3"“4”
用 read 实现变量传递
上面介绍的都是内置变量,下面是交互式的变量。
加 -s 为加密
举例:
1.
read -p "whatisyouname?" TARGET
echo "$TARGET"
执行结果:
2.判断某一主机的网络状态,通不通畅
read -p "please input ipaddr?" TARGET
ping -c1 -w1 $TARGET &> /dev/null && {
echo $TARGET is up
}||{
echo $TARGET is down
}
执行结果:
3.加密方式的设定:
read -p "please input ipaddr?" -s TARGET
ping -c1 -w1 $TARGET &> /dev/null && {
echo $TARGET is up
}||{
echo $TARGET is down
}
执行结果:
4.加空行:
read -p "please input ipaddr?" -s TARGET
echo ""
ping -c1 -w1 $TARGET &> /dev/null && {
echo $TARGET is up
}||{
echo $TARGET is down
}
执行结果:
linux 系统中命令别名的设定
针对当前环境生效
alias xie='vim'
xie file
退出当前的shell后不生效
针对当前用户生效
家目录的 .bashrc文件 加入alias xie='vim'
source .bashrc
退出当前shell依然生效
但是切换到student不生效
su student
su - student
针对所有用户生效
/etc/bashrc 加不加-都会读取这个文件 用户
/etc/profile 不加- 不生效 系统环境
写到/etc/bashrc su student也会生效
写到/etc/profile 只有su - student才会生效
所以我们写到/etc/bashrc
alias xie='vim'
su student
su - student
删除
删除两个文件里写的内容
然后 unalias xie
查看有没有删除 alias
利用命令执行结果设定变量
$()和 `` `
$()和`` ``用途更广
echo time is date 不能显示时间
可以这样显示:
echo time is `date`
echo time is $(date)
或者time=`date`
echo $time
vim test.pl
#!/usr/bin/perl
print `date`
#!/usr/bin/perl
print $(date)
perl test.pl 无法执行
所以``更广
退出值 $?
$? 是命令在执行完成之后产生的退出值,范围是 [0-255]
当 $0=0 时标示命令执行没有错误输出,非0为错,命令执行完一定有退出值,这个值可以用 exit 命令执行。
例如:exit 66
举例:
指定退出值,举例:
#!/bin/bash
echo zhangyiwen
exit 66
执行结果:
[ $USER = "1000" ] || {
echo error
exit 66
}
执行结果:
脚本中的函数
脚本中的函数时把一个复杂的语句块定义成一个字符串的方法。
Host_Message()
{
read -p "Please input you action: " Action
[ "Action" == "exit" ] && exit 0
[ "Action" == "user"]&&echo You are $USER
[ "Action" == "hostname" ]&& echo $HOST
Host_Message
}
Host_Message
在.sh文件中写入:
export a=ls
a /mnt
会报错,命令未找到 因为a是定义变量而不是功能
变量只是指定值 而函数是显示功能
相当于脚本中的脚本
提取重复的,让脚本循环执行
例如:
ECHO()
{
echo -e "\033[${1}m$2\033[0m"
}
ECHO 31 ERROR
ECHO 32 OK
ECHO 31 ERROR
ECHO 32 OK
执行结果:
练习题
判断用户输入的内容,如果输入exit或EXIT,直接退出
代码如下:
#!/bin/bash
ACTION()
{
read -p "Please input a word: " WORD
[ "$WORD" = "exit" -o "$WORD" = "EXIT" ] &&{
echo bye
exit 0
}||{
echo $WORD
}
ACTION 循环执行
}
ACTION 调用函数
执行结果:
练习题
创建用户 ,当运行脚本 user_ctrl.sh 时出现提示C D E。
要求:当用户输出C时,提示输入用户名,判断用户存不存在,存在提示该用户存在,不存在提示输入密码,建立用户,返回主页面
当用户输入D时,提示输入用户名,用户名不存在提示不存在,直接返回到主页面。用户名存在,删除,返回到主页面
当用户输入E时,直接退出。
思路:
分3步 C D E
C 又分为用户存在和用户不存在
D 分为用户存在和不存在
E 直接退出
echo -e 输出 换行 \n 前后加\n就是上下都换行
代码如下:
#!/bin/bash
echo -e "\nC[reate] D[elete] E[xit]\n"
Choose_Fun()
{
read -p "Please input Action:" WORD
ACTION=`echo "$WORD" |tr 'A-Z' 'a-z'`
[ "$ACTION" = "c" -o "$ACTION" = "create" ] && {
Create_User_Func
}
[ "$ACTION" = "d" -o "$ACTION" = "delete" ] && {
Delete_User_Func
}
[ "$ACTION" = "e" -o "$ACTION" = "edit" ] && {
echo bye
exit
}||{
echo "Error:$ACTION is wrong action!!"
Choose_Fun
}
Choose_Fun
}
Create_User_Func()
{
read -p "Please input name:" USERNAME
id $USERNAME &> /dev/null
[ "$?" = "0" ] && {
echo $USERNAME is exist!
Create_User_Func
}||{
useradd $USERNAME
read -p "Please input passwd :" PASSWD
echo $PASSWD | passwd --stdin $USERNAME &> /dev/null
echo "$USERNAME is created successfully!"
Choose_Fun
}
}
Delete_User_Func()
{
read -p "Please input username:" USERNAME
id $USERNAME &> /dev/null
[ "$?" = "0" ] && {
userdel -r $USERNAME
echo $USERNAME is deleted!
Choose_Fun
}||{
echo "$USERNAME is not exist"
Choose_Fun
}
}
Choose_Fun
执行结果:
脚本中的数组
df -h / | sed -n '/\/$/p'
a=(`df -h / | sed -n '/\/$/p'`)
echo ${a[0]}
echo ${a[4]}