Linux Shell 常用操作与脚本示例详解

$[] 符号的运算

$[] 是 Shell 中用于整数运算的符号,支持加减乘除、取余及自增自减等操作

示例 1:计算 1 到 10 的总和

复制代码
 [lyk@controller bin 15:37:04]$ echo {1..10}
 1 2 3 4 5 6 7 8 9 10
 [lyk@controller bin 16:00:54]$ echo {1..10} | sed 's/ /+/g'
 1+2+3+4+5+6+7+8+9+10
 ​
 [lyk@controller bin 16:01:58]$ echo $(echo {1..10} | sed 's/ /+/g')=
 1+2+3+4+5+6+7+8+9+10=
 [lyk@controller bin 16:02:07]$ echo $(echo {1..10} | sed 's/ /+/g')=$(echo $[ $(echo {1..10}|sed 's/ /+/g')])
 1+2+3+4+5+6+7+8+9+10=55

示例 2:基础算术运算

复制代码
 [lyk@controller bin 16:03:32]$ echo $[1+1]
 2
 [lyk@controller bin 16:04:31]$ echo $[4-2]
 2
 [lyk@controller bin 16:04:36]$ echo $[2*3]
 6
 [lyk@controller bin 16:04:54]$ echo $[4/1]
 4
 [lyk@controller bin 16:04:58]$ echo $[5/2]
 2
 [lyk@controller bin 16:05:13]$ echo $[5%2]
 1
 ​
 [lyk@controller bin 16:05:19]$ count=3;echo $[(count+1)*3]  # (3+1)*3=12
 12
 [lyk@controller bin 16:05:36]$ count=3;echo $[ ++count + 3 ]# count先变成4,4+3=7
 7
 [lyk@controller bin 16:05:41]$ count=3;echo $[ count++ + 3 ]# 先算3+3=6,count再变成4
 6
 [lyk@controller bin 16:05:54]$ count=3;echo $[ --count + 3 ]# count先变成2,2+3=5
 5
 [lyk@controller bin 16:06:00]$ count=3;echo $[ count-- + 3 ]# 先算3+3=6,count再变成2
 6

案例1:统计/etc/profile文件中每个单词出现的次数,并显示数量最多的10个单词

  • 以下三种方法均用于统计 /etc/profile 中每个单词的出现次数,并显示出现次数最多的前 10 个单词(方法差异主要在 "提取单词" 的方式)
复制代码
 #方法一:用 egrep 提取纯字母单词
 [lyk@controller bin 16:06:05]$ cat /etc/profile| egrep -o '[a-zA-Z]+' | sort | uniq -c | sort -nr|head
      12 usr
       8 then
       8 if
       8 fi
       7 bin
       6 pathmunge
       6 PATH
       6 in
       6 id
       6 i
 ​
 cat /etc/profile:读取文件内容。
 egrep -o '[a-zA-Z]+':用正则提取所有纯字母单词(-o 只输出匹配的部分,[a-zA-Z]+ 匹配连续字母)。
 sort:对单词排序(为去重做准备)。
 uniq -c:统计每个单词的出现次数(-c 前缀显示次数)。
 sort -nr:按次数从高到低排序(-n 按数字排序,-r 逆序)。
 head:默认显示前 10 行。
 ​
 ​
 #方法二:用 tr 分割单词,sed 取范围
 [lyk@controller bin 16:31:35]$ cat /etc/profile | tr '[[:punct:] ]' '\n' | sort | uniq -c | sort -nr | sed -n '2,11p'
      12 usr
       8 then
       8 if
       8 fi
       7 bin
       6 pathmunge
       6 PATH
       6 in
       6 id
       6 i
       
 tr '[[:punct:] ]' '\n':将所有标点符号([:punct:])和空格替换为换行符,实现按标点 / 空格拆分单词
 sed -n '2,11p':只显示第 2 到 11 行(跳过出现次数最多的第 1 行,取接下来的 10 行)
 ​
 #方法三:用 tr 分割单词,awk 取范围
 [lyk@controller bin 16:31:38]$ cat /etc/profile | tr '[[:punct:] ]' '\n' | sort | uniq -c | sort -nr|awk 'NR>=2 && NR<=11'
      12 usr
       8 then
       8 if
       8 fi
       7 bin
       6 pathmunge
       6 PATH
       6 in
       6 id
       6 i
       
 awk 'NR>=2 && NR<=11':用 awk 筛选行号(NR 表示行号),只保留第 2 到 11 行,效果同方法二的 sed

案例2:文件 / 目录判断与操作

  • 利用 Shell 的条件判断([ ])可检查文件 / 目录属性,并执行相应操作

示例 1:判断文件是否可读取

