2020-09_Shell 编程笔记

2020-09_Shell 编程笔记
强烈推介IDEA2020.2破解激活,IntelliJ IDEA 注册码,2020.2 IDEA 激活码

第一章 Shell 脚本编程应用指南

1. 学习Shell编程需要掌握的基础。

  • vi/vim的熟练使用
  • Linux 常用命令的熟练使用
  • 常见 Linux 网络服务部署排错

2. Shell 脚本概念原理介绍。

shell 是一个命令解释器。它在操作系统的外层,负责直接与用户的对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕返回给用户。

3. 简单和复杂的两个 shell 脚本。

范例 1. 清除/var/log 下的 message 日志文件的简单命令脚本。

# 把所有命令放在一个文件堆积起来就形成了脚本。
# 要使用 root 身份来运行这个脚本
# 清除日志脚本
cd /var/log
cat /dev/null > messages
echo "Logs cleaned up."
# 提示:/var/log/messages 是系统的日志文件,很重要

问题:
(1) 不是 root 就无法执行清理日志。
(2) 没有任何的流程控制语句,简单的说就是顺序操作,没有成功判断和逻辑性。

范例2. 包含命令、变量和流程控制语句的清除 /var/log 下的 messages 日志文件的 shell 脚本。

#!/bin/bash
# 清除日志脚本
LOG_DIR=/var/log
ROOT_UID=0 # $UID为0的时候,用户才具有root用户的权限
# 要使用root用户来运行,中括号加空格隔开
if [ "$UID" -ne "$ROOT_UID" ]
then
    echo "Must be root ro tun this script."
    exit 1
fi
cd $LOG_DIR || {
    echo "Cannot change to necessary directory." >&2
    exit 1
}
cat /dev/null > messages && echo "Logs cleaned up."
exit 0
# 退出之前返回0表示成功返回1表示失败

扩展:清空日志及文件内容的三种方法:
[root@localhost day1]# echo >test.log # 有一空白行
[root@localhost day1]# > test.log # 重定向
[root@localhost day1]# cat /dev/null > test.log

4. Linux系统的默认脚本解释器?

Centos linux 系统默认的 shell 是 bash
查看方法:echo $SHELL 或 grep root /etc/passwd

5. shell 脚本的建立和执行

  • 脚本开头(第一行)
    一个规范的 shell 脚本的第一行会指出由那个程序(解释器)来执行脚本中的内容,在linux bash 编程中一般为:
#!/bin/bash
或
#!bin/sh < ==255 个字符以内

“#!”又被称为幻数,在执行脚本时,内核会根据"#!"后的解释器确定该用哪个程序解释脚本中的内容。注意:这一行必须为每个脚本顶端的第一行。
sh 为bash的软链接。

如果为python,则第一行为,执行如:python test.py执行

#!/usr/bin/env python

6. shell脚本开发基本规范及习惯

(1) 开头指定脚本解释器

#!bin/sh 或 #!/bin/bash

(2) 开头加版权等信息

#Date: 16:29 2020-3-30
#Author: Created by oldboy
#Mail: 48000448@qq.com
#Function: This scripts function is....
#Version: 1.1

提示:可配置vim编辑文件时自动加上以上信息,方法是修改~/.vimrc 配置文件。

(3) 脚本不用中文注释
尽量使用英文注释防止本机或切换系统环境后中文乱码的困扰。

(4) 脚本以.sh为扩展名

(5) 代码书写习惯优秀
I. 成对的符号内容一次写出来,防止遗漏,如:{},[],’’,""
II. [] 中括号两端要有空格,书写时即可留出空格[ ]
III. 流程控制语句一次性书写完,在添加内容,如:
if 语句格式一次完成:
if 条件内容
then
内容
fi
for 循环格式一次完成:
for
do
内容
done

(6) 通过缩进让代码易读

第二章 Shell 变量基础及深入

1. 环境变量

环境变量用于定义 Shell 的运行环境,保证 Shell 命令的正确执执行。家目录下的.bash_profile文件中或全局配置/etc/bashrc,/etc/profile,/etc/profile.d中定义。
登录显示加载内容可以放在/etc/profile.d目录下。

传统上,所有的环境变量均为大写。环境变量应用于用户进程前,必须用export命令导出。

用 evn 或 set 显示默认环境变量。unset 消除本地变量和环境变量。

2. 局部变量

I. 普通字符串变量定义:
变量名=value; 变量名=‘value’; 变量名=’'value"

II. 命令变量:
变量名=``; 变量名=$()

习惯:数字不加引号,其他默认加双引号。

单引号:看到的是什么就会输出什么。
双引号:把双引号内的所有内容都输出出来,如果内容中有命令,变量,特殊转义,会先解析出命令结果,然后在输出最终内容来。
无引号:一般连续的字符串,数字i,路径等可以不加引号。不过最好情况用双引号替代之。

3. 特殊变量

I. 位置变量
$0 获取当前执行的 shell 脚本的文件名,包括脚本路径,如
dirname $0 # 文件路径
basename $0 # 文件名字

