V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiaofami
V2EX  ›  Bash

初学者写了个 bash 脚本,求大佬点评

  •  
  •   xiaofami · 2021-05-19 16:47:13 +08:00 · 1723 次点击
    这是一个创建于 1044 天前的主题,其中的信息可能已经有所发展或是发生改变。

    读的《 Linux 命令行与 shell 脚本编程大全》这本书。目前自己感觉列表处理不好,遇到需要遍历列表的时候我会把它传给另一个函数,然后用位置参数+shift 处理,不知是否合适。

    #!/bin/bash
    # 对 pdftk 的简单封装,用于删除指定的页码,以空格分隔,支持形如"5-7"的页码范围。页码输入不必按顺序,类似"12 6-8 1 3"输入是可以正常工作的。
    
    #isPdftkinstalled 作用为检查 pdftk 是否可用,若可用则执行 pdftk --version
    function isPdftkinstalled {
        echo
        if [ -z $(whereis pdftk | gawk '{print $2}') ]
        then
            echo "pdftk 未安装或未加入 PATH,请检查。"
            echo "提示:pdftk 已加入 Deepin 官方源,您可以通过 sudo apt install pdftk 简单安装。"
        else
            echo $(pdftk --version)
        fi
        echo
    }
    
    #getCouples 作用为对输入的页码进行处理,支持输入单页或页码范围,将其转换为数对(获取范围前后页码,以冒号分隔)
    function getCouples {
        local couples=''
        local left_end=''
        local right_end=''
        while [ -n "$1" ]
        do      
            arg1=$(echo "$1" | gawk -F"[- ]" '{print $1}')
            arg2=$(echo "$1" | gawk -F"[- ]" '{print $2}')
            left_end=$[ $arg1 - 1 ]
            #对应页码范围情况
            if [ -n "$arg2" ]
            then
                right_end=$[ $arg2 + 1 ]
            else
            #对应单页情况
                right_end=$[ $arg1 + 1 ]
            fi
            couples=$(echo $couples $left_end:$right_end)
            shift
        done
        #数对排序处理,注意 sort 是针对行的排序,故需要将空格转换成换行
        couples=$(echo $couples | tr " " "\n" | sort -t ':' -k 1 -n)
        couples=$(refineCouples $couples)
        echo $couples
    }
    
    #refineCouples 作用为合并相邻数对,供 getCouples 调用
    function refineCouples {
        local args=''
        local isNabour=''
        local Num1=$(echo $1 | cut -d ":" -f1)
        local Num2=$(echo $1 | cut -d ":" -f2)
        local Num3=''
        local Num4=''
        shift
        while [ -n "$1" ]
        do
            Num3=$(echo $1 | cut -d ":" -f1)
            Num4=$(echo $1 | cut -d ":" -f2)
            isNabour=$[ $Num2 - $Num3 ]
            if [ $isNabour -eq 1 ]
            then
                Num2=$Num4
            else
                args=$(echo $args $Num1:$Num2)
                Num1=$Num3
                Num2=$Num4
            fi
            shift
        done
        args=$(echo $args $Num1:$Num2)
        echo $args
    }
    
    #generateRanges 作用为将数对转换为 pdftk 可用的页码范围
    function generateRanges {
        local first_Bit=$(echo $1 | cut -d ":" -f1)
        local Num1=''
        local Num2=''
        local args=''
        while [ -n "$1" ]
        do
            Num1=$(echo $1 | cut -d ":" -f2)
            if [ -n "$2" ]
            then
                Num2=$(echo $2 | cut -d ":" -f1)
                if [ $Num1 -gt $Num2 ]
                then
                    Num2=$Num1
                fi
            else
                Num2="end"
            fi
            shift
            args=$(echo $args $Num1-$Num2)
        done
    
        if [ $first_Bit -gt 0 ]
        then
            args=$(echo 1-$first_Bit $args)
        fi
        echo $args
    }
    
    pdfFile=$1
    shift
    if [ $# -lt 2 ]
    then
        echo "Usage:pdftool [filename] [discard pages]"
        exit
    fi
    
    pagesConserved=$(generateRanges $(getCouples $*))
    pdftk_command=$(echo pdftk $pdfFile cat $pagesConserved output new_$(basename ${pdfFile}))
    #echo $pdftk_command
    $pdftk_command
    
    11 条回复    2023-05-15 03:32:03 +08:00
    gstqc
        1
    gstqc  
       2021-05-19 17:19:29 +08:00 via Android   ❤️ 2
    很好
    我选择用 Python 重写
    wellsc
        2
    wellsc  
       2021-05-19 17:56:27 +08:00
    用 Python 写吧,shell perl 之类的可维护性太差了
    liaojl
        3
    liaojl  
       2021-05-19 19:38:48 +08:00 via iPhone   ❤️ 1
    复杂一点的脚本用 Python 写吧,超过百行的 Bash 已经成鬼画符了
    heyjei
        4
    heyjei  
       2021-05-19 20:50:24 +08:00 via Android
    写的不错,但是理解起来很吃力,这语法看起来就难受,所以我选择用 python 的 os.system
    yitingbai
        5
    yitingbai  
       2021-05-19 21:03:51 +08:00
    我看 bash 教程的时候就记住了一句话, 超过 10 行的脚步用 python 去写
    love
        6
    love  
       2021-05-19 21:17:02 +08:00   ❤️ 2
    强烈建议加上 -e 标记
    #!/bin/bash -e
    bash 脚本中的命令很容易因各种原因出错,因为 bash 不会抛异常,不加标记的话会不管不顾地一直运行到底,导致各种意想不到的可怕的事发生
    IgniteWhite
        7
    IgniteWhite  
       2021-05-19 21:57:56 +08:00   ❤️ 1
    一个小点:为了增加脚本兼容性,一般把首行的 shebang line 写成
    #!/usr/bin/env bash
    同理,如果写一个直接用文件名运行的 python 脚本,也写成
    #!/usr/bin/env python
    lululau
        8
    lululau  
       2021-05-19 22:41:12 +08:00   ❤️ 1
    很好,$(echo $1 | cut -d ":" -f1) 这种可以用变量替换替代 ${1%%:*}

    说用 Python 的压根不会写 Shell 脚本,不用理会
    gstqc
        9
    gstqc  
       2021-05-20 00:04:19 +08:00 via Android
    我写过一百多 shell 脚本,最长的过千行,咋就变成根本不会写了……
    我只能说:运行环境允许你用 Python 并且脚本稍微复杂一点,就用 Python 吧
    ipwx
        10
    ipwx  
       2021-05-20 00:26:48 +08:00
    我承认我太菜,写不来 bash,所以我用 python
    hxy100
        11
    hxy100  
       318 天前
    bash 写的脚本通常只能自己看,换个人就看不懂啦
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1700 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 16:43 · PVG 00:43 · LAX 09:43 · JFK 12:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.