Shell 编程日记

  • A+
所属分类:系统文档

Shell 脚本语法

Shell 编程日记

  • Shell 解释器
名称 路径 简介
Bourne Shell /usr/bin/sh或/bin/sh Bourne shell是AT&T开发的原始UNIX shell
以其开发人员Stephen Bourne命名,Bourne shell也以其程序名sh闻名
Bourne Again Shell /usr/bin/bash bash是大多数Linux系统以及Mac OS X默认的shell
Bash 可以说是bourne shell增强版
C Shell /usr/bin/csh C Shell Bill Joy于20世纪80年代早期,在Berkeley的加利福尼亚大学开发了C shell;
主要是为了让用户更容易的使用交互式功能,并把ALGOL风格的语法结构变成了C语言风格
Korm Shell /usr/bin/ksh 贝尔实验室的David Korn在上世纪80年代初开发
基于Bourne shell的源代码发展而来,向后兼容的Bourne Shell,包括C shell的诸多特性
....
  • Shell 脚本执行顺序依旧遵循“从上往下、从左往右”的顺序;
  • Shell 脚本就是把一些命和运算符写进脚本文件,然后完成批量重复性工作而已;
  • Shell 脚本支持流程控制,如 forwhileif 等语句控制;
  • Shell 脚本句末无须标点符号标记,换行即表示语句结束;
  • Shell 脚本严格区分大小写,a 和 A 是完全不同的两个字符串;
  • Shell 脚本通常的以 /usr/bin/bash 开头,必须以此句开头,表示 shell 脚本解释器;
  • Shell 脚本注释用 # 开头,但第一句除外/usr/bin/bash
  • Shell 脚本通常以 .sh 为后缀命名,约定成俗;
  • Shell 脚本调试可以使用 bash -x xx.sh 运行脚本,系统会打印出每一条语句及执行结果;

Shell 基础语句

