shell 是一个命令解释器。它在操作系统的外层,负责直接与用户的对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕返回给用户。
范例 1. 清除/var/log 下的 message 日志文件的简单命令脚本。
# 把所有命令放在一个文件堆积起来就形成了脚本。
# 要使用 root 身份来运行这个脚本
# 清除日志脚本
cd /var/log
cat /dev/null > messages
echo "Logs cleaned up."
# 提示:/var/log/messages 是系统的日志文件,很重要
问题: (1) 不是 root 就无法执行清理日志。 (2) 没有任何的流程控制语句,简单的说就是顺序操作,没有成功判断和逻辑性。
范例2. 包含命令、变量和流程控制语句的清除 /var/log 下的 messages 日志文件的 shell 脚本。
#!/bin/bash
# 清除日志脚本
LOG_DIR=/var/log
ROOT_UID=0 # $UID为0的时候,用户才具有root用户的权限
# 要使用root用户来运行,中括号加空格隔开
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "Must be root ro tun this script."
exit 1
fi
cd $LOG_DIR || {
echo "Cannot change to necessary directory." >&2
exit 1
}
cat /dev/null > messages && echo "Logs cleaned up."
exit 0
# 退出之前返回0表示成功返回1表示失败
扩展:清空日志及文件内容的三种方法: [root@localhost day1]# echo >test.log # 有一空白行 [root@localhost day1]# > test.log # 重定向 [root@localhost day1]# cat /dev/null > test.log
Centos linux 系统默认的 shell 是 bash。 查看方法:echo $SHELL 或 grep root /etc/passwd
#!/bin/bash
或
#!bin/sh < ==255 个字符以内
“#!”又被称为幻数,在执行脚本时,内核会根据"#!"后的解释器确定该用哪个程序解释脚本中的内容。注意:这一行必须为每个脚本顶端的第一行。 sh 为bash的软链接。
如果为python,则第一行为,执行如:python test.py执行
#!/usr/bin/env python
(1) 开头指定脚本解释器
#!bin/sh 或 #!/bin/bash
(2) 开头加版权等信息
#Date: 16:29 2020-3-30
#Author: Created by oldboy
#Mail: 48000448@qq.com
#Function: This scripts function is....
#Version: 1.1
提示:可配置vim编辑文件时自动加上以上信息,方法是修改~/.vimrc 配置文件。
(3) 脚本不用中文注释 尽量使用英文注释防止本机或切换系统环境后中文乱码的困扰。
(4) 脚本以.sh为扩展名
(5) 代码书写习惯优秀 I. 成对的符号内容一次写出来,防止遗漏,如:{},[],’’,"" II. [] 中括号两端要有空格,书写时即可留出空格[ ] III. 流程控制语句一次性书写完,在添加内容,如: if 语句格式一次完成: if 条件内容 then 内容 fi for 循环格式一次完成: for do 内容 done
(6) 通过缩进让代码易读
环境变量用于定义 Shell 的运行环境,保证 Shell 命令的正确执执行。家目录下的.bash_profile文件中或全局配置/etc/bashrc,/etc/profile,/etc/profile.d中定义。 登录显示加载内容可以放在/etc/profile.d目录下。
传统上,所有的环境变量均为大写。环境变量应用于用户进程前,必须用export命令导出。
用 evn 或 set 显示默认环境变量。unset 消除本地变量和环境变量。
I. 普通字符串变量定义: 变量名=value; 变量名=‘value’; 变量名=’'value"
II. 命令变量: 变量名=``; 变量名=$()
习惯:数字不加引号,其他默认加双引号。
单引号:看到的是什么就会输出什么。 双引号:把双引号内的所有内容都输出出来,如果内容中有命令,变量,特殊转义,会先解析出命令结果,然后在输出最终内容来。 无引号:一般连续的字符串,数字i,路径等可以不加引号。不过最好情况用双引号替代之。
I. 位置变量 0 获取当前执行的 shell 脚本的文件名,包括脚本路径,如 dirname 0 # 文件路径 basename
n 获 取 当 前 执 行 的 s h e l l 脚 本 的 第 n 个 参 数 值 , n = 1..9 , 当 n 为 0 时 表 示 脚 本 的 文 件 名 , 如 果 n 大 于 9 , 则 n 获取当前执行的 shell 脚本的第 n 个参数值,n=1..9, 当 n 为 0 时表示脚本的文件名,如果n 大于9,则 n获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9,则{10}
$# 获取当前 shell 脚本命令行中参数的总个数
企业案例:控制用户传的参数个数
[ $# -ne 2 ] && {
echo "must two"
exit 1
}
echo oldgirl
$$ 获取当前 shell 的进程号
$? 获取执行上一个指令的返回值(0为成功,非0为失败)
(1)应用案例:当系统中只能有某个脚本同时只能运行一个进程的时候
# pid.sh 脚本文件
[root@localhost scripts]# cat pid.sh
#!/bin/sh
pidPath=/tmp/a.pid
if [ -f "$pidPath" ]
then
kill -USR2 `cat $pidPath`
rm -f $pidPath
fi
# script pid write to $pidPath
echo $$ >$pidPath
sleep 300
# 查看进程
[root@localhost scripts]# ps -ef|grep pid.sh|grep -v grep
root 1758 1457 0 10:03 pts/0 00:00:00 sh pid.sh
常用计算命令:(())、let、expr、bc(小数)、$[] I. (()))用法
[root@localhost scripts]# ((a=1+2**3-4%3))
[root@localhost scripts]# echo $a
8
[root@localhost scripts]# b=$((1+2**3-4%3))
[root@localhost scripts]# echo $b
8
[root@localhost scripts]# echo $((3>2))
1
[root@localhost scripts]# echo $((3<2))
0
范例:一次计算一个(非混合运算),即传参传两个数,传一个计算符号,出结果。
[root@localhost scripts]# cat d.sh
echo $(($1$2$3))
[root@localhost scripts]# sh d.sh 3*2
6
II. let 用法
[root@localhost scripts]# i=2
[root@localhost scripts]# let i=i+8
[root@localhost scripts]# echo $i
10
[root@localhost scripts]# i=2
[root@localhost scripts]# i=i+8
[root@localhost scripts]# echo $i
i+8
III. expr 用法
[root@localhost scripts]# expr 2 + 2
4
[root@localhost scripts]# expr 2+2
2+2
[root@localhost scripts]# expr $[2*3]
6
[root@localhost scripts]# expr $[2/3]
0
IIII. read 用法
# -t timeout 设置输入等待的时间,单位默认为秒。
# -p prompt 设置提示信息
[root@localhost scripts]# read -t 5 -p "pls input:" a
pls input:1
[root@localhost scripts]# echo $a
1
# 单分支
if [条件]
then
指令
fi
# 双分支
if 条件
then
指令集
else
指令集
fi
# 多分支
if 条件
then
指令
elif 条件
then
指令
...
else
指令
fi
特殊写法:if [-f “$file1”]; then echo 1;fi 相当于: [-f “file1”] && echo 1
范例1:单分支 if 条件句两个整数比较大小。
[root@localhost scripts]# cat if-single.sh
#!/bin/sh
if [ 10 -lt 12 ]
then
echo "yes,10 is less than 12"
fi
范例2:使用 read 及脚本传参方式如何实现上述整数的比较?
#!/bin/sh
read -p "pls input two num:" a b
if [ $a -lt $b ];then
echo "yes,$a less than $b"
fi
if [ $a -eq $b ];then
echo "yes,$a equal $b"
fi
if [ $a -gt $b ];then
echo "yes,$a greater than $b"
fi
oldboy-1.html,oldboy-2.html,…,oldboy-10.html
[root@localhost oldboy]# cat /home/scripts/01.sh
[ ! -d /oldboy ] && mkdir -p /oldboy
for i in `seq 10`
do
touch /oldboy/oldboy-${i}.html
done
[root@localhost scripts]# cat 02.sh
#!/bin/sh
cd /oldboy
for f in `ls *.html`
do
mv $f `echo $f|sed 's#oldboy#linux#g'|sed 's#html#HTML#g'`
done
#!/bin/sh
for n in `seq -w 10`
do
useradd oldboy$n&&\
echo "root$n"|passwd --stdin oldboy$n
done
[root@localhost scripts]# array=(1 2 3)
[root@localhost scripts]# echo ${#array[@]}
3
[root@localhost scripts]# echo ${#array[*]}
3
[root@localhost scripts]# echo ${array[0]}
1
本文由来源 jackaroo2020,由 javajgs_com 整理编辑,其版权均为 jackaroo2020 所有,文章内容系作者个人观点,不代表 Java架构师必看 对观点赞同或支持。如需转载,请注明文章来源。