n 获 取 当 前 执 行 的 s h e l l 脚 本 的 第 n 个 参 数 值 , n = 1..9 , 当 n 为 0 时 表 示 脚 本 的 文 件 名 , 如 果 n 大 于 9 , 则 n 获取当前执行的 shell 脚本的第 n 个参数值,n=1..9, 当 n 为 0 时表示脚本的文件名,如果n 大于9,则 nshellnn=1..9,n0n9{10}

$# 获取当前 shell 脚本命令行中参数的总个数

企业案例:控制用户传的参数个数

[ $# -ne 2 ] && {
    echo "must two"
    exit 1
}
echo oldgirl

$$ 获取当前 shell 的进程号

$? 获取执行上一个指令的返回值(0为成功,非0为失败)

(1)应用案例:当系统中只能有某个脚本同时只能运行一个进程的时候

# pid.sh 脚本文件
[root@localhost scripts]# cat pid.sh
#!/bin/sh
pidPath=/tmp/a.pid
if [ -f "$pidPath" ]
   then
      kill -USR2 `cat $pidPath`
      rm -f $pidPath
fi
# script pid write to $pidPath
echo $$ >$pidPath
sleep 300

# 查看进程
[root@localhost scripts]# ps -ef|grep pid.sh|grep -v grep
root      1758  1457  0 10:03 pts/0    00:00:00 sh pid.sh

4. 变量的数值计算

常用计算命令:(())、let、expr、bc(小数)、$[]
I. (()))用法

[root@localhost scripts]# ((a=1+2**3-4%3))
[root@localhost scripts]# echo $a
8
[root@localhost scripts]# b=$((1+2**3-4%3))
[root@localhost scripts]# echo $b
8
[root@localhost scripts]# echo $((3>2))
1
[root@localhost scripts]# echo $((3<2))
0

范例:一次计算一个(非混合运算),即传参传两个数,传一个计算符号,出结果。

[root@localhost scripts]# cat d.sh
echo $(($1$2$3))
[root@localhost scripts]# sh d.sh 3*2
6

II. let 用法

[root@localhost scripts]# i=2
[root@localhost scripts]# let i=i+8
[root@localhost scripts]# echo $i
10
[root@localhost scripts]# i=2
[root@localhost scripts]# i=i+8
[root@localhost scripts]# echo $i
i+8

III. expr 用法

[root@localhost scripts]# expr 2 + 2
4
[root@localhost scripts]# expr 2+2
2+2
[root@localhost scripts]# expr $[2*3]
6
[root@localhost scripts]# expr $[2/3]
0

IIII. read 用法

# -t timeout 设置输入等待的时间,单位默认为秒。
# -p prompt  设置提示信息
[root@localhost scripts]# read -t 5 -p "pls input:" a
pls input:1
[root@localhost scripts]# echo $a
1

第三章 分支与循环结构

1. if 条件句

# 单分支
if [条件]
  then
    指令
fi

# 双分支
if 条件
  then 
    指令集
else
    指令集
fi

# 多分支
if 条件
  then 
    指令
elif  条件
  then 
    指令
    ...
else
    指令
fi   

特殊写法:if [-f “$file1”]; then echo 1;fi 相当于: [-f “file1”] && echo 1

范例1:单分支 if 条件句两个整数比较大小。

[root@localhost scripts]# cat if-single.sh
#!/bin/sh
if [ 10 -lt 12 ]
   then
       echo "yes,10 is less than 12"
fi

范例2:使用 read 及脚本传参方式如何实现上述整数的比较?

#!/bin/sh
read -p "pls input two num:" a b

if [ $a -lt $b ];then
   echo "yes,$a less than $b"
fi
if [ $a -eq $b ];then
   echo "yes,$a equal $b"
fi
if [ $a -gt $b ];then
   echo "yes,$a greater than $b"
fi

第四章 实例示范

1. 使用 for 循环在 /oldboy 目录下批量创建10个文件,名称依次为:

oldboy-1.html,oldboy-2.html,…,oldboy-10.html

[root@localhost oldboy]# cat /home/scripts/01.sh
[ ! -d /oldboy ] && mkdir -p /oldboy
for i in `seq 10`
do
  touch /oldboy/oldboy-${i}.html
done

2. 用 for 循环实现将以上文件名中的 oldboy 全部改成 linux, 并且扩展名改成大写。要求:for 循环的循环体不能出现 oldboy字符串。

[root@localhost scripts]# cat 02.sh
#!/bin/sh
cd /oldboy
for f in `ls *.html`
do
  mv $f `echo $f|sed 's#oldboy#linux#g'|sed 's#html#HTML#g'`
done

3. 批量创建 10 个系统账号 oldboy01-oldboy10 并设置密码(密码不能相同)。

#!/bin/sh
for n in `seq -w 10`
do
  useradd oldboy$n&&\
  echo "root$n"|passwd --stdin oldboy$n
done

4. 数组定义与增删改查

[root@localhost scripts]# array=(1 2 3)
[root@localhost scripts]# echo ${#array[@]}
3
[root@localhost scripts]# echo ${#array[*]}
3
[root@localhost scripts]# echo ${array[0]}
1
本文来源jackaroo2020,由架构君转载发布,观点不代表Java架构师必看的立场,转载请标明来源出处:https://javajgs.com/archives/7019

发表评论