1.编写一个C语言程序
2.再编译这个C语言程序
假设这个C语言程序的为main.c
gcc main.c -o main
3.将编译后的应用程序移到/usr/bin/,这样就可直接将其当做命令来使用
sudo mv main /usr/bin/
//之后便可直接使用
main
4.查看Shell解释器
cat /etc/shells
5. 什么是 Shell 脚本
Shell 脚本是一种为 Shell 编写的脚本程序,它将一系列命令写入一个文件,通过 Shell 解释执行,从而实现自动化任务。最常用的 Shell 是 Bash(Bourne Again Shell),本笔记以 Bash 为例。
6. 第一个 Shell 脚本
6.1 创建脚本文件
#!/bin/bash
# 这是注释,第一行是 shebang,指定使用 /bin/bash 解释器
echo "Hello, World!"
6.2 添加执行权限
chmod +x hello.sh
6.3 运行脚本
./hello.sh
# 或者
bash hello.sh
7. 运行脚本的多种方式
-
作为可执行程序:
./script.sh(需要执行权限) -
直接调用解释器:
bash script.sh(不需要执行权限) -
使用
source或.:source script.sh或. script.sh(在当前 Shell 环境中执行,而不是子 Shell)
8. Shell 变量
8.1 定义变量
name="John" # 等号两边不能有空格
age=25
8.2 使用变量
echo $name # 输出 John
echo ${name} # 花括号可选,用于界定变量名
8.3 变量命名规则
-
只能包含字母、数字、下划线
-
不能以数字开头
-
区分大小写
8.4 只读变量
readonly PI=3.14159
PI=3.14 # 报错:只读变量
8.5 删除变量
unset name # 删除变量(不能删除只读变量)
9. 特殊变量
| 变量 | 含义 |
|---|---|
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的第 n 个参数(n≥1,如 $1、$2) |
$# | 传递给脚本或函数的参数个数 |
$* | 所有参数(作为一个整体字符串) |
$@ | 所有参数(每个参数独立,常用于循环) |
$? | 上一条命令的退出状态(0 表示成功,非 0 表示失败) |
$$ | 当前 Shell 进程的 PID |
$! | 后台运行的最后一个进程的 PID |
$- | 当前 Shell 的选项标志 |
$_ | 上一个命令的最后一个参数 |
示例:
#!/bin/bash
echo "脚本名: $0"
echo "第一个参数: $1"
echo "参数个数: $#"
echo "所有参数: $*"
echo "所有参数(每个独立): $@"
echo "上一个命令退出状态: $?"
10. 变量替换与扩展
10.1 命令替换
-
反引号
`command`或$(command)
today=`date +%Y-%m-%d`
today=$(date +%Y-%m-%d)
10.2 算术扩展
echo $(( 5 + 3 )) # 输出 8
$(( )) 推荐用法
sum=$((5 + 3))
mul=$((5 * 3))
div=$((10 / 3)) # 整数除法,结果为 3
mod=$((10 % 3)) # 取余,结果为 1
10.3 大括号扩展(生成序列)
echo file{1,2,3}.txt # 输出 file1.txt file2.txt file3.txt
echo {1..5} # 输出 1 2 3 4 5
echo {a..c} # 输出 a b c
11. 条件测试
11.1 测试命令 test 或 [ ]
if test "$name" = "John"
then
echo "Yes"
fi
# 等价于
if [ "$name" = "John" ]
then
echo "Yes"
fi
11.2 常用文件测试
| 表达式 | 含义 |
|---|---|
-f file | 是否为普通文件 |
-d file | 是否为目录 |
-e file | 文件是否存在 |
-r file | 文件是否可读 |
-w file | 文件是否可写 |
-x file | 文件是否可执行 |
-s file | 文件大小是否大于 0 |
-L file | 是否为符号链接 |
11.3 字符串比较
| 表达式 | 含义 |
|---|---|
"$str1" = "$str2" | 相等 |
"$str1" != "$str2" | 不等 |
-z "$str" | 字符串长度为零 |
-n "$str" | 字符串长度非零 |
注意:变量引用最好加上双引号,防止变量为空时语法错误。
11.4 数值比较(用于 [ ])
| 表达式 | 含义 |
|---|---|
$num1 -eq $num2 | 等于 |
$num1 -ne $num2 | 不等于 |
$num1 -lt $num2 | 小于 |
$num1 -le $num2 | 小于等于 |
$num1 -gt $num2 | 大于 |
$num1 -ge $num2 | 大于等于 |
11.5 逻辑运算符
在 [ ] 中 | 在 [[ ]] 中 | 含义 |
|---|---|---|
! | ! | 取反 |
-a | && | 与 |
-o | || | 或 |
推荐使用 [[ ]] 进行测试,它支持 &&、||,且不需要对变量加引号(但加引号是安全习惯)。
if [[ -f "$file" && -r "$file" ]]; then
echo "文件存在且可读"
fi
12. 流程控制
12.1 if 语句
if condition
then
commands
elif condition2
then
commands
else
commands
fi
示例:
#!/bin/bash
if [ $# -eq 0 ]
then
echo "未提供参数"
elif [ $# -eq 1 ]
then
echo "有一个参数: $1"
else
echo "有多个参数"
fi
9.2 case 语句
case 变量 in
模式1)
commands1
;;
模式2)
commands2
;;
*)
默认命令
;;
esac
示例:
#!/bin/bash
echo "请输入 yes 或 no"
read answer
case $answer in
yes|y|Y)
echo "你选择了 yes"
;;
no|n|N)
echo "你选择了 no"
;;
*)
echo "无效输入"
;;
esac
13. 循环
13.1 for 循环
# 遍历列表
for var in item1 item2 ...; do
commands
done
# 类C风格
for (( i=0; i<10; i++ )); do
commands
done
示例:
# 遍历文件
for file in *.txt; do
echo "处理文件: $file"
done
# 从 1 到 5
for i in {1..5}; do
echo "Number: $i"
done
# 类 C 风格
for (( i=0; i<5; i++ )); do
echo "i = $i"
done
13.2 while 循环
while condition; do
commands
done
示例:
# 计数器
count=1
while [ $count -le 5 ]; do
echo "count = $count"
((count++))
done
# 读取文件行
while IFS= read -r line; do
echo "行: $line"
done < file.txt
13.3 until 循环
until condition; do # 条件为假时执行,直到条件为真停止
commands
done
14. 函数
14.1 定义函数
# 方式一
function_name() {
commands
[return n]
}
# 方式二
function function_name {
commands
}
14.2 调用函数
直接写函数名即可,可传递参数。
function greet {
echo "Hello, $1!"
}
greet "Alice" # 输出 Hello, Alice!
14.3 返回值
-
使用
return返回整数(0-255),0 表示成功,非 0 表示错误。 -
通过
$?获取返回值。 -
若要返回字符串,可借助 echo 捕获输出。
示例:
add() {
local sum=$(( $1 + $2 )) # local 声明局部变量
echo $sum # 通过输出返回
}
result=$(add 5 3)
echo $result # 输出 8
15. 输入输出重定向
| 符号 | 含义 |
|---|---|
command > file | 将标准输出重定向到 file(覆盖) |
command >> file | 将标准输出追加到 file |
command < file | 将 file 作为标准输入 |
command 2> file | 将标准错误重定向到 file |
command > file 2>&1 | 将标准输出和标准错误都重定向到 file |
command &> file | 同上(Bash 扩展) |
command 2>&1 > file | 错误输出到当前标准输出,然后标准输出重定向到 file(注意顺序) |
command > /dev/null | 丢弃输出 |
示例:
ls /nonexist 2> error.log
echo "hello" >> output.txt
cat < input.txt
16. 管道
将一个命令的输出作为另一个命令的输入。
command1 | command2 | command3
示例:
ls -l | grep "\.txt" | wc -l
17. 命令替换
使用 $(command) 或 `command` 将命令的输出赋值给变量。
files=$(ls)
date=`date +%Y%m%d`
18. 脚本调试
18.1 调试选项
-
bash -x script.sh:执行时显示每条命令及其展开后的结果。 -
bash -v script.sh:显示输入的原始命令。 -
在脚本中设置
set -x开启调试,set +x关闭。
示例:
#!/bin/bash
set -x # 开启调试
echo "Debug mode on"
set +x # 关闭
echo "Debug mode off"
18.2 检查语法
bash -n script.sh # 仅检查语法错误,不执行
19.Shell 脚本如何获取输入
在 Shell 脚本中,获取输入的方式多种多样,主要分为命令行参数、交互式读取、重定向输入和菜单选择。
1. 命令行参数
脚本启动时可以在命令后面附加参数,脚本内部通过位置变量获取。
-
$0:脚本名称 -
$1,$2, ...,$9:第1、2…9个参数 -
${10}:第10个参数(大括号必需) -
$#:参数个数 -
$*:所有参数作为一个字符串 -
$@:所有参数作为独立字符串(常用于循环)
2. 使用 read 命令读取用户输入
read 从标准输入(通常是键盘)读取一行,并赋值给变量。
2.1 基本用法
2.2 常用选项
| 选项 | 说明 |
|---|---|
-p "提示信息" | 直接显示提示信息,不换行 |
-t 秒数 | 设置超时时间(秒) |
-s | 静默模式,不显示输入(用于密码) |
-n 字符数 | 读取指定字符数后自动结束 |
-a 数组名 | 将输入读取为数组(空格分隔) |
-d 分隔符 | 使用自定义分隔符结束输入(默认换行) |
示例:
#!/bin/bash
# 带提示的输入
read -p "请输入用户名: " username
# 隐藏输入(密码)
read -s -p "请输入密码: " password
echo
# 超时处理(5秒)
if read -t 5 -p "在5秒内输入: " answer; then
echo "你输入了: $answer"
else
echo "超时"
fi
# 读取多个变量(按空格分隔)
read -p "输入名字和年龄(空格分隔): " name age
echo "姓名: $name, 年龄: $age"
# 读取数组
read -p "输入多个数字(空格分隔): " -a numbers
echo "第一个数字: ${numbers[0]}"
3. 从文件重定向输入
脚本可以从文件读取内容作为标准输入。
3.1 简单重定向
#!/bin/bash
# 将文件内容作为输入
while read line; do
echo "行: $line"
done < /etc/passwd
3.2 使用文件描述符
#!/bin/bash
exec 3< input.txt # 打开文件并绑定到文件描述符3
while read -u 3 line; do
echo "从FD3读取: $line"
done
exec 3<&- # 关闭文件描述符
3.3 使用 cat 读取
#!/bin/bash
cat file.txt | while read line; do
echo "处理: $line"
done
注意:管道会使 while 在子 Shell 中运行,循环内设置的变量外部无法访问。若需保留变量,建议使用输入重定向(< file)或进程替换。
4. select 菜单
select 结构生成简单的数字菜单,让用户选择。
语法:
select 变量 in 列表; do
commands
done
示例:
#!/bin/bash
echo "请选择你的操作系统:"
select os in "Linux" "Windows" "macOS" "退出"; do
case $os in
"Linux")
echo "你选择了 Linux"
;;
"Windows")
echo "你选择了 Windows"
;;
"macOS")
echo "你选择了 macOS"
;;
"退出")
break
;;
*)
echo "无效选择"
;;
esac
done
运行时,select 会列出选项并显示提示符(默认为 #?),用户输入数字后变量 os 获取对应的值,然后进入循环,直到遇到 break。
5. 从标准输入读取(管道)
脚本可以通过管道接收上一个命令的输出作为输入。
示例:
#!/bin/bash
# 从管道读取数据
while read line; do
echo "接收到: $line"
done
调用方式:
echo -e "apple\nbanana\ncherry" | ./script.sh
或
cat file.txt | ./script.sh
&spm=1001.2101.3001.5002&articleId=158623224&d=1&t=3&u=8cb1e5254c934b91b071fdb64d77b7bd)
442

被折叠的 条评论
为什么被折叠?



