找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2328

积分

1

好友

321

主题
发表于 7 天前 | 查看: 20| 回复: 0

Linux系统层次与Shell位置示意图

Shell 一直是类 Unix 系统的核心命令行解释器,也是 Linux 强大功能的关键体现。常见的 Shell 如 Bash、Zsh 等,不仅提供了丰富的命令,其可编程性更允许我们通过编写脚本来自动化处理日常工作,极大提升效率。下面通过 40 个示例来快速掌握 Shell 脚本编程。

1. Hello World

学习任何新语言都从“Hello World”开始。创建一个名为 hello-world.sh 的文件,并写入以下内容:

#!/bin/bash
echo "Hello World"

保存后,需要赋予文件执行权限:

$ chmod a+x hello-world.sh

运行脚本有两种方式:

$ bash hello-world.sh
$ ./hello-world.sh

脚本会输出字符串 “Hello World”。

2. 使用 echo 打印

echo 命令用于在终端打印信息,支持转义序列和输出控制。创建一个 echo.sh 脚本:

#!/bin/bash
echo "Printing text"
echo -n "Printing text without newline"
echo -e "\nRemoving \t special \t characters\n"

运行脚本查看效果。-n 选项可以取消输出末尾的换行符,-e 选项则允许解析字符串中的转义字符(如 \n 换行、\t 制表符)。

3. 使用注释

注释是编写高质量、可维护代码的基础。在 Shell 脚本中,使用 # 符号来添加单行注释。

#!/bin/bash
# 这是注释:计算两个数的和
((sum=25+35))

# 打印结果
echo $sum

这段脚本将输出数字 60。注意第一行的 #!/bin/bash 是一个特例,它称为 “shebang”,用于指定执行此脚本的解释器路径。

4. 多行注释

Shell 本身没有专门的多行注释语法,但可以通过一些小技巧实现。下面是一个名为 comment.sh 的示例:

#!/bin/bash
: '
这是一个多行注释。
本脚本用于计算数字 5 的平方。
'
((area=5*5))
echo $area

多行注释内容被包裹在 : ‘ 符号之间。

5. While 循环

while 循环用于重复执行一段代码,直到条件不再满足。查看 while.sh 脚本:

#!/bin/bash
i=0

while [ $i -le 2 ]
do
  echo Number: $i
  ((i++))
done

while 循环的基本结构如下,注意方括号 [ ] 内的空格是必需的:

while [ condition ]
do
  commands
done

6. For 循环

for 循环是另一种高效的迭代结构。下面是一个打印 1 到 10 的简单示例:

#!/bin/bash

for (( counter=1; counter<=10; counter++ ))
do
  echo -n "$counter "
done

printf "\n"

7. 接收用户输入

使用 read 命令可以获取用户的输入。

#!/bin/bash
echo -n "Enter Something:"
read something

echo "You Entered: $something"

8. If 语句

if 语句用于条件判断,其基本语法为:

if CONDITION
then
  STATEMENTS
fi

只有当条件为真时,thenfi 之间的语句才会执行。下面是一个示例:

#!/bin/bash
echo -n “Enter a number: ”
read num
if [[ $num -gt 10 ]]
then
  echo “Number is greater than 10.”
fi

如果输入的数字大于 10,则会显示输出。这里 -gt 表示大于;类似地,-lt 小于,-le 小于等于,-ge 大于等于。条件判断使用双中括号 [[ ]]

9. 使用 If Else 进行更多控制

结合 else 可以使逻辑更加完整。

#!/bin/bash

read n
if [ $n -lt 10 ];
then
  echo “It is a one digit number”
else
  echo “It is a two digit number”
fi

else 部分需要放在 if 的语句块之后,fi 之前。

10. 使用 AND 运算符

AND 运算符 && 用于检查多个条件是否同时成立。

#!/bin/bash
echo -n “Enter Number:”
read num

if [[ ( $num -lt 10 ) && ( $num%2 -eq 0 ) ]]; then
  echo “Even Number”
else
  echo “Odd Number”
fi

只有数字小于 10 并且 是偶数时,才会输出 “Even Number”。

11. 使用 OR 运算符

