yuanxiaojiang
人的放纵是本能,自律才是修行

 

Shell命令解释器

命令解释器  
bash 应用最广泛,默认在红帽系列和Debian/Ubuntu使用
dash Debian/Ubuntu 系统的默认命令解释器
csh、tcsh 一些unix系统使用
zsh 功能更强大,支持更多插件,界面美观

编程语言分类

解释型(直接解析类):shell、python、php 书写成文件后,可以通过对应的解释器直接运行

编译型(需要编译才能运行):C、C++、Java、Golang 下载好源代码,必须要进行编译生成可以运行的命令

vim优化

# 修改vimrc文件,达到控制vim创建、编辑文件的动作
    # 当前用户生效:追加到当前用户目录下 ~/.vimrc
    # 全局生效:追加到/etc/vimrc

set ignorecase  
autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()"  
func SetTitle()  
    if expand("%:e") == 'sh'  
        call setline(1, "#!/bin/bash")  
        call setline(2, "#########################################")  
        call setline(3, "# File Name: " . expand("%"))  
        call setline(4, "# Version: V1.0")  
        call setline(5, "# Author: yuanxiaojiang")  
        call setline(6, "# Organization: https://www.cnblogs.com/yuanxiaojiang")  
        call setline(7, "# Desc:")  
        call setline(8, "#########################################")  
    endif  
endfunc  

#! 符号含义

用于指定脚本默认的命令解释器

命令解释器 写法
bash #!/bin/bash
python #!/usr/bin/python2 或 #!/usr/bin/env python2

shell脚本执行方式

