Shell
Shell 基础
基础概念
-
Shell 简介 Shell 是 Linux/Unix 系统中的命令解释器,负责读取用户命令并调用内核执行,常见的有 Bash、sh、zsh 等。
-
脚本文件与解释器声明 脚本文件通常以
.sh结尾,第一行一般以#!/bin/bash开头(称为 shebang),指明使用哪个解释器运行脚本。 -
变量与环境变量
- 变量赋值:无需空格,例如
var="Hello"。 - 变量引用:使用
$var或${var}。 - 环境变量:如 PATH、HOME 等,通过
export命令导出。
- 变量赋值:无需空格,例如
Shell 数组
-
数组声明与赋值
- 声明数组:
array=(val1 val2 val3) - 访问数组元素:
${array[0]}表示第一个元素。 - 获取所有元素:
${array[@]}或${array[*]}。 - 数组长度:
${#array[@]}表示数组中元素个数。
- 声明数组:
-
数组遍历 可以使用 for 循环遍历整个数组,例如:
for value in "${array[@]}"; do echo "$value" done
条件判断与循环
-
条件判断
- 使用
if [ condition ]或if [[ condition ]]。 - 常用比较运算符包括:
-eq、-ne、-lt、-gt、-le、-ge(用于数值);=、!=(用于字符串)。
- 使用
-
循环结构
- for 循环:遍历列表、数组或使用 C 语言风格的语法。
- while 循环:在条件为真时重复执行命令。
- until 循环:在条件为假时执行循环体。
命令替换与算术运算
-
命令替换 使用反引号(
command)或者$(command)来获取命令输出。例如:current_date=$(date +%Y-%m-%d) -
算术运算 使用
$((表达式))进行算术运算,例如:sum=$((a + b))
函数定义与调用
-
函数定义
可以使用如下两种方式定义函数:
function func_name() { # 函数体 } # 或者 func_name() { # 函数体 } -
函数调用 直接使用函数名调用,函数可以接受参数,通过
$1、$2等访问。
常用 Shell 命令与调试
-
常用命令
echo:打印输出。read:从标准输入读取数据。test或[ ... ]:用于条件测试。grep、sed、awk等工具用于文本处理。
-
脚本调试 在脚本开头加入
set -x可打开调试模式,显示每条命令执行细节;set -e可在遇到错误时退出脚本。
文件权限与执行
- 文件权限设置 使用
chmod命令设置文件权限,如chmod +x script.sh使脚本具有执行权限。 - 路径与软链接 确保可执行文件位于 PATH 环境变量中,必要时可通过
ln -s创建软链接。
日常使用
-if -eq,if -ne,if -gt
-eq //等于
-ne //不等于
-gt //大于
-lt //小于
ge //大于等于
le //小于等于
if [[ $status -eq 0 ]]; then
定时任务
crontab -e
30 0 * * * sh /home/news/newsapp/shell/rt_status_cause_log.sh > /home/news/newsapp/log/rt_status_cause_log.log 2>&1
正则
匹配非行
^(?!.*asd).*$
#此正则可以匹配不包含asd 的字符串
匹配行
^(?=.*asd).*$
#一般都是匹配包含的字符串
校验URL
/^http[s]{0,1}://.+$/ 或 /^http[s]{0,1}://.{1,n}$/ (表示url串的长度为length(“https://”) + n )
\ / :表示字符“/”。
"^The":表示所有以"The"开始的字符串("There","The cat"等);
"of despair$":表示所以以"of despair"结尾的字符串;
代码复制
复制
scp -r import_tables/ /home/saiche/saiche/shell/
修改权限
chown -R saiche:saiche /home/saiche/saiche/shell/import_tables/
批量替换
sed -i "s/chengyu/saiche/g" `grep chengyu -rl /home/saiche/saiche/hql`
统计月初
月头:
date -d "2014-01-07" +%Y-%m-01
月尾:
date -d "`date -d '2014-01-07 +1 month ' +%Y-%m-01` -1 day " +%F
季头:
date -d "`awk -F- '$2%3==1{print $1FS$2FS"01";next}$2%3==2{print $1FS$2-1FS"01";next}{print $1FS$2-2FS"01"}' <<<2014-1-07`" +%F
季尾:
date -d "`awk -F- '$2%3==1{print $1FS$2+3FS"01";next}$2%3==2{print $1FS$2+2FS"01";next}{print $1FS$2+1FS"01"}' <<<2014-1-07` -1 day" +%F
并行执行
sh a.sh &
sh b.sh &
sh c.sh &
wait
sh d.sh
exit
这样就可以让 a.sh b.sh c.sh并行执行
获取系统时间
#!/bin/bash
time=`date +%H:%M:%S`
echo $time
if [[ "$time" > "02:00:00" ]]&& [[ "$time" < "11:30:00" ]]
then
echo "当前时间还没到中午"
else
echo "已过中午,请休息"
fi
在shell中将内容打印并且存储到日志文件
利用"echo命令"和">>重定向“实现操作:
echo "`date +'%Y-%m-%d %H:%M:%S'`: $output" 打印到屏幕
echo "`date +'%Y-%m-%d %H:%M:%S'`: $output" >> $log_file 输出到日志文件
日常问题
Permission denied
我准备在LINUX 下做给自动SSH 登录的脚步,下载了expect,也安装 /usr/bin/expect目录,但是在写的脚步里,老是提示:-bash: ./texpect.sh: /usr/bin/expect: bad interpreter: Permission denied
Permission denied这个错误,可能是没有赋予脚本可执行权限。
需要先 chmod +x ./sh_ext_ztd.ztd
shell中空格的使用
shell脚本中,if [ "flag" = "1"]; then这个语句会报错,原因是什么
在 Shell 脚本中,条件语句
if [ "$flag" = "1" ] ; then和if ["$flag" = "1"]; then在语法上是有区别的。正确的语法应该是在
[和]之间留有空格,以确保正确解析条件。因此,正确的写法是if [ "$flag" = "1" ]; then。当你将
[与$flag相连时,Shell 会将其视为一个命令名称,而不是条件测试。因此,if ["$flag" = "1"]; then会导致语法错误。
测试用例
#!/bin/sh
set -e -x
export HADOOP_USER_NAME=dba
day=$1
flag=$2
echo $flag
#if ["$flag" = "1"]; then
if [ "$flag" = "1" ] ; then
echo "11111"
else
echo "2"
fi
!