shell学习

本文详细介绍了Shell脚本的编程规范,包括文件扩展名、首行指定解释器、注释和空格使用。此外,还讲解了如何执行脚本,以及变量的命名规则、赋值方法和分类。内容涵盖局部变量、环境变量和特殊变量的使用。文章还涉及了`read`命令、`test`测试命令、条件控制结构(如`if`、`case`)以及循环和函数。最后,简要介绍了`cut`、`awk`和`sed`命令的用途。
摘要由CSDN通过智能技术生成

shell编程规范
脚本文件规范
1 文件的扩展名必须是.sh
2 文件的首行必须使用#!  指定脚本的shell运行环境(即脚本解释器)
	如: #!/bin/bash
3 脚本中的行注释为 #
4 指令、选项、参数之间即使有多个空格仍会被视为一个空格
5 tab键形成的空白也被视为一个空格键
6 空白行会被忽略
实例:

#!/bin/bash
# 注释
echo "hello world"

脚本文件的执行
  • 使用bash 程序来调用执行,主需要有读(r)权限即可

    sh *.sh
    bash *.sh
    
  • 直接执行脚本,需要有读执行权限(rx)

    ./*.sh
    
    chmod +x *.sh
    
  • 借助变量PATH功能

    将*.sh放入到~/bin目录下,因为PATH里拼接了~/bin目录
    注意:~/bin目录必须自行创建
    

shell中变量的用法
1 变量的命名规范

	- 命名只能使用英文字母。数字和下划线。首个字符不能是以数字开头
    - 字母习惯用大写
    - 中间不能有空格
    - 不能使用标点符号
    - 不能使用bash 里关键字

2 变量的使用规则

	- 直接定义变量名称,没有类型需要强调(x=1,y=2,z=x+y)
	- 赋值时,"="前后不能有空格
	- 命令的执行结果赋值给变量时,使用反单引号   如 T=‘data’
	- 调用变量时,必须使用$  格式: $变量名  或者 ${变量名}
变量分类
  • shell中变量分为三种:局部变量 环境变量 特殊变量
局部变量:用户自定义,在脚本中或者命令中定义
环境变量:保存和系统操作相关的数据,$HOME $PWD $SHELL $USER等
特殊变量:
		位置参数:向脚本中传递参数或者数据,变量名不能自定义,变量作用固定。
		预定义参数:是bash中已经定义好的变量,变量名,作用固定
  • 局部变量 :用户自定义变量,由字母或者下划线开头,由字母数字或者下划线序列组成,大小写字母意义不同,变量名长度没有限制

    • 变量调用时,要在变量名前面加 $
    • 习惯使用大写字母命名 ,赋值时不能在=前后加空格 变量=值
    1、定义时赋值:等号两侧不能有空格
    A=33
    
    2、将一个命令的执行结果赋值给变量
    A=`ls -l`
    A=$(ls -l)
    进行逻辑运算 $(())
    A=$((1+2))
    A=`expr 4 + 5 `
    
    3 将一个变量赋值给另一个变量
    A=$STR
    
    • 变量叠加
    A=123
    C="$A"456
    D=${A}789
    #  单引号里面的内容会全部输出,双引号会输出对应的值
    
    • 列出所有变量: set
    • 删除变量 unset A 撤销变量A 静态变量不能unset readonly B=5
    • 作用域为当前的shell环境,仅在当前的shell实例中有效
  • 环境变量: 系统设置好的,作用域: 当前shell以及所有子shell

    • 声明变量 export 变量名=变量值

    • ¥#常见配置文件如下:

      • /etc/profile 针对系统所有用户生效,此文件应用于所有用户

      • $HOME/.bash_profile 针对特定用户生效,

        $HOME 为用户的宿主目录。每次用户登录系统后,首先继承/etc/profile文件中的定义在应用bash_profile文件中的定义

  • 位置参数变量

    $n    n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,大于等于10的参数需要用大括号包含 ${10}
    $*  代表命令行中所有参数,把所有参数看成一个整体。以 “$1 $2 ... $n”的形式输出所有参数
    $@   代表命令行中所有参数,把每个参数区分对待,以“$1”“$2”...的形式输出所有参数
    $# 参数个数
    #!/bin/bash
    
    echo $1
    echo $#
    echo $2
    echo $*
    echo $@
    
    该方式可以接收命令行参数 ,传参
    
    循环输出参数
    
    #!/bin/bash
    
    echo "test \$*"
    for i in $*
    do
            echo $i
    done
    
    echo "test \$@"
    for i in $@
    do
            echo $i
    done
    
    echo "test \"\$*\""
    for i in "$*"
    do
            echo $i
    done
    
    echo "test \"\$@\""
    for i in "$@"
    do
            echo $i
    done
    输出:
    sh 2.sh 1 2 3
    test $*
    1
    2
    3
    test $@
    1
    2
    3
    test "$*"
    1 2 3
    test "$@"
    1
    2
    3
    
  • 预定义变量

    $? 执行上一个命令的返回值,执行成功,返回0,执行失败 返回非0
    $$ 当前进程号(PID)
    $! 后台运行的最后一个进程号,最近一个被放入当后台执行的进程 &
    
    vim pre.sh
    pwd > /dev/null  
    echo $$
    
    bash *.sh ; echo $?
    
read命令
  • read [选项] 值
  • read -p (提示语句) -n (字符个数) -t(等待时间,单位为秒) -s(隐藏输入)
read -t 30 -p "please input your name:" NAME
echo $NAME
read -s -p "please input your age:" AGE
echo $AGE
read -n 1 -p "please input your sex [M/F]:" GENDER
echo $GENDER

# 注意:
1、在输入时,如果输错了要删除执行ctrl+del
2、符号不要输入中文
3、NAME 与“之间要有空格
test测试命令
文件类型检测
test -e filename  # 检测filename是否存在
test -d filename  # 检测filename是不是目录
test -f filename  # 检测filename是不是普通文件
test -L filename  # 检测filename是不是软连接文件

文件属性检测
test -r filename  # 检测文件是否有可读权限
test -w filename  # 检测文件是否有可写权限
test -x filename  # 检测文件是否有可执行权限

两个文件的比较
test file1 -nt file2  # 检测file1是否比file2新
test file1 -ot file2  # 检测file1是否比file2旧
test file1 -ef file2  # 检测file1与file2是否为同一文件

两个整数比较
test n1 -eq n2  # 检测n1 n2 是否相等
test n1 -ne n2  # 检测n1 n2 是否不等
...

条件控制
  • if 条件语句-单分支
单分支if/else语句

if [ 条件判断式 ]
then 
	程序
fi
或者 
if [条件判断式] ; then
	程序
fi

eg:
#!/bin/bash
A=$1
if [ $A == "stop" ]
then
	systemctl stop firewalld
fi

  • elif多分支
#!/bin/bash
A=$1
if [ $A == "stop"]
then
	systemctl stop firewalld
elif [ $A == "start" ]
then
	systemctl start firewalld
else 
	systemctl status firewalld
fi

  • case : case 变量的值用来匹配value1 value2 等,

    匹配到后则执行后面的命令

#!/bin/bash
CMD=$1
case $CMD in 
start)
	echo "starting"
	;;
stop)
	echo "stoping"
	;;
test)
	echo "testing"
	;;
*)
	echo "Usage: {start|stop}"
	;;
esac

循环
  • for循环
遍历:
#!/bin/bash
for N in 1 2 3
do 
	echo $N
done

for ((i=0;i<=5;i++))
do
	echo "hi $i"
done

# 计算从1到100的和
#!/bin/bash
for ((i=0;i<=100;i++))
do
	sum=(($sum+$i))
done
echo $sum

for ((i=0;i<=100;i++)); do mysum=$(($mysum+$i)); done ; echo $mysum
  • while 循环
while [ expression ]
do
command
...
done

# 求1-10各个数的平方和
#!/bin/bash
num=1
while [ $num -le 10 ]   #((i<=10))
do
        sum=`expr $num \* $num`   # sum1=$(($sum * $sum))
        echo $sum
        num=`expr $num + 1`
done
函数

先定义再调用,

格式:

函数名()
{
    command1
    command2
    return 返回值变量
}

结构

[ function ] funname [()]
{
    action;
    [return int;]
}

eg:
#!/bin/bash
function start() {
    echo "starting"
}
function stop {
    echo "stop"
    return 3
}
restart() {
    echo "restarting"
}
$1; echo $?

注意:
如果函数名后面没有(),在函数名和{之间,必须要有空格
函数返回值,只能通过$?系统变量来获得,
没有return,将最后一条命令的运行结果作为返回值
return会转成数值 [0-255]
脚本调试
  • 测试脚本
#!/bin/bash
a=$1
set -x  #只对set -x 后面的代码进行调试
b=3
echo "b:"+$b
c=$a
echo $a

执行: bash -x test.sh  # 显示该脚本所有变量的值

-n 不行脚本,只检测语法的模式,将返回所有语法错误,如:函数没有正确闭合
-v 执行并显示脚本内容
cut命令
cut [选项] 文件名  默认分割符是制表符,一个制表符代表一列

选项:
-f 列号: 提取第几列
-d 分隔符: 按照指定分割符分割列

cut -f 2 aa.txt 提取第二列
cut -d ":" -f 1,3 /etc/passwd 以:分割,提取第1列和第3列
cat /etc/passwd |grep /bin/bash |grep -v root |cut -d ":" -f 1 获取所有可以登录的普通用户用户名

cut的局限性  不能分割不定长度的空格
比如 :df -h 不能使用cut分割

awk介绍
文本分析工具,将文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分在进行分析处理
语法: awk '条件1{动作1}条件2{动作2}...'文件名
条件 (Pattern)
一般关系表达式作为条件: > >= <=等
动作(Action):
格式化输出
流程控制语句
eg df -h |awk '{print \$1 "\t" \$3}' 显示第一列和第三列


FS内置变量

cat /etc/passwd |grep "/bin/bash" |awk 'BEGIN {FS=":"}{print $1 "\t" $3}'
cat /etc/passwd |grep "/bin/bash" |awk -F : '{print $1 "\t" $3}'
BEGIN在所有数据读取之前执行
sed介绍

sed: stream editor

sed是一个非交互性文本编辑器,它编辑文件或标注输入导出的文本拷贝,标准输入可能来自键盘 文本重定向 字符串或者变量,或者是一个管道的文本

sed不与初始化文件打交道,操作一个拷贝,所有改动如果没有重定向到一个文件,将输出到屏幕

sed [选项]‘[动作]’ 文件名

-n 使用安静模式,显示经过sed处理过的数据

-e 允许多点编辑

-i 直接修改读取的档案内容,不由屏幕输出

a 新增

c 替换

d 删除

i 插入

p 打印

s 查找并替换 eg 1,20s/old/new/g # 1,20 第一到20行,s/开头 /g结尾 将old换成new

sed '2p' sed.txt  显示第二行和所有数据
sed -n '2p' sed.txt  只显示第二行
sed -n '2,3p' sed.txt
df -h |sed -n '1p' 接收命令结果数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值