OR 运算符 || 在多个条件中,只要有一个为真则整体为真。

#!/bin/bash
echo -n “Enter any number:”
read n

if [[ ( $n -eq 15 || $n -eq 45 ) ]]
then
  echo “You won”
else
  echo “You lost!”
fi

只有当用户输入数字 15 45 时,才会宣布获胜。

12. 使用 Elif

elif 代表 “else if”,用于实现链式的条件判断。

#!/bin/bash
echo -n “Enter a number: ”
read num

if [[ $num -gt 10 ]]
then
  echo “Number is greater than 10.”
elif [[ $num -eq 10 ]]
then
  echo “Number is equal to 10.”
else
  echo “Number is less than 10.”
fi

13. case 条件

当条件分支较多时,使用 case 语句比多个 if-elif 更清晰。

#!/bin/bash
echo -n “Enter a number: ”
read num

case $num in
  100)
    echo “Hundred!!” ;;
  200)
    echo “Double Hundred!!” ;;
  *)
    echo “Neither 100 nor 200” ;;
esac

条件分支写在 caseesac 关键字之间。*) 模式用于匹配所有其他情况。

14. 命令行参数

直接从命令行向脚本传递参数非常有用。特殊变量 $1, $2... 可以获取这些参数。

#!/bin/bash
echo “Total arguments : $#”
echo “First Argument = $1”
echo “Second Argument = $2”

将脚本命名为 test.sh 并按如下方式调用:

$ ./test.sh Hey Howdy

$1 对应第一个参数 “Hey”,$2 对应第二个参数 “Howdy”。$# 则用于获取参数的总个数。

15. 使用名称获取参数

可以通过键值对的形式传递具名参数。

#!/bin/bash
for arg in “$@”
do
  index=$(echo $arg | cut -f1 -d=)
  val=$(echo $arg | cut -f2 -d=)
  case $index in
    X) x=$val;;
    Y) y=$val;;
    *)
  esac
done
((result=x+y))
echo “X+Y=$result”

将脚本命名为 test.sh,并如下调用:

$ ./test.sh X=44 Y=100

它将输出 X+Y=144。参数存储在 “$@” 中,脚本使用 cut 命令进行解析。

16. 连接字符串

在 Bash 中连接字符串非常简单直接。

#!/bin/bash
string1=“Ubuntu”
string2=“Pit”
string=$string1$string2
echo “$string is a great resource for Linux beginners.”

17. 字符串截取

Bash 可以通过参数展开来截取子字符串。

#!/bin/bash
Str=“Learn Bash Commands from UbuntuPit”
subStr=${Str:0:20}
echo $subStr

该脚本会输出 “Learn Bash Commands”。参数展开的格式为 ${VAR_NAME:S:L},其中 S 是起始位置(从0开始),L 是要截取的长度。

18. 使用 cut 做截取

除了参数展开,也可以用 cut 命令来截取字符串,尤其适合按分隔符处理。

#!/bin/bash
Str=“Learn Bash Commands from UbuntuPit”
#subStr=${Str:0:20}

subStr=$(echo $Str| cut -d ‘ ’ -f 1-3)
echo $subStr

这里 -d ‘ ’ 指定空格为分隔符,-f 1-3 表示取第一到第三段,输出为 “Learn Bash Commands”。

19. 添加两个值

在 Shell 脚本中进行算术运算很简单。

#!/bin/bash
echo -n “Enter first number:”
read x
echo -n “Enter second number:”
read y
(( sum=x+y ))
echo “The result of addition=$sum”

使用双括号 (( )) 来进行计算。

20. 添加多个值

使用循环可以连续获取多个用户输入并进行累加。

#!/bin/bash
sum=0
for (( counter=1; counter<5; counter++ ))
do
  echo -n “Enter Your Number:”
  read n
  (( sum+=n ))
done
printf “\n”
echo “Result is: $sum”

注意:如果不使用 (( ))+= 操作将会是字符串拼接而非数值相加。

21. Bash 中的函数

函数可以将常用代码块封装起来,提高代码复用率。