复制代码
 # 检查是否有 /etc/shadow 的读权限,有则输出提示
 [lyk@controller ~ 16:51:39]$ [ -r /etc/shadow ] && echo i can read /etc/shadow
 # (无输出,因为普通用户没有 /etc/shadow 的读权限)
 ​
 # 检查是否没有读权限,没有则输出提示
 [lyk@controller ~ 16:51:56]$ [ ! -r /etc/shadow ] && echo i can not read /etc/shadow
 i can not read /etc/shadow
 ​
 # 普通用户无权限,故输出
 ​
 -- [ -r 文件名 ]:判断文件是否有读权限
 -- !:取反(! -r 表示 “没有读权限”)
 -- &&:逻辑与(前面条件成立时,执行后面的命令

示例 2:判断目录是否存在并操作

复制代码
 # 假设 $path 是 /tmp/data
 # 检查目录是否存在,存在则提示
 [lyk@controller ~ 16:53:06]$ [ -d $path ] && echo $path is a directory
 # (无输出,因为目录不存在)
 ​
 # 检查目录是否不存在,不存在则提示
 [lyk@controller ~ 16:53:44]$ [ ! -d $path ] && echo $path is not a directory
 /tmp/data is not a directory
 ​
 # 目录不存在则创建,并提示
 [lyk@controller ~ 16:54:03]$ [ ! -d $path ] && mkdir $path && echo 创建$path成功
 创建/tmp/data成功
 ​
 # 目录存在则删除
 [lyk@controller ~ 16:56:35]$ [ -d $path ] && rmdir $path
 ​
 # 检查目录是否已删除
 [lyk@controller ~ 16:57:12]$ ls $path
 ls: 无法访问/tmp/data: 没有那个文件或目录
 ​
 [lyk@controller ~ 16:57:19]$ [ -d $path ] && echo $path is exist
 # (无输出,因为不存在)
 ​
 # 重新创建目录后检查
 [lyk@controller ~ 16:58:16]$ mkdir $path
 [lyk@controller ~ 16:58:29]$ [ -d $path ] && echo $path is exist
 /tmp/data is exist
 ​
 ​
 [ -d 目录名 ]:判断是否为目录且存在。
 mkdir $path:创建目录。
 rmdir $path:删除空目录。

案例3:判断当前用户是否是root用户

  • 以下四种方法均用于检查执行脚本的用户是否为 root,若不是则提示并退出
复制代码
 #方法 1:用 whoami 命令判断
 [lyk@controller bin 17:24:26]$ vim 123.sh
 ​
 1 #!/bin/bash                                                                        2 [ "$(whoami)" != "root" ] && echo pls run as root. && exit
 ​
 [lyk@controller ~ 17:23:34]$ cd bin
 [lyk@controller bin 17:24:00]$ mv ~/123.sh .
 [lyk@controller bin 17:24:21]$ 123.sh
 [lyk@controller ~ 17:22:14]$ chmod +x 123.sh
 [lyk@controller bin 17:24:21]$ 123.sh
 pls run as root.
 ​
 ​
 -- $(whoami):执行 whoami 命令,获取当前用户名(root 用户返回 root)。
 -- [ "$(whoami)" != "root" ]:若用户名不是 root,则条件成立。
 -- && exit:提示后退出脚本。
复制代码
 #方法 2:用 $USER 变量判断
 [lyk@controller bin 17:25:42]$ vim 123.sh
   1 #!/bin/bash
   2 [ "$USER" != "root" ] && echo pls run as root. && exit  
   
 [lyk@controller bin 17:27:35]$ 123.sh
 pls run as root.
 ​
 -- $USER:Shell 内置变量,直接表示当前用户名(root 用户为 root)
复制代码
 #方法 3:用 $UID 变量判断
 [lyk@controller bin 17:28:28]$ vim 123.sh
   1 #!/bin/bash
   2 [ "$UID"  -ne 0 ] && echo pls run as root. && exit 
 [lyk@controller bin 17:28:27]$ 123.sh
 pls run as root.
 ​
 -- $UID:Shell 内置变量,表示当前用户的 UID(root 用户的 UID 是 0,普通用户 UID ≥ 1000)
 -- -ne 0:不等于 0(即非 root 用户)
复制代码
#方法 4:用 (()) 算术表达式判断
[lyk@controller bin 17:28:57]$ vim 123.sh
  1 #!/bin/bash                                
  2 ((UID!=0)) && echo pls run as root. && exit  
  
[lyk@controller bin 17:29:44]$ 123.sh
pls run as root.  

-- ((UID!=0)):算术表达式写法,判断 UID 是否不等于 0(非 root 用户),更简洁
相关推荐
Wy_编程2 小时前
Linux-文本搜索工具grep
linux·运维·服务器
qq998992 小时前
AAA服务器技术
运维·服务器
xujiangyan_2 小时前
linux的sysctl系统以及systemd系统。
linux·服务器·网络
iCan_qi2 小时前
【Mac】【Minecraft】关于如何在Mac上搭建基岩版MC服务器的方法
运维·服务器·macos·minecraft
ezreal_pan4 小时前
Kubernetes 负载均衡现象解析:为何同一批次请求集中于单个 Pod
运维·云原生·k8s·traefik
朱皮皮呀5 小时前
Spring Cloud——服务注册与服务发现原理与实现
运维·spring cloud·eureka·服务发现·php
xixingzhe25 小时前
多人同时导出 Excel 导致内存溢出
服务器·设计
云手机掌柜5 小时前
Tumblr长文运营:亚矩阵云手机助力多账号轮询与关键词布局系统
大数据·服务器·tcp/ip·矩阵·流量运营·虚幻·云手机
yuanpan6 小时前
ubuntu系统上的conda虚拟环境导出方便下次安装
linux·ubuntu·conda