shell脚本的基本知识
变量的定义
1、定义本身
数据在内存中,变量就是用来定义内存一片区域的地址,当内存信息发生了改变,字符串已经定义好了,就可以用这个名字找到这个地址中的信息。
2、变量存在的意义
命令无法操作一直变化的目标,用一串固定的字符来表示不固定的目标可以解决此问题
shell脚本中变量的定义方法
-
环境级别
A=1 vim westos.sh echo $A sh westos.sh ##这个运行方式不会得到结果 source westos.sh ##只有这个方式运行才可以得到结果,因为他是在当前shell中运行的 export A=1 ##输入此命令,其他的运行方式会生效,但是当环境退出再次进入的时候,这几个命令又会失效
-
用户级别
vim ~/.bash_profile export a=1 ##在文件中编辑此命令就可以使得在此用户之下任何时候都可以使用运行命令得到结果 source ~/.bash_profile
但是这个有效性只是在本用户,切换用户会失效。
-
系统级别
vim /etc/profile.d/westos.sh export A=3 ##此时切换到任何的用户中都可以识别这个文件 sh /mnt/westos.sh . /mnt/westos.sh ##env可以看见系统中设置的变量 echo $USER ##输出此时的用户 #用一串固定的字符表示不固定的值,显示出多样化。相当于C中的占位符。
变量名称
变量名称可包含的字符:字母 下划线 数字
变量名称定义规则:不能用数字开头
建议:
变量名称短全用大写字符
变量名称长用_区分子类
变量的转译
-
转译
\ ##转译单个字符 “ ” ##弱引用,批量转译个数字符,不能转译 “\” “`” “$” “!” ' ' ##强引用 WESTOS=hello\ westos ##使用\转换空格 WESTOS="hello #westos" ##使用“”,批量转换 echo $WESTOS echo '$5' echo "####### $USER ######" ## 有些东西不想转移,用“ ”可以达到效果
-
声明
a=1
echo $ab
echo ${a}b
-
变量的数组
A=(1 2 3 4) echo $A ##输出数组A的第一个数 echo ${A[1]} ##输出数组的第二个数 echo ${A[*]} ##输出数组的所有值 echo ${A[@]} ##输出数组的所有值 echo ${#A[*]} ##输出数组值的个数 echo ${A[-1]} ##输出数组的最后一个值 unset A[n] ##删除数组的第N-1个值 unset a ##删除数组a #*所表示的是一串字符“1 2 3 4” @表示“1”“2”“3”“4”
linux中命令的别名设定
alias xie='vim' ##临时设定
vim ~/.bashrc
alias xie='vim'
source ~/.bashrc
xie ~/.bashrc ##当前设定只是针对此用户
vim /etc/bashrc
alias xie='vim'
source /etc/bashrc ##针对系统所有用户生效
unalias xie ##删除当前环境中的alias需要将文件中的内容删除且使用
用户环境变量的更改
用户环境变量:用户在执行命令的时候,他默认识别到的能够执行命令所在系统的位置。
我们在执行一些脚本的时候不需要加路径,如ll、ls等,这是因为环境变量中有bin这个目录,/bin实际上是一个链接,真实的是usr下面的bin。
echo $PATH ##查看环境变量
如果我们想把mnt加在环境变量中
vim ~/.bash_profile
export PATH=$PATH:/mnt ##在原始的基础上加mnt
source ~/.bash_profile
echo $PATH ##查看环境变量
westos.sh
java在Windows中安装之后需要配置环境变量,在java里面用的命令,需要被告诉路径。不能直接指定这个盘执行这个命令,否则你就只能安装在这个盘中,所以要配置环境变量。
如何在Linux中安装?
vim westos.java
public class westos{
public static void main(String args[]){
System.out.println("hello westos");
}
}
dnf install java-11-openjdk.x86_64 java-11-openjdk-devel -y
rpm -ql java-11-openjdk ##查看安装位置
java westos.java ##此时不能运行
vim java.sh ##编辑环境变量
export JAVA_HOME=/usr/lib/jvm/jre-openjdk
export PATH=$PATH:$JAVA_HOME
export CLASSPATH=.:$
source java.sh
java westos.java
脚本中的传参
设定脚本函数的时候,我们许多变量都是用命令截取到的
-
在脚本中执行的时候,如何让某些命令先执行?
TIME=$(date) ##定义函数 echo $TIME TIME=($(date)) ##定义数组,$()只能在shell中使用 echo $TIME echo ${TIME[3]} TIME=(`date`) ##定义数组,通用,很多语言中都可以使用。 echo ${TIME[-1]} unset TIME ##删掉TIME的赋值
-
传参:交互式和非交互式
非交互式:输出的时候没有任何的提示,如ls
交互式:输出的时候有提示,如passwd非交互式 vim westos.sh echo '$0' is $0 echo '$1' is $1 echo '$2' is $2 echo '$3' is $3 echo '$#' is $# ##脚本后面所跟字符串的个数 echo '$*' is $* ##所有,一串字符 echo '$@' is $@ ##所有,三串字符 sh westos.sh sh westos.sh linux 交互式 read -p "please input forward :" -s WESTOS echo -e "" echo $WESTOS
练习题:
-
题目
sh ctrl_user.sh
Useage: $0 create | delete !!sh ctrl_user.sh create
Please input username: user1
user1 is exist
Please input password:无回显
用户user1会被建立并设定其密码为以上输入的密码sh ctrl_user.sh delete
Please input username: user1
user1 is not existuser1存在
userdel -r user1
user1 is deleted -
解答:
[ "$1" != "create" -a "$1" != "delete" ] && { echo "Useage: $0 create | delete !" exit }||{ [ "root" != "$USER" ] && { echo "Error: Please running $0 with root!!" exit } } [ "$1" = "create" ]&&{ read -p "Please input username: " USERNAME id $USERNAME &> /dev/null &&{ echo "$USERNAME is exist" }||{ read -p "Please input password: " -s PASSWORD echo "" useradd $USERNAME echo $PASSWORD | passwd --stdin $USERNAME &> /dev/null && echo $USERNAME is created } }||{ read -p "Please input username: " USERNANE id $USERNAME &> /dev/null &&{ userdel -r $USERNAME && echo "$USERNAME is deleted" }||{ echo "$USERNAME is not exist" } }
脚本函数
可以用一串字符来表示一个动作
vim westos.sh
echo -e "\033[31mhello\033[0m"
sh westos.sh
能否把这个命令做成显示不同颜色的?
echo -e "\033[$1m$2\033[0m" ##$1表示第一个字符是颜色的设定命令,$2表示第二个字符是显示的内容
传参,如此只能使用脚本的时候把颜色带进去。
chmod +x westos.sh
vim check.sh
id $1 &> /dev/null && {
/mnt/westos.sh 32 "$1 is exist"
}||{
/mnt/westos.sh 31 "$1 is not exist"
}
sh check.sh li
函数?在脚本中设定一个字符串,等于一个语句块或者等于一个程序来执行。把复杂的过程抽离出来。
如何将上述两个文件放在一个文件中?
vim check.sh
ECHO()
{
echo -e "\033[$1m$2\033[0m"
}
id $1 &> /dev/null && {
ECHO 32 "$1 is exist"
}||{
ECHO 32 "$1 is not exist"
}
sh check.sh li
函数可以使得脚本一直循环起来
vim check.sh
ECHO()
{
read -p "Please input word: " WORD
[ "$WORD" = "exit" ] &&{
exit
}||{
echo $WORD
ECHO
}
}
ECHO
练习题
-
检测文件类型
CHECK () { [ $1 "$2" ]&&{ echo "$2 is $3!" exit } } [ -z "$1" ]&&{ echo "Error: please input following $0" exit }||{ [ ! -e "$1" ]&&{ echo "$1 is not exist!" }||{ CHECK -L $1 link CHECK -f $1 file CHECK -d $1 directory } }
-
第二题
题目:sh create_user.sh Please input username:westos westos exit -------<output>----> westos is exist ----->Please input username; westos not exist -------please input password:无回显密码 此用户会自动建立并且密码为提示后设定的密码 并显示:westos is created 并再次提示:Please input username: 当please input username:exit 此脚本退出
答案:
USER_CREATE() { read -p "please input username :" USERNAME [ "$USERNAME" = "exit" ] &&{ exit }||{ id $USERNAME &> /dev/null &&{ echo "$USERNAME is exist" USER_CREATE }||{ read -p "please input password: " PASSWD echo " " useradd $USERNAME echo $PASSWD | passwd --stadin $USERNAME &> /dev/null && echo "$USERNAME is created" USER_CREATE } } } USER_CREATE