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

2021-05-19 16:47:13 +08:00
 xiaofami

读的《 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
1762 次点击
所在节点   Bash
11 条回复
gstqc
2021-05-19 17:19:29 +08:00
很好
我选择用 Python 重写
wellsc
2021-05-19 17:56:27 +08:00
用 Python 写吧,shell perl 之类的可维护性太差了
liaojl
2021-05-19 19:38:48 +08:00
复杂一点的脚本用 Python 写吧,超过百行的 Bash 已经成鬼画符了
heyjei
2021-05-19 20:50:24 +08:00
写的不错,但是理解起来很吃力,这语法看起来就难受,所以我选择用 python 的 os.system
yitingbai
2021-05-19 21:03:51 +08:00
我看 bash 教程的时候就记住了一句话, 超过 10 行的脚步用 python 去写
love
2021-05-19 21:17:02 +08:00
强烈建议加上 -e 标记
#!/bin/bash -e
bash 脚本中的命令很容易因各种原因出错,因为 bash 不会抛异常,不加标记的话会不管不顾地一直运行到底,导致各种意想不到的可怕的事发生
IgniteWhite
2021-05-19 21:57:56 +08:00
一个小点:为了增加脚本兼容性,一般把首行的 shebang line 写成
#!/usr/bin/env bash
同理,如果写一个直接用文件名运行的 python 脚本,也写成
#!/usr/bin/env python
lululau
2021-05-19 22:41:12 +08:00
很好,$(echo $1 | cut -d ":" -f1) 这种可以用变量替换替代 ${1%%:*}

说用 Python 的压根不会写 Shell 脚本,不用理会
gstqc
2021-05-20 00:04:19 +08:00
我写过一百多 shell 脚本,最长的过千行,咋就变成根本不会写了……
我只能说:运行环境允许你用 Python 并且脚本稍微复杂一点,就用 Python 吧
ipwx
2021-05-20 00:26:48 +08:00
我承认我太菜,写不来 bash,所以我用 python
hxy100
349 天前
bash 写的脚本通常只能自己看,换个人就看不懂啦

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/777942

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX