美文网首页
Linux shell 编程

Linux shell 编程

作者: wayyyy | 来源:发表于2020-04-09 21:35 被阅读0次

shell脚本

$PATH环境变量

为什么我们可以在任何路径执行ls命令了?
是因为环境变量$PATH的帮助,当我们执行一个命令,系统会按照PATH的设置去每个PATH定义的目录下查询文件名为ls的可执行文件,如果多个目录有同名的文件,那么先查询到的先执行。

$ echo $PATH
  /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
type命令
"" 和 ''区别
重定向
  • 注意在 < > 左边的变量不会展开
    #!/bin/bash
    
    ip=10.1.59.43
    cmd="ping -c 2 ${ip} &> /dev/null"
    echo ${cmd}
    ${cmd}      # 这里会报错,需要用 eval ${cmd}
    
eval
数据流重定向
  • 标准输入,使用<
  • 标准输出,使用>
  • 标准错误输出,使用2>
命令执行判断
  • cmd1;cmd2

    sync; sync; shutdown -f           
    
  • cmd1 && cmd2

    • 若cmd1执行正确则执行cmd2
    • 若cmd1执行错误则不执行cmd2
    查看txt文件是否存在,存在就新建txt2。
    ls txt && touch txt2
    
  • cmd1 || cmd2

    • 若cmd1执行正确则不执行cmd2
    • 若cmd1执行错误则执行cmd2
    查看txt文件是否存在,不存在就新建txt。
    ls txt || touch txt
    
  • cmd && cmd1 || cmd2

    • cmd 执行成功则执行cmd1,执行失败则执行cmd2,实际上是 (cmd && cmd1) || cmd2
    查看txt是否存在,存在输出exit,不存在输出no exit
    test -f txt && echo 'exit' || echo 'no exit'
    
shell变量

疑问:shell环境变量以及set,env,export的区别?

  • 基础

    name="admin"
    echo '$name'      输出:$name
    echo "$name"      输出:admin
    
    unset name        取消变量
    
  • 环境变量

    env  查看环境变量
    set  查看所有变量(环境变量与自定义变量)
    
shell 脚本执行方式
  • sh shellscript.sh./shellscript.sh都是在使用一个新的bash环境(子进程)来执行脚本内的内容。
  • source shellscript.sh是在原父进程执行脚本内容。
shell 脚本默认变量
变量 意义
$# 指传给脚本的参数个数
$0 指脚本文件本身名字
$@ 传给脚本的所有参数(不包括$0)
$$ 是脚本运行的当前进程ID号
$? 显示最后一个命令的退出状态,0表示没有错误,其他表示有错误
语法
  • 变量声明

    declare -[aixr]  variable
    
    -i 声明定义为整数类型 例子:declare -i sum=10+20
    -r 将变量设置成readonly类型。不能修改,也不能重设
    -a 将变量定位数组类型
    
  • local 变量

  • if else

    if [ $1x == "ab"x ]; then
      echo "you had enter ab"
    elif [ $1x == "cd"x ]; then
      echo "you had enter cd"
    else
      echo "you had enter unexpected word"
    fi
    
    • if [ 表达式1 -a 表达式2 ]
      
    • if [ 表达式1 -o 表达式2 ]
      
  • case esac

    case $变量名称 in
      "第一个变量内容")
          ......
      ;;        # 有2个分号
      "第二个变量内容")
          ......
       ;;        # 有2个分号
          ......
    esac       
    
  • for do done循环

    // 固定循环
    for var in con1 con2 con3
      do 
          ......
    done
    
    // 数值处理
    for i in `seq 1 2 100`
    do
          ......
    done
    
  • while do done循环

    while [条件判断式]
    do
          ......
    done
    
  • until do done循环

    until [条件判断式]
    do
        ......
    done
    
数值运算
#! /bin/bash

service_port=10000
log_service_port=$(expr $(service_port) + 1)
shell 函数返回字符串

shell函数只能返回数字,不允许返回字符串,但是可以用点小技巧返回字符串。

#! /bin/bash

function return_str()
{
    local l_str="hello world"
    echo "${l_str}"
}

str=$(return_str)
echo ${str}
向函数传递数组和从函数返回数组
local
var="hello"

function test()
{
    local var="world";
    echo "${var}"
}

test    // 输出 world
数组