#!/bin/bash
function Add()
{
  echo -n “Enter a Number: ”
  read x
  echo -n “Enter another Number: ”
  read y
  echo “Addition is: $(( x+y ))”
}

Add

这里定义了一个名为 Add 的函数来执行加法。之后每当需要加法功能时,只需调用 Add 函数即可。

22. 具有返回值的函数

函数可以通过标准输出“返回”数据。

#!/bin/bash

function Greet() {
  str=“Hello $name, what brings you to UbuntuPit.com?”
  echo $str
}

echo “-> what’s your name?”
read name

val=$(Greet)
echo -e “-> $val”

函数 Greet 中的 echo 输出被命令替换 $(...) 捕获,并赋值给了变量 val

23. 从 Bash 脚本创建目录

Shell 脚本可以方便地调用系统命令,例如创建目录。

#!/bin/bash
echo -n “Enter directory name ->”
read newdir
cmd=“mkdir $newdir”
eval $cmd

脚本调用了 mkdir 命令。也可以使用反引号直接执行命令:

`mkdir $newdir`

24. 确认存在后创建目录

为了避免覆盖已有目录,可以先进行检查。

#!/bin/bash
echo -n “Enter directory name ->”
read dir
if [ -d “$dir” ]
then
  echo “Directory exists”
else
  `mkdir $dir`
  echo “Directory created”
fi

[ -d “$dir” ] 用于判断 $dir 是否存在且是一个目录。

25. 读取文件

使用循环可以逐行读取文件内容。

#!/bin/bash
file=‘editors.txt’
while read line; do
  echo $line
done < $file

假设 editors.txt 文件内容如下:

1. Vim
2. Emacs
3. ed
4. nano
5. Code

脚本将逐行输出这些内容。

26. 删除文件

下面的脚本会询问文件名,如果文件存在则将其删除。

#!/bin/bash
echo -n “Enter filename ->”
read name
rm -i $name

rm -i 中的 -i 选项会在删除前进行确认。输入 editors.txt 并在提示时按 y 确认,文件将被删除。

27. 附加到文件

使用重定向操作符 >> 可以向文件末尾追加内容。

#!/bin/bash
echo “Before appending the file”
cat editors.txt
echo “6. NotePad++” >> editors.txt
echo “After appending the file”
cat editors.txt

这个例子展示了如何直接在 Shell 脚本中调用常见的终端命令来完成文件操作。

28. 测试文件存在

此脚本用于检查指定的文件是否存在。

#!/bin/bash
filename=$1
if [ -f “$filename” ]; then
  echo “File exists”
else
  echo “File does not exist”
fi

文件名通过第一个命令行参数 $1 传递。[ -f “$filename” ] 用于检查路径是否为常规文件。

29. 从 Shell 脚本发送邮件

结合 mail 命令,可以从脚本中发送电子邮件。

#!/bin/bash
recipient=”admin@example.com”
subject=”Greetings”
message=”Welcome to UbuntuPit”
`mail -s $subject $recipient <<< $message`

此脚本会向收件人发送一封带有指定主题和内容的邮件。需要系统已配置好邮件发送服务。

30. 解析日期和时间

date 命令可以获取并格式化系统日期和时间。

#!/bin/bash
year=`date +%Y`
month=`date +%m`
day=`date +%d`
hour=`date +%H`
minute=`date +%M`
second=`date +%S`
echo `date`
echo “Current Date is: $day-$month-$year”
echo “Current Time is: $hour:$minute:$second”

运行此脚本以了解其功能。也可以直接在终端尝试运行 date 命令及其各种格式参数。

31. sleep 命令

sleep 命令可以让脚本暂停执行指定的秒数。

#!/bin/bash
echo “How long to wait?”
read time
sleep $time
echo “Waited for $time seconds!”

程序会在执行最后的 echo 命令前等待用户输入的秒数。

32. wait 命令

wait 命令用于等待某个后台进程结束。

#!/bin/bash
echo “Testing wait command”
sleep 5 &
pid=$!
kill $pid
wait $pid
echo $pid was terminated.

这个脚本启动了一个后台休眠进程,然后立即杀死它,并使用 wait 等待该进程真正结束。

33. 显示上次更新的文件

