<output id="ilehw"><bdo id="ilehw"><nobr id="ilehw"></nobr></bdo></output>
        <dl id="ilehw"><font id="ilehw"></font></dl>
          1. Bash 技巧 已翻译 100%

            oschina 投递于 01/03 11:00 (共 13 段, 翻译完成于 01-16)
            阅读 535
            收藏 2
            3
            加载中

            Bash不是最佳的程序员友好之工具。它需要小心谨慎,底层知识并且不允许出现任何错误(你知道你不能输入foo = 42,对吧?)。 另一方面,bash是无处不在的(即使在Windows 10上),它非常容易移植且功能强大,?#23548;?#19978;它是自动化任务时最实用的选择。幸运的是,遵循一套简单的规则可以使你免于其诸多雷区。

            Tocy
            Tocy
            翻译于 01/04 11:06
            0

            1. Shebang

            目前有数个可用的shebang,你可以用其引用你想执行代码的解?#25512;鰲?#20182;们中的一些是:

            • #!/usr/bin/env bash

            • #!/bin/bash

            • #!/bin/sh

            • #!/bin/sh –

            我们都知道shebang仅仅是一个指向shell解?#25512;?#30340;路径(绝对火相对于当前目录),但哪一个更受欢迎呢?

            长话短说 –为了可移植性,你应该使用#!/usr/bin/env bash。这是因为POSIX并没有标准化路径名,因此不同的基于UNIX的系统可能会将bash放到不同的位置。你不能完全假定——例如——/bin/bash是必然存在的 (一些BSD系统将bash可执行文件放到/usr/local/bin/bash中)。

             

            Tocy
            Tocy
            翻译于 01/07 14:45
            0

            Env实用程序可以帮助我们规避这种限制:#!/usr/bin/env bash将是代码在执行时使用PATH路径下找到的第一个解?#25512;鰲?#23613;管这不是最完美的解决方案 (那么如果同样的问题也适用于/usr/bin/env呢? 幸运的是,据我所知每个UNIX OS将env放置到同一个位置), 这是我们能做到的最好的方案。

            ?#27426;?#25105;意识到这也有个例外:对于系统启动脚本,既然/bin/sh是系统标准命令行解?#25512;鰨?#20351;用之。 

            更多信息请查阅这篇这篇文章。

            Tocy
            Tocy
            翻译于 01/07 14:55
            0

            2. 始终使用引号

            这是你应该遵循的最简单以及最好的建议,?#21592;?#20813;诸多可能的陷阱。错误的shell引用是让bash程序员头痛的最常见原因。不幸的是,它并不像重要那么容易。

            目前有很多不错的文章完全涵盖了这一特定主题。我没有更多要说的,但向你推荐这篇以及t这篇文章。

            值得记住的是:你通常应该使用双引号。

            Tocy
            Tocy
            翻译于 01/07 15:00
            0

            3.变量的使用

            $foo 是bash中引用变量的经典方法,但是bash2.0版本(通过echo $BASH_VERSION查看)给我们提供了新标记方法——变量扩展。这种方法是通过在变量标识符的两边使用大括号来做标记的,比如${foo}。为什么说这是一种好的?#23548;?#21602;?因为它给我们带来了一些新的特性:

            数组元素的扩展:${array[42]}

            ?#38382;?#30340;扩展,例如${filename%.*} (删除了文件的扩展名),, ${foo// } (删除了空格), ${BASH_VERSION%%.*}(获取bash的大版本号)

            变量名的拼接:${dirname}/${filename}

            将字符串拼接到变量的后面: ${HOME}/.bashrc

            通过位置?#38382;?#26469;访问?#38382;?#21464;量(脚本的输入?#38382;?#20363;如 $9

            支持子字符串的访问:${foo:1:5}

            间接引用:${!foo}  将会展开成一个由名称为foo,且存储在其中的?#36947;?#38388;接表示的值(bar=42; foo="bar"; echo "${!foo}" 将会打印42)

            大小写修改:${foo^}会将foo的首字母修改为大写字母,,(单独一个逗号会将其转换成小写字母)双重?#38382;?#30340;这种方法 (^^ 和 ,,) 会将所有的字母进行转换。

            SVD
            SVD
            翻译于 01/06 00:14
            0

            在大多数常见情况下,使用变量扩展?#38382;?#20351;我们没有优于经典扩展?#38382;?#30340;地方,但为了保持代码一致性,在所有地方使用它可?#21592;?#35748;为是一种好的做法。在阅读更多相关信息。

            你还需要了解关于bash中的变量的是,默认情况下,所有变量都是全局变量。这可能导致诸如浅拷贝、覆盖或歧义引用等问题。local运算符限制了变量的?#27573;В?#38450;止它们泄漏到全?#32622;?#21517;空间中。请记住 - 将所有函数的变?#21487;?#32622;为local变量。

            Tocy
            Tocy
            翻译于 01/07 15:04
            0

            4.观察脚本的运行目录

            你经常会在bash脚本中?#25512;?#20182;的文件进行交互。因此,你必须十?#20013;?#24515;使用相对路径。默认情况下,当前的工作路径是由脚本所在的父shell环境下所得到的。

            $ pwd
            /home/jakub
            
            $ cat test/test
            #!/usr/bin/env bash
            echo "$(pwd)"
            
            $ ./test/test
            /home/jakub

            当pwd和脚本所在的路径不一致的时候,会存在一些问题。这个时候,不能够简单的通过./脚本名称的方式运行脚本,因为它不会指向你的脚本?#21592;?#30340;文件。为了更加简单的将脚本作用到特定路径的文件,并且避免不小心引用到其他的系统文件,你应该考虑使用这个方便的单行指令将子shell工作目录更改为bash脚本的所在的目录:

            cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null && pwd)" || return
            $ pwd
            /home/jakub
            
            $ cat test/test
            #!/usr/bin/env bash
            cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" || return
            echo "$(pwd)"
            
            $ ./test/test
            /home/jakub/test

            看起来是不是更加自然?

            SVD
            SVD
            翻译于 01/06 13:15
            0

            5. 你真的不需要 ls

            在 bash 脚本中使用 ls 的方法几乎总是有缺陷的,我甚至无法记起这样做的一个理由。为了解?#25512;?#21407;因,我们来看看两个常见的例子:

            for file in $(ls *.txt)

            当?#25105;?#25991;件名包含空格时,分词将破坏此 for 循环。更重要的是 —— 如果文件名包含 glob 字符(也称为通配符,如*、?、[、]),它将被识别为 glob 模式并由 shell 扩展,但这可能不是你想要的。另一个问题是 POSIX 允许路径名包含除 \0 之外的任何字符(包括 |,/ 甚至换行符)。这使得在处理 ls 输出时无法确定第一个路径名的结束位置以及第二个路径名的起始位置。

            for file in "$(ls *.txt)"

            将 ls 包含在双引号内将导致其输出被视为单个词 —— 而不是期望的文件列表。

            如?#25105;?#27491;确的方式遍历文件列表呢?有两种可行策略:

            for file in ./*.txt

            这会使用上述的 bash globbing 功能。记得是双引用"${file}"!

            find . -type f -name '*.txt' -exec ...

            这个可能是最好的解决方案。 Find 工具允许你使用基于正则表达式的搜索(-regex),递归并具?#34892;?#22810;你可能觉得有用的内置功能。这里有一个不错的简介。

            find . -type f -name '*.txt' -print0 | xargs -0 ...

            另一种替代 find 的用法是使用 xargs。它既不简单也不简短,但 xargs 的优势在于它支持并行管道执行。更多有关此差异的信息阅读此文

            总而言之,永远不要尝试解析 ls 命令的输出。它根本没有被设计用于解析,你无法让其正常工作。点此阅读更多。

            Tocy
            Tocy
            翻译于 01/11 18:05
            0

            6. 期待意外

            通常忘记检查在bash脚本中执行命令的非零状态代码。很容易想象当我们的cd命令在文件操作之前静默失败时会发生什么(因为例如“没有这样的文件或目录?#20445;?/p>

            #!/usr/bin/env bash
            cd "${some_directory}"
            rm -rf ./*

            上面的一个例子会很好的工作,但只有在没有出错的情况下。目的?#24039;?#38500;some_directory/目录的内容,但最终可能会在完全不同的目录位置执行rm -rf ./*。

            cd“$ {some_directory}”&& rm -rf ./* 和 cd“$ {some_directory}”|| return是最简单的自描述解决方案。在这两种情况下,如果cd返回非零,则不会执行删除。值得指出的是,此代码仍然容?#36164;?#21040;常见编程错误的影响 - 拼?#21019;?#35823;。

            执行cd“$ {some_dierctory}”&& rm -rf ./*将最终删除您可能要保留的文件(只要没有拼?#21019;?#35823;的some_dierctory变?#21487;?#26126;)。 “$ {some_dierctory}”将扩展为“?#20445;?#36825;是完全?#34892;?#30340;cd?#38382;?#23558;我们带到主目录。不过不用担心,这不是?#36866;?#30340;结局。

            tsingkuo2019
            tsingkuo2019
            翻译于 01/10 09:45
            0

            Bash编程有一些值得注意的对于程序员友好的开关:

            • set -o nounset 可以设置bash将引用未被初始化的变量视为错误,这一特性可?#21592;?#20813;我们犯下拼写等低级错误。

            • set -o errexit 可以设置bash脚本在语句的返回值为非0值的时候立即退出。虽然使用errexit可以帮助我们?#34892;?#30340;检验程序的错误,但要正确的使用errexit却需要一些技巧。一些命令故意返回非0的?#36947;?#20135;生告警,并?#39029;?#24207;员?#38750;?#30340;知道应该如何去处理特定命令返回的错误值。参考这里了解更多。

            • set -o pipefail 可以改变使用管道时的默认行为。默认情况下,bash会将管道前面的命令返回的状态码作为管道后面的命令的输入,这意味着false| true返回0(管道符前面的状态是非0,会立马执行管道符后的命令)。这样的结果有可能不是你所期望的,因为这种情况下会忽略管道符前面的命令的结果。此时需要使用pipefail命令了,通过set -o pipefail的设置,可以设置管道的退出码为最右边的返回非零的命令(或者在所有的指令的执行成功的情况下设置退出码为0)。

            当然,错误问题的处理不仅仅适用于上面提到的cd命令,你的bash脚本应该考虑各种情况下可能出现的问题,比如路径名称中?#30446;?#26684;,文件的缺失,目录?#21019;?#24314;,或者是错误的使用了原本不存在的命令等(例如,就像你所了解的,并不是所?#24615;?#34892;你的bash脚本的linux操作系统都预装了awk命令)

            SVD
            SVD
            翻译于 01/05 23:52
            0
            本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链?#21360;?/div>
            我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
            加载中

            评论(0)

            返回顶部
            顶部
            广东快乐十分实时开奖

                  <output id="ilehw"><bdo id="ilehw"><nobr id="ilehw"></nobr></bdo></output>
                  <dl id="ilehw"><font id="ilehw"></font></dl>

                            <output id="ilehw"><bdo id="ilehw"><nobr id="ilehw"></nobr></bdo></output>
                            <dl id="ilehw"><font id="ilehw"></font></dl>
                              1. 23号福建十一选五开奖结果查询今天 央视体育频道节目表 竞彩足球比分玩法 吉林快三跨度图 辽宁35选7开好运奖结果查询 最新福建22选5开奖结果今天 福建11选5中奖对照表 极速快乐十分官网 中国足球竟彩实时比分 广西快三开奖直播 新疆11选5推荐号走势图表 平特一肖论坛。与你同行 北京pk10平台哪个好 安徽25选5昨天开奖号 四川金7乐玩法