shell中的数据分为2类:一类是普通数组,另一类是关联数组。

  • 数组定义方式

    array_test=(1 2 3 4)
    declare -a array_test  # 先声明一个空的数组,后面可以根据索引来动态添加
    
    echo ${!array_test1[*]}
    echo ${#array_test1[*]}  # 显示数组中的元素个数(只统计值不为空的元素)
    
  • 比较两个字符串是否相等的办法是:

    if [ "$test"x = "test"x ]; then
    

    这里的关键有几点:
    1 使用单个等号
    2 注意到等号两边各有一个空格:这是unix shell的要求
    3 注意到 "$test"x 最后的x,这是特意安排的,因为当 $test 为空的时候,上面的表达式就变成了 x = testx,显然是不相等的。而如果没有这个x,表达式就会报错:[: =: unary operator expected

字符串替换

https://www.cnblogs.com/gaochsh/p/6901809.html

判断一个变量是否为空
#!/bin/bash

function check_var_is_null()
{
    local l_var=$1
    if [ ! -n "${l_var}" ]; then
        echo "var is null"
    else
        echo "var is not null"
    fi
}

para1=""
para2=
check_var_is_null ${para1}
check_var_is_null ${para2}
对文件和目录存不存在
#!/bin/bash

function file_is_exist()
{
    local l_file=$1
    if [ -f "${l_file}" ]; then
        echo "found"
    else
        echo "not found"
    fi
}
判断式 意义
-e filename 判断文件名是否存在
-f filename 判断文件名是否存在且为文件
-d filename 判断文件名是否存在且为目录
-b -c -S -p -L 判断文件名是否存在且为块设备,字符设备,Socket文件,管道文件,连接文件
-r filename 检测该文件名是否存在且具有读权限
-w filename 检测该文件名是否存在且具有写权限
-x filename 检测该文件名是否存在且具有执行权限
n1 -eq/ne/gt/ge/lt/le n2 n1 相等/不等/大于/大于等于/小于/小于等于 n2
str1 = str2 字符串str1是否等于字符串str2
str1 != str2 字符串str1是否不等于str2
-z str 判断字符串str是否为空串
-a 2个条件同时成立 -r file -a test -x file
-o 任何一个条件成立
反向
文本替换
#!/bin/bash

function global_replace() {
    local l_file=$1
    local l_old_word=$2
    local l_new_word=$3

    eval sed -i 's/${l_old_word}/${l_new_word}/g' ${l_file}
    if [ $? -ne 0 ]; then
        echo "error: replace word faild, exit"
        exit 1
    fi
}
函数传参注意
#!/bin/bash
function func_param()
{
    local l_var=$1;
    echo "${l_var}"
}

mysql_user_info="-usheng -psheng0"
func_param ${mysql_user_info}        // 输出 -usheng
func_param "${mysql_user_info}"      // 输出 -usheng -psheng0
推荐一个shell代码片段学习

https://github.com/dylanaraps/pure-bash-bible

编写可靠shell脚本技巧
  • -x
    在执行每一个命令之前把经过的变量展开之后的命令打印出来。

  • -e
    遇到一个命令失败(返回值非0)时,立即退出。
    但是如果有时确实需要忽略个别的返回码。可以使用|| true,如:

    [cmd] || true
    或者
    [cmd] || ret=$?
    
  • -u
    试图使用未定义的变量,立即退出。

    #!/bin/bash
    
    set -u
    echo ${var}
    echo "here"
    

    输出:./te.sh: line 4: var: unbound variable

  • -o pipefail
    只要管道中的一个子命令失败,整个管道命令就失败。

  • timeout 限制运行时间
    有时候,需要对命令设置一个超时时间,这时可以使用timeout命令。

    timeout 600s [cmd] arg1 arg2
    

    命令在超时时间内运行结束时,返回码为 0,否则会返回一个非零返回码。

shellcheck

shellcheck 是一款实用的 shell脚本静态检查工具。
项目地址:https://github.com/koalaman/shellcheck
ubuntu 安装

apt-get install shellcheck
多任务并行
#!/bin/bash

for i in {1..254};do
    ip="192.168.80.$i"
    ping -c 2 $ip &> /dev/null && echo $ip is up &
done

wait

参考资料

  1. https://zhuanlan.zhihu.com/p/123989641

相关文章

网友评论

      本文标题:Linux shell 编程

      本文链接:https://www.haomeiwen.com/subject/mnphyhtx.html