结合 lsgrepawk 命令,可以找到当前目录中最近更新或创建的文件。

#!/bin/bash
ls -lrt | grep ^- | awk ‘END{print $NF}’

ls -lrt 以时间倒序列出文件,grep ^- 筛选出普通文件,awk 则打印出最后一行(即最新的文件)的最后一个字段(文件名)。

34. 添加批处理扩展

此脚本为指定目录下的所有文件添加统一的扩展名。

#!/bin/bash
dir=$1
for file in `ls $1/*`
do
  mv $file $file.UP
done

注意:请先在测试目录中运行此脚本,不要直接在重要目录使用。运行时要提供目录路径作为参数,使用 . 代表当前目录。

35. 打印文件或目录的数量

使用 find 命令统计给定目录中的文件和文件夹数量。

#!/bin/bash
if [ -d “$@” ]; then
  echo “Files found: $(find “$@” -type f | wc -l)”
  echo “Folders found: $(find “$@” -type d | wc -l)”
else
  echo “[ERROR] Please retry with another folder.”
  exit 1
fi

脚本接收一个目录名作为参数。如果目录不存在或无权限访问,会提示错误。

36. 清理日志文件

这是一个实际的运维脚本示例,用于清空特定的日志文件。

#!/bin/bash
LOG_DIR=/var/log
cd $LOG_DIR

cat /dev/null > messages
cat /dev/null > wtmp
echo “Logs cleaned up.”

此脚本会清空 /var/log/messages/var/log/wtmp 文件。请注意,需要 root 权限才能执行。

37. 使用 Bash 备份脚本

这是一个简单的备份脚本,用于打包过去 24 小时内修改过的文件。

#!/bin/bash
BACKUPFILE=backup-$(date +%m-%d-%Y)
archive=${1:-$BACKUPFILE}

find . -mtime -1 -type f -print0 | xargs -0 tar rvf “$archive.tar”
echo “Directory $PWD backed up in archive file \“$archive.tar.gz\”.”
exit 0

find . -mtime -1 查找一天内修改过的文件,tar 命令将其打包。备份成功后输出提示信息。这类自动化脚本是运维工作中不可或缺的一部分。

38. 检查你是否是 root 用户

通过比较用户 ID ($UID) 和 root 的用户 ID (0) 来判断当前用户身份。

#!/bin/bash
ROOT_UID=0

if [ “$UID” -eq “$ROOT_UID” ]
then
  echo “You are root.”
else
  echo “You are not root”
fi
exit 0

脚本的输出取决于运行它的用户。Root 用户的 $UID 为 0。

39. 从文件中删除重复行

使用 sortuniq 命令可以轻松去除文件中的重复行。

#! /bin/sh
echo -n “Enter Filename-> ”
read filename
if [ -f “$filename” ]; then
  sort $filename | uniq | tee sorted.txt
else
  echo “No $filename in $pwd…try again”
fi
exit 0

脚本对文件内容进行排序,uniq 去除连续的重复行,tee 命令同时将结果输出到屏幕和 sorted.txt 文件,并保留原文件不变。

40. 系统维护

可以编写脚本自动执行系统更新和清理任务,替代手动操作。

#!/bin/bash
echo -e “\n$(date “+%d-%m-%Y — %T”) — Starting work\n”

apt-get update
apt-get -y upgrade

apt-get -y autoremove
apt-get autoclean

echo -e “\n$(date “+%T”) \t Script Terminated”

该脚本依次执行更新软件列表、升级已安装的包、自动移除不再需要的旧包、清理下载缓存等操作。需要使用 sudo 权限运行。

掌握这些基础的 Shell 脚本示例,已经能够应对许多日常的自动化任务。如果你想深入探讨更多复杂的运维与自动化场景,例如监控、持续集成或配置管理,欢迎在云栈社区与广大开发者一起交流学习。




上一篇:RTX 5070部署WhisperX避坑指南:解决CUDA兼容性与PyTorch版本冲突
下一篇:AI编程颠覆传统:资深工程师称Agent与Vibe Coding将淘汰IDE
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-10 18:25 , Processed in 0.432276 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表