Shell 脚本入门:变量、if、for 一次讲清
很多重复操作,其实不用每次都手敲一遍。把命令写进一个文件,让 Shell 按顺序跑一遍,这就是 Shell 脚本。它不需要装任何东西,Linux 自带,今天就从最常用的三样讲起:变量、if 判断、for 循环。
先写第一个脚本
新建一个文件 hello.sh,写下:
#!/bin/bash
echo "你好,Shell"
第一行 #!/bin/bash 叫 Shebang,告诉系统用哪个解释器来跑这个文件。写完先给它执行权限,再运行:
chmod +x hello.sh
./hello.sh
如果忘记加 chmod +x,系统会报权限不足;也可以直接用 bash hello.sh 运行,不用改权限。刚开始练手,两种方式都可以用。
变量:给值起个名字
变量就是给一个值起个名字,之后用名字代替它。写法很简单:
name="小明"
echo "你好,$name"
注意三点。第一,等号两边不能有空格,写成 name = "小明" 会报错。第二,取值时在名字前加 $。第三,值里有空格要用引号包起来。
变量还能接住命令的输出。比如想把今天的日期存下来:
today=$(date +%Y-%m-%d)
echo "今天是 $today"
$(...) 的意思是先跑括号里的命令,再把结果当成值。这种写法在备份脚本里很常见:文件名后面拼上日期,就不会把旧备份覆盖掉。
if:让脚本自己做决定
脚本不只是按顺序跑,还能根据情况走不同的路。判断磁盘空间够不够,就是一个典型场景:
used=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$used" -gt 80 ]; then
echo "磁盘用了 $used%,该清理了"
else
echo "磁盘用了 $used%,还够用"
fi
这里有几个固定格式要记住:if 后面跟条件,条件写在 [ ] 里,then 后面是条件成立时做的事,else 是不成立时做的事,最后以 fi 收尾。
[ ] 里的比较符号和数学课不太一样:-gt 是大于,-lt 是小于,-eq 是等于,-ne 是不等于。写错符号,判断结果就反了。字符串比较用 = 和 !=。还有一个常用的 -f,用来判断某个文件在不在:
if [ -f "/etc/hosts" ]; then
echo "hosts 文件存在"
fi
for:重复的事交给循环
要对一批文件做同样的事,一个一个敲太慢了,for 循环就是干这个的:
for file in *.log; do
echo "正在处理 $file"
done
*.log 会展开成当前目录下所有以 .log 结尾的文件,循环一个一个处理。do 和 done 之间是每次循环要做的事。
再看一个更实用的例子:批量给一批文件改名,在文件名前面加上日期:
today=$(date +%Y%m%d)
for file in *.txt; do
mv "$file" "${today}_$file"
done
${today}_$file 里的大括号是用来划清变量边界的:不加大括号,Shell 会把 today_ 当成一个变量名,取到的就是空值。这类小坑踩过一次就记住了。
三个新手常踩的坑
第一,等号两边加空格。a = 1 在 Shell 里不是赋值,而是把 a 当成命令去跑,一定报错。
第二,变量没加引号。文件名里有空格时,mv $file 新名字 会被拆成好几段;写成 mv "$file" 新名字 才稳妥。养成习惯:用到变量就加双引号。
第三,条件里的空格不能省。[ "$used"-gt 80 ] 这样写是错的,[、] 和里面的每一项之间都要有空格,少一个都不行。
一个能直接用的小例子
把上面三样拼起来,就是一个每天能跑的磁盘检查脚本:
#!/bin/bash
used=$(df / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$used" -gt 80 ]; then
echo "警告:根分区用了 $used%,请及时清理"
for file in /tmp/*.log; do
echo "可清理的临时日志:$file"
done
else
echo "磁盘正常,用了 $used%"
fi
存成文件、给执行权限,就能直接跑。配合定时任务每天跑一次,磁盘快满了能第一时间知道,不用等到服务挂了才发现。
Shell 脚本不用一次全学会。先从变量、if、for 这三样开始,遇到重复操作就想想能不能写成脚本,写多了自然就熟了。
- 点赞
- 收藏
- 关注作者
评论(0)