执行方法 应用
通过sh或bash⭐⭐⭐ 最常用的执行方式(非红帽系统中,建议使用bash 运行脚本
通过.(点)或source⭐
加载/生效配置文件(环境变量,别名) /etc/profile
常用:可以用来实现include功能,把其他脚本引入到当前脚本中
通过相对或绝对路径
不推荐使用(用于系统脚本/服务调用脚本,脚本需要加上执行权限才能使用)
输入重定向符号
不推荐使用

sh或bash

[root@m01 ~]# cat /server/scripts/show_info.sh 
hostname 
whoami
[root@m01 ~]# sh /server/scripts/show_info.sh 
m01
root

. 或 source

[root@m01 ~]# . /server/scripts/show_info.sh 
m01
root
[root@m01 ~]# source /server/scripts/show_info.sh 
m01
root

相对或绝对路径

# 给脚本加上执行权限,系统/服务调用某个脚本时使用
[root@m01 ~]# chmod +x /server/scripts/show_info.sh
[root@m01 ~]# /server/scripts/show_info.sh
m01
root
[root@m01 /server/scripts]# ./show_info.sh
m01
root

使用重定向符号执行脚本

[root@m01 ~]# sh </server/scripts/show_info.sh 
m01
root

 

变量

变量分类

分类 说明
普通变量(局部变量) 在脚本中写的通常是普通变量
环境变量(全局变量) 一般有系统创建(PATH、PS1)
特殊变量 shell编程的核心

环境变量

# /etc/profile:用于永久配置用户环境变量和启动程序的脚本文件,主要在用户登录时被执行
#
env:用于显示当前的环境变量 # export:用于将一个shell变量标记为环境变量,创建全局变量 # declare:用于声明一个变量并设置其属性 declare MY_VAR="Hello, World!" # 声明普通变量 declare -x MY_ENV_VAR="I am an environment variable" # 声明环境变量 declare -r MY_READONLY="Cannot change me" # 声明只读变量
环境变量名字
含义
应用场景
PATH
记录命令位置的环境变量,运行命令的时候bash会在PATH的路径中查找
通过二进制包或编译安装软件,增加新的命令路径
LANG
系统语言与字符集
修改语言字符集
PS1
命令行格式
修改命令行格式,生产环境不推荐修改
UID或EUID
用户的uid
用于判断当前用户是否为root
HOSTNAME
主机名
 
PROMPT_COMMAND
存放命令,命令行执行命令后会运行这个变量的内容,用于实现行为审计(记录用户操作)
行为审计
HISTSIZE
内存中保留的历史命令数量
未来安全优化配置
HISTFILESIZE
历史记录文件(~/.bash_history)的大小
未来安全优化配置
HISTCONTROL
控制如何记录历史命令
未来安全优化配置
HISTFILE
指定历史命令记录文件的位置和名称 未来安全优化配置
TMOUT
超时自动跳出时间 未来安全优化配置

 

环境变量相关文件及其目录 

~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该 

文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件. 

~/.bashrc:该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该 

该文件被读取. 

环境变量文件加载顺序

文件或目录 作用 启动时间
/etc/profile 系统级配置文件,用于为所有用户设置环境变量和启动程序(该文件通常会调用/etc/profile.d/目录中的所有脚本) 用户登录到系统时启动 
/etc/bashrc 系统级配置文件,用于设置交互式非登录特性和其他配置(别名、函数的定义) 打开新的交互式shell 
~/.bashrc 特定用户的配置文件   用户打开新的终端窗口或执行新的 Bash shell 时,会读取此文件
~/.bash_profile 用户登录时执行的脚本,主要用于设置用户特定的环境变量   
/etc/profile.d 存放用户自定义或者系统级的脚本 登录时执行该目录中的所有脚本

登录shell(通过ssh或tty登录)

/etc/profile(/etc/profile.d)

~/.bash_profile

~/.bashrc

/etc/bashrc

 

案例:书写脚本每次用户登录后显示系统的基本信息

 

# 未来通过软连接来实现该功能
ln -s /server/scripts/devops_shell/sys_login_info.sh /etc/profile.d/sys_login_info.sh
cat /server/scripts/devops_shell/sys_login_info.sh
sys_hostname=`hostname`
sys_ip_addrs=`hostname -I`
sys_mem_total=`free -h|awk 'NR==2{print $2}'`
sys_mem_free=`free -h|awk 'NR==2{print $NF}'`
sys_load=`w |awk 'NR==1{print $(NF-2) $(NF-1) $NF}'`

# 输出
cat <<EOF
    主机名:${sys_hostname}
    IP地址:${sys_ip_addrs}
    总内存:${sys_mem_total}
    可用内存:${sys_mem_free}
    系统负载:${sys_load}
EOF

 

特殊变量

特殊变量-位置变量

位置的特殊变量 含义 应用场景
$n (数字) 脚本的第n个参数 命令行与脚本内部桥梁
$0 脚本的名字 用于输出脚本的格式或帮助时
$# 脚本参数的个数 一般与判断结合,检查脚本参数个数
$@  $* 取出脚本所有的参数,$*加上双引号会将所有的参数合并为一个参数 数据或循环

案例:判断指定的用户是否存在

[root@m01 ~]# cat /server/scripts/devops-shell/check_user.sh
if [ $# -ne 1 ];then
  echo "输入格式正确"
  exit 1
fi
username=$1
if id ${username} &>/dev/null;then
  echo "用户${username}存在"
else
  echo "用户${username}不存在"
fi
[root@m01 ~]# sh /server/scripts/devops-shell/check_user.sh root
用户root存在

 

面试题:$n(n>9)输出结果

$1 = root
$10 --> $1+0 --> 取$1的值后面拼接0  root0
$11 --> $1+1 --> 取$1的值后面拼接1  root1

 

案例:输出脚本所有参数和参数个数

[root@m01 /server/scripts/devops-shell]# cat 01.sh 
for age in "$@";do
    echo "$age"
done
for age in "$*";do  # $*加上双引号会将所有的参数合并为一个参数
    echo "$age"
done
echo $#

[root@m01 /server/scripts/devops-shell]# sh 01.sh yuan xiao jiang
yuan
xiao
yuan xiao
3

 

 

特殊变量-状态变量

状态的特殊变量 含义 应用场景
$?
上一个命令、脚本的返回值,0表示正确,非0即错误
一般与判断检查命令
结果。
$$
当前脚本的pid
一般写在脚本中获取
脚本pid
$! 上一个脚本/命令(持续运行)的pid  
$_
上一个命令的最后一参数,其实下划线是个环境变量,记录了上一个命令、脚本的
最后一个参数. 使用esc+ .(点)
 

特殊变量-变量子串

变量子串(parameter表示变量名字) 含义
${parameter} 变量取值
${#parameter} 统计变量字符长度
删除开头、结尾(word表示要删除的内容)  
${parameter#word}
从变量左边开始删除,按照最短匹配删除
${parameter##word}
从变量左边开始删除,按照最长匹配删除
${parameter%word}
从变量右边开始删除,按照最短匹配删除
${parameter%%word}
从变量右边开始删除,按照最长匹配删除
截取(切片):类似于cut -c  
${parameter:5} 从下标为5的字符开始向后截取
${parameter:5:2}
从下标为5的字符开始向后截取2个字符
替换  
${parameter/word/replace}
把word替换为replace 仅替换第1个
${parameter//word/replace}
把word替换为replace 替换全部
[root@m01 ~]# var=yuanxiaoyuan996
[root@m01 ~]# echo ${var#yuan}
xiaoyuan996
[root@m01 ~]# echo ${var#*yuan}
xiaoyuan996
[root@m01 ~]# echo ${var##*yuan}
996
[root@m01 ~]# echo ${var#*an}
xiaoyuan996


# 取出文件名
[root@m01 ~]# echo ${dir##*/}
ifcfg-eth0
# 取出路径名
[root@m01 ~]# echo ${dir%/*}
/etc/sysconfig/network-scripts
[root@m01 ~]# dirname $dir
/etc/sysconfig/network-scripts
[root@m01 ~]# basename $dir
ifcfg-eth0

# 面试题:I am English teacher welcome to English teacher training class.
for循环打印下面这句话中字母数不大于6的单词

[root@m01 /server/scripts/devops-shell]# cat 02.sh
content="I am English teacher welcome to English teacher training class."
content_new=`echo ${content} |sed 's#\.##g'`

for word in $content_new
do
if [ ${#word} -le 6 ];then
echo "单词字符数<=6:${word}"
fi
done

[root@m01 /server/scripts/devops-shell]# sh 02.sh
单词字符数<=6:I
单词字符数<=6:am
单词字符数<=6:to
单词字符数<=6:class

[root@m01 /server/scripts/devops-shell]# echo ${content} |sed 's#\.##g' |xargs -n1 |awk -F"[ ]" 'length($1)<=6'
I
am
to
class

特殊变量-变量扩展(设置默认值)

格式 含义
${parameter:-word}
变量parameter没定义或为空,把word作为默认值输出,不修改变量内容
${parameter:=word}
变量parameter没定义或为空,把word作为默认值输出,修改变量内容
${parameter:?word}
变量parameter没定义或为空,把word作为默认值输出并输出错误,不修改变量内容
${parameter:+word}
变量parameter没定义或为空,不做任何操作(不输出),否则将变量内容替换成word

变量赋值

赋值方法 格式 应用场景
直接赋值 var=yuanxiaojiang 绝大部分场景使用
命令结果赋值 hostname=`hostname` 获取命令的结果:``或$()
脚本传参(通过脚本命令行传参进行赋值) user_name=$1(脚本的第一个位置参数) 用于将命令行内容传入脚本
read交互式赋值(读取文件内容赋值给变量) 通过read命令实现 用户交互
-p
交互的时候提示信息
-t
超过这个时间没有操作,则自动退出
-s
不显示用户的输入.记录密码才用

 

 

[root@m01 ~]# read -p "请输入密码:" pass
请输入密码:123
[root@m01 ~]# echo $pass
123
# 同时交互赋值
[root@m01 ~]# read -p "请输入两个数字num1 num2:" num1 num2
请输入两个数字num1 num2:1 2
[root@m01 ~]# echo $num1,$num2
1,2

 

shell编程运算

运算符

算数运算符 +  -  *  /  %  ^或** 用于执行基本的数学运算
关系运算符
  • -eq:等于 =
  • -ne:不等于 !=
  • -gt:greater than >
  • -lt:less than <
  • -ge:greater than or equal to >=
  • le:less than or equal to <=
用于比较两个值,返回真或假
逻辑运算符
  • &&  前一个命令执行成功,再执行后面的命令(判断)
  • ||     前一个命令执行失败了,再执行后面的命令(判断)
  • !
用于逻辑运算,通常与条件判断结合使用
位运算符
  • & : 按位与
  • | : 按位或
  • ^ : 按位异或
  • ~ : 按位取反
  • << : 左移
  • >> : 右移
用于执行位级的操作
文件测试运算符
  • -e : 文件存在
  • -f : 是文件
  • -d : 是目录
  • -r : 可读
  • -w : 可写
  • -x : 可执行
检查文件的属性
字符串操作运算符 
  • = : 字符串相等
  • != : 字符串不相等
  • < : 字符串小于
  • > : 字符串大于
  • # : 字符串长度
  • ${string1}${string2} : 字符串连接
用于字符串的比较和连接

运算方法

运算命令/符号 说明 应用场景
awk 可以进行计算(带小数),可以与shell脚本进行变量传递 一般计算都可以使用awk
bc 用于执行任意精度的算数运算的命令行计算器 一般计算都可以使用bc(需要安装)
expr
用于执行简单整数算数运算、字符串操作、逻辑操作的命令
一般用于检查输入内容是否位数字
let
进行计算,整数,变量直接使用即可
 
$(())
进行计算,整数,变量直接使用即可
 
$[]
进行计算,整数,变量直接使用即可
 

awk计算

# 基础用法
    [root@m01 ~]# awk 'BEGIN{print 1/3*100}'
    33.3333
# 在awk中使用shell变量
    awk -v选项用于创建或修改awk中的变量(-v使shell脚本与awk的桥梁)
    [root@m01 ~]# num=2
    [root@m01 ~]# awk -v n1=1 -v n2=$num 'BEGIN{print n1/n2}'
    0.5
    在awk中变量直接使用即可,不要加上$n1,如果加上了会被awk识别为取列

 

bc

# -l:显示小数
[root@m01 ~]# echo 5/3 |bc -l
1.66666666666666666666

 

expr

# expr算数运算符两边需要使用空格
[root@m01 ~]# expr 1+1
1+1
[root@m01 ~]# expr 1 + 1
2
[root@m01 ~]# expr 1 * 1  # *号需要使用转义字符
expr: syntax error
[root@m01 ~]# expr 1 \* 1
1

# expr进行计算的结果为0,返回值为一

[root@m01 ~]# expr 1 + 1
2
[root@m01 ~]# echo $?
0
[root@m01 ~]# expr 0 + 0
0
[root@m01 ~]# echo $?
1

 

 

案例:对输入的内容检查是否为数字

[root@m01 /server/scripts/devops-shell]# cat 03.sh 
read -p "请输入任意信息:" str
if [ "$str" = "-666" ];then
    echo "恭喜你触发了隐藏数字"
    exit 1
fi
expr "$str" + 666 &>/dev/null
if [ $? -eq 0 ];then
    echo "${str}是数字"
else 
    echo "${str}不是数字"
fi

let、$(())、$[]

[root@m01 ~]# n1=666
[root@m01 ~]# n2=999
[root@m01 ~]# let c=n1+n2
[root@m01 ~]# echo $c
1665
[root@m01 ~]# let c++
[root@m01 ~]# echo $c
1666
[root@m01 ~]# echo $((n1+n2))
1665
[root@m01 ~]# echo $[n1+n2]

 

posted on 2025-03-27 13:40  猿小姜  阅读(28)  评论(0)    收藏  举报

levels of contents