语样 描述 例子
001 echo "string" 打印(输出/显示)内容 打印 Hellow Shell 到屏幕
echo "Hellow Shell."
002 > 重定向输出(不追加,会覆盖前面已有的内容 把 Hellow Shell 输出到 test.txt 文档
echo "Hellow Shell." > test.txt
003 >> 追加重定向输出(末行追加,不覆盖前面已有的内容 把 Hellow Shell 输出到 test.txt 文档
echo "Hellow Linux." >> test.txt
004 < 重定向输入
005 `` 命令替换,先运行``里面的命令,然后把结果赋给变量 把时间赋值给DATE 变量
DATE=\`date +%T\`
006 &dollar;() 命令替换,等同于\`\`,但推荐使用$() 把时间赋值给DATE 变量
DATE=$(date +%T)
007 &dollar;{} 变量引用,推荐 声明变量 T 并打印输出到屏幕
T=&dollar;(ls -l)
echo ${T}
008 &#124 管道符,把前一个命令执行的结果作为后一个命令的输入 查看文件 test.txt 并统计行数
cat test.txt &#124 wc -l
009 (()) 双括号一般用于计算
val++ :后增
val-- : 后减
++val : 先增
--val : 先减
! : 逻辑求反
~ : 位求反
** : 幂运算
<< : 左位移
>> : 右位移
& : 位布尔和
&#124 : 位布尔或
&& : 逻辑和
&#124&#124 : 逻辑或
计算5+3
(( 5 + 3 ))
010 [[]] 支持模式匹配,支持正则表达式(不是所有的shell都支持[[]] ...

Linux 退出状态码

状态码 描述
0 命令成功结束
1 一般性未知错误
2 不适合的shel命令错误
126 命令不可执行
127 没有找到相关命令
128 无效的退出参数
128+x 与Linux信号x相关的严重错误
130 通过Ctrl+C终止
255 正常范围之外的退出状态码

数组相关

  • 数组定义

定义数组建议“见名知意”,元素之间用空格分隔,数组元素下标从 0 开始

arry_name=(value1 value2 value3 ...)     // 格式1,适用于元素较少情况

arry_name=(
  value1
  value2
  value3
  ...
)     // 格式2,适用于元素较多情况
  • 数组元素操作

需要注意数组的作用域,博主就遇到数组作用域问题

arry_sname=(zhangsan lisi wangwu zhaoliu)  // 定义数组 arry_sname
echo ${arry_sname[0]}                      // 打印第一个元素
echo ${arry_sname[*]}                      // 打印所有元素
echo ${arry_sname[@]}                      // 打印所有元素
echo ${#arry_sname[*]}                      // 打印数组长度
echo ${#arry_sname[@]}                      // 打印数组长度
  • 素组元素修改
arry_sname[3]=value4                      // 添加新的元素,如果下标元素存在,则值会被替换
unset arry_sname[3]                       // 删除下标为3的数组元素
unset arry_snme                           // 删除数组

Shell 测试语句

在Shell 脚本中,表达式要 [] 括起来,且表达式两边均要有空格

  • 数值比较
比较表达式 描述
n1 -eq n2 n1 = n2
n1 -ge n2 n1 >= n2
n1 -gt n2 n1 > n2
n1 -le n2 n1 <= n2
n1 -lt n2 n1 < n2
n1 -ne n2 n1 ≠ n2
  • 字符串比较
比较表达式 描述
str1 = str2 str1 = str2
str1 != str2 str1 ≠ str2
str1 < str2 str1 < str2
str1 > str2 str1 > str2
-z str1 str1 长度非0
-n str1 str1 长度为0
  • 文件比较
比较表达式 描述
-d file file 是否存在且是一个目录
-e file file 是否存在(目录或文件)
-f file file 是否存在且是一个文件
-r file file 是否存在且可读
-s file file 是否存在且非空
-w file file 是否存在且可写
-x file file 是否存在且可执行
-o file file 是否存在且所有者属于当前用户
-G file file 是否存在且默认组与当前用户组相同
file1 -nt file2 file1 是否比 file2 新
file1 -ot file2 file1 是否比 file2 旧

Shell 流程控制语句

  • IF 语句
// 单条件
if 条件;then
   命令1
   命令2
   ....
fi

---------------------------

// 双条件

if 条件;then
   命令1
   命令2
   ....
else
   命令3
   命令4
   ....
fi

---------------------------
// 多条件

if 条件1;then
   命令

elif 条件2;then
   命令

elif 条件3;then
   命令

else
   命令
fi
  • While 语句
// while 从某种意义上来讲,可以说是 if-then 语句和 for 循环的混杂体
// while 语句中,只有当测试条件为 true 时,才会不断循环下去,直至遇到 false
while 测试条件
do
    命令
done
  • For 语句
// for 语句是按行逐一遍历数据,以回车换行为分割
// list 支持命令,支持变量引用
// for 循环默认会以空格换行,所有如果你的行有空格的话
// 在 for 循环前,设置换行符(其它符号类似) IFS.old=$IFS;IFS=$'\n'
// 同时在 for 循环完成后,记得还原 IFS=$IFS.old
for var in list
do 
    命令
done


// Bash for 语句支持C语言风格,注意空格
for (( i=1;i<10;i++ ))
do
   命令
done

// for 支持多变量,注意空格
for (( i=1,j=10;i<10;i++,j-- ))
do
   命令
done
  • case 语句
case 变量 in
    值a)
       代码 A
      ;;
    值b)
       代码 B
      ;;
    值c)
       代码 C
      ;;
    *)
       代码 D
      ;;
esac

Shell 函数创建与调用

  • 函数创建(function)
// 语法格式,其中 function可以省略,但是建议标准化格式
function name {
    命令
    内容
}
  • 函数调用
// 调用函数,直接写函数名即可
test

sed、awk 用法

  • sed 编辑器(流编辑器)
// sed 常见用法
// 常规替换字符,默认情况只替换第一次匹配到的字符串
sed 's/str_old/str_new' file

// 按要求替换(flag)
sed 's/str_old/str_new/3' file  // 匹配到的第三处替换,3 是需要替换的第几次匹配到的意思
sed 's/str_old/str_new/g' file  // 匹配到全文替换
sed '2s/str_old/str_new' file  // 按行匹配替换:匹配第二行内容,并替换
sed '2,3s/str_old/str_new' file  // 从第二行开始匹配,到第三行结束,并替换
sed '2,$s/str_old/str_new' file  // 从第二行开始全文匹配,并替换

// 删除行操作
sed '5d' file  // 删除文件 file 第 5 行内容
sed '2,7d' file // 删除文件 file 第 2~7 行内容
sed '7,$d' file // 删除文件 file 第 7 行以后所有的行

// 插入操作,如果使用变量,请使用双引号
sed -i "Line i str" file  // 在 Line行前插入 str(新行),i 前可以加数字(3i)表示第几行前插入
sed -i 'Line a str" file  // 在 Line行后插入 str(新行),a 前可以加数字(3a)表示第几行后插入

// 追加操作


Shell 小技巧/样例

  • 跳出循环语句
// 跳出当前循环
break

// 跳出指定循环,n 是循环层级
break n
  • 关键字匹配(涉及正则表达式)
// 匹配关键字信息,str1 字符串包含 str2 内容
[[ str1 =~ str2 ]]
  • 字符串替换
// 字符串替换,如果末尾加 /g 表示全部替换
var1='abc123'
var=${var1/'bc1'/'BC1'}
  • EOF 格式化输出
// 格式输出到指定文件,EOF 只是标记,不是关键字
cat >> test.txt <<EOF
    内容
    命令
EOF
  • 提示并接收用户输入数据
// read 可以接收用户输入的内容,把用户敲入的用户赋值给 username
read -p "请输入用户名:" username

// 设置等待输入超时
read -t 5 -p "请输入用户名:" username


// 隐藏模式输入,如 Linux 输入密码一样
read -s -p "请输入密码:" userpasswd
  • Shell 多进程示例
  • 正则表达式
待更新...
  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: