Shell 基础

92 阅读4分钟

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[ ... ]:用于条件测试。
    • grepsedawk 等工具用于文本处理。
  • 脚本调试 在脚本开头加入 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这个可以用,if["flag" = "1" ] ; then这个可以用,if ["flag" = "1"]; then这个语句会报错,原因是什么

在 Shell 脚本中,条件语句 if [ "$flag" = "1" ] ; thenif ["$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

image-20240327142207030image-20240327142207030!

image-20240327142226360