重击理论

/ bin / bash

0.索引

  1. 大多数人发生的事情
  2. 脚本的结构
  3. 在屏幕上打印
  4. 读取用户输入
  5. bash中的计算
  6. 条款
  7. 循环
  8. 功能
  9. 盖普特斯

1.大多数人发生的事情

/ bin / bash或/ bin / sh

在执行脚本时,机器要做的第一件事就是查看应该使用哪个shell。 在大多数当前的linux系统上 / bin / sh的 是一个链接 / bin / bash,但并非总是如此,例如在使用 busybox的 带来 Sh 通常他们也带来 ,但如果您使用 / bin / sh的,它将无法与Bash一起运行。 这就是为什么我建议始终使用 / bin / bash.

Unicode与ASCII

您是否曾经想过为什么不能在脚本中使用“¿”或“?”? 还是使用口音? 在交互式脚本中可能会很烦人。 那是因为Bash的默认编码是ASCII,或者说是相同的英文字符集。 要更改它,我们只需要告诉脚本我们要使用Unicode。 为此,您必须在命令解释器之后添加一行:

#-*-编码:UTF-8-*-

请注意,这一行在脚本的开头很重要。

使脚本可执行

有趣的是,有多少人使用«$ bash脚本.sh“ 代替 ”$ ./脚本.sh毕竟,这就是我们为之定义的外壳。

要添加执行权限,您必须执行:

须藤+ x script.sh
如果脚本是可执行的,则可以将其添加到PATH中,并使其可以从计算机上的任何位置/文件夹执行。 为此,我们必须将其添加到用户的.bashrc或/ etc / bashrc行中
BIN =“我们有脚本的文件夹” PATH =“ $ BIN $ PATH”
用大写形式写变量名是Bash规则。 许多人不遵循此规则,但是对于长脚本来说,它是值得赞赏的,因为它们使它们更具可读性

2.脚本的结构

  1. 全局变量的定义
  2. 帮助
  3. 功能
  4. 主体

标头是我们指示要使用的shell和编码的位置。 该功能的优点是可以重复使用仅编写一次即可重复的代码,并使脚本更易于理解,对于超过100行的代码而言,这非常有用。

为了使用函数,必须在脚本主体之前使用定义它们。 而且,如果我们想在主体和函数中的所有脚本的全局级别使用变量,则必须在所有内容的开头,标题之后定义它们。

最后,优良作法是在脚本运行错误或参数错误时编写帮助函数。 显然,在这些情况下,我们希望立即退出脚本,而不读取函数。 为此,我们可以使用:

函数help(){echo“”“我们的格式正确的帮助文本。”“”如果[[-z $ 1 || $ 1 ==“ -h” || $ 1 ==“ --help”]]; 然后帮忙

如果在帮助功能中添加“退出”,则每次运行帮助时(例如,在出现错误消息后等),我们都会退出脚本。 我们保存了几行代码。

该条件表示在屏幕上显示帮助,如果脚本没有参数运行或指定了-h / –help,则退出。 如果您看一下,那是大多数Linux程序的标准行为。

将3引号与echo一起使用可以使用换行符,而不会使消息显示为echo。 对于多行消息,只使用一次回声更为方便。

3.在屏幕上打印

有2条用于以bash打印到屏幕的主要命令:«回音“和”的printf«。 它们既快又都是bash的一部分。 对于初学者而言,主要区别在于echo在末尾添加了换行符,而«的printf“才不是。

回声非常好,并且是大多数人使用的回声,但是,当读取用户的INPUT时,或者当您希望通过字处理打印从文件中获取的变量时,可能会发生奇怪的事情。 它们通常很容易解决,就像将双引号更改为单引号或反之亦然,或从引号中删除变量引用一样容易。 «回音»根据我们的编译方式,是否还会发生奇怪的事情,如果我们始终使用Ubuntu或Fedora,它不会影响我们,但是如果更改发行版,它会影响我们。

这就是为什么我使用«的printf«,这不会让我头疼,而且表现得更像«的printf»从C或«打印»对于Python,如果您想将脚本移植到另一种编程语言,那是非常重要的。

有关更广泛的讨论,您可以访问 来自Stack Exchange上Unix和Linux的这个问题.

4.读取用户INPUT

我们在脚本名称之后和按ENTER键之前编写的所有内容都会自动保存在特殊变量中。 这些变量的类型为$ X,其中X是数字。

«$0»表示我们脚本的名称,并来自«$1»无穷大,我们稍后编写的所有内容都是可变的。 例如:

cat << EOF >> test.sh#!/ bin / bash#-*-编码:UTF-8-*-printf“ \ $ 0 = $ 0 \ n” printf“ \ $ 1 = $ 1 \ n” printf“ \ $ 2 = $ 2 \ n“ EOF chmod + x script.sh ./script.sh我的file.txt

我们创建一个测试脚本,使其可执行,并使用2个参数运行它。 我们获得以下屏幕输出:

$ 0 = ./script.sh $ 1 =我的$ 2 = file.txt

使用引号,我们可以将“ my file.txt”传递给“ $ 1”。

我们还可以使用“ read”命令读取用户的INPUT,直接指示要在其中保存参数的变量。 例如:

printf“你叫什么名字?\ n”读为NAME printf“你好,$ NAME。\ n”
注意变量的分配。 “ $ VAR = content”将产生错误,等号,变量名和内容之间不能留空格。 正确的用法是“ VAR =内容”

5. Bash中的计算

为此,我们可以使用«表达式«,只要我们不需要进行复杂的计算即可。 应该注意两件事,第一件事是«表达式»仅接受整数,其次是除法返回整个结果,以查看我们可以使用的其余部分«%«。

通常,我们希望将expr的结果分配给变量。 我们可以通过两种方式做到这一点:

VAR2 =`expr $ VAR1 / 10` VAR2 = $(expr $ VAR1 / 100)

您也可以跳过«表达式»使用双括号:

VAR2 = $((($ VAR1 / 100))
要进一步了解«表达式»或者使用整数的替代方法,您可以看一下 这KZKG ^ gaara条目.

6。 条款

关于“if“”其他“”ELIF»和条件。 您可以在以下内容中了解到:

我只想强调使用简单方括号之间的区别,«[]«和双括号,«[[]]«,关于条件。 使用双括号,我们可以使用其他条件:

  • «&&»和
  • «||»对于或

使用“&&“和”||»使用简单的方括号,应将每个零件分开放在单独的方括号中。 用于查看是否需要执行帮助的脚本部分的示例为:

如果[-z“ $ 1”] || [“ $ 1” ==“ -h”] || [“ $ 1” ==“ --help”]]; 然后帮忙

这也使我们不必为了避免错误而在引号中写变量名。 例如:

如果[$ 1 = 1]; 然后printf“参数等于1。”; fi如果[“ $ 1” = 1]; 然后printf“参数等于1。”; fi如果[[$ 1 = 1]]; 然后printf“参数等于1。”; 科幻

如果在没有任何参数的情况下运行script.sh,则第一种情况将产生错误:

bash:[:=:期望一元运算符
在Bash中,“ =”和“ ==“都以相同的方式解释。 在其他编程语言中不会发生这种情况,其中``=''仅用于分配变量。

尚未谈论的是«案件«,用于简化«if«。 让我们从头开始,当我们没有任何«if»所有代码将被执行。 如果我们添加条件«if»我们将有两种情况,一种是“if»以及另一种不执行此块的情况。

如果我们添加«其他«我们还将有两种情况,但这两种情况与以前的情况有所不同。 因为现在将有两个条件代码块,A和B,以及C块,这是程序的其余部分。 A或B将被执行,而C将被执行。在先前的情况下,它是A和C或仅是C。

为避免书写条件«如果别的“ 内 ”其他»为了简化代码的读取,它是创建的«ELIF«。 当我们有许多条件取决于上一个条件时,例如数字范围或类型:

如果[[$ VAR1 = 1]],则VAR1 = $ 1; 然后printf“ 1 \ n” elif [[$ VAR1 = 2]]; 然后printf“ 2 \ n” elif [[$ VAR1 = 3]]; 然后printf“ 3 \ n” else printf“ none \ n” fi

对于最后一个«ELIF»将阅读许多条件。 在这种情况下,简化了该过程:

VAR1 = $ 1 case $ VAR in 1)printf“ 1 \ n” ;; 2)printf“ 2 \ n” ;; 3 | 4)printf“ 3或4,取决于\ n” ;; *)printf“ none \ n” ;; 那C

将读取一个变量(在这种情况下为VAR1),并将检查该变量是否与任何情况均等效,否则将执行默认情况“ *”。 双分号等效于«打破“, 他们告诉”案件»那必须结束。

«案例»也可以用作«的序列if«,为此您必须使用«;;&»(继续)代替«;;» (停)。

7.循环

在任何编程语言中,很少有循环是已知的。 在Bash中,它们是«“”直到“和” «。 关于这些的内容已经写在博客中:

循环有两种类型« «,属于那种«$用于LOQUESEA中的VAR»以及C类型是什么«$ for((我= 0;我<= 10;我++))«。 第二种循环« »非常有用,它在循环开始时包含3个部分:

  • 变量的声明和初始化(在这种情况下为辅助变量“ I = 0”)。
  • 执行条件(直到I小于或等于10)。
  • 辅助变量的增加

我认为这是所有循环中最强大的循环。 一个示例,显示从0到10的所有数字,包括:

#!/ bin / bash for((I = 0; I <= 10; I ++)); 做printf“ $ I \ n”完成

8.功能

Bash不允许我们做某些事情,对吧? 乍一看,bash函数阻止您执行三件事:在函数中声明局部变量,将参数传递给函数以及返回参数。 一切都有解决方案。

什么都不做:

#!/ bin / bash VAR = 1 printc“ $ VAR \ n”函数hello(){VAR = 2 printf“ $ VAR \ n”}你好printf“ $ VAR \ n”

打印到屏幕1、2和2。

要声明局部变量,请添加«本地»声明时:

#!/ bin / bash VAR = 1 printf“ $ VAR1 \ n”函数foo(){本地VAR1 = 2 printf“ $ VAR1 \ n”} printf“ $ VAR1 \ n” foo printf“ $ VAR1 \ n”

在屏幕上打印1、1、2、1。

如何将参数传递给函数?

#!/ bin / bash#-*-编码:UTF-8-*-function hello(){printf“ Hello $ 1 \ n”}

printf“你叫什么名字?\ n”
读取VAR1
你好$ VAR1

如何返回参数?

#!/ bin / bash#-*-编码:UTF-8-*-function hello(){printf“ Hello holita”} printf“您叫什么名字?\ n”读取VAR1 VAR1 = $(hello)#在这里printf“ $ VAR1 $ VAR2 \ n”

如您所见,这有两个缺点,您只能返回一个参数(可以是向量😀),并且如果要返回参数,则无法再从该函数在屏幕上打印。

您可以在 [url=https://blog.desdelinux.net/programando-en-bash-parte-3/]这篇文章来自 Usemoslinux[/url]。

9.Getops

您需要了解有关Bash创建复杂脚本的最后一件事是«傻瓜«。 它用于将选项传递给脚本,而不考虑顺序。 唯一的缺点是它只会影响空头期权:

#!/ bin / bash#-*-编码:UTF-8-*-VARC = 0 function help(){printf“帮助消息\ n”退出},如果[[-z $ 1]]; 然后在getopts时帮助fi:ha:b:c OPT; 在h)帮助中做$ OPT的情况;; :) 救命 ;; a)VARA = $ OPTARG ;; b)VARB = $ OPTARG ;; c)VARC = 1 ;; \?) 救命 ;; esac done#使用VARA,VARB和VARC进行处理的脚本的主要块

«获取选项»逐个读取选项,因此需要循环。

可以使用«传递两种类型的选项获取选项“:

  • 参数称为标志,在这种情况下为-c或-h。 它们用我们要使用的字母指定。 它们就像布尔变量,«true»(是)或«false”(他们不在这里)。
  • 带有关联参数的参数-a任何东西-b任何东西。 它们用我们想要的字母指定,下面用冒号表示。 参数存储在OPTARG中(此名称不可更改)。
最初的双点表示没有错误。

这个脚本做什么?

当不传递任何选项,传递“ -h”参数,传递无效参数(例如,“-x”,由“ \?”完成)时显示帮助消息。没有参数的有效参数(“:”)。 在其余情况下,它将VARC中存在的“ -c”保存为1,并且在VARA和VARB中将值分别用“ -a”和“ -b”传递。


发表您的评论

您的电子邮件地址将不会被发表。 必填字段标有 *

*

*

  1. 负责数据:MiguelÁngelGatón
  2. 数据用途:控制垃圾邮件,注释管理。
  3. 合法性:您的同意
  4. 数据通讯:除非有法律义务,否则不会将数据传达给第三方。
  5. 数据存储:Occentus Networks(EU)托管的数据库
  6. 权利:您可以随时限制,恢复和删除您的信息。

  1.   拉夫

    很好我不多说U_U

  2.   米格尔

    您好很好的文章。
    嘿,您授予sudo + x而不是chmod + x权限

    1.    Henry

      $ sudo chmod + x script.sh
      (更确切地说,呵呵)

      啊,恭喜你,谢谢!

  3.   火冷

    很好的帖子,事实是我向你表示祝贺,请继续保持,问候

  4.   古斯塔沃

    而且,如果希望脚本在执行时可见,请逐步查看例如变量,条件和所有内容的行为,则可以使用:

    sh -x脚本

    问候

  5.   达戈

    护身符。 很好,很好解释。
    谢谢。

  6.   加布里埃尔

    关于这个主题的优秀文章

  7.   马里奥·吉列尔莫·扎瓦拉·席尔瓦

    非常有趣,非常重要,感谢您提供的信息…。
    干杯!

  8.   不来自布鲁克林

    谢谢大家的祝贺,关于Miguel命令,他不允许我在发布该条目后对其进行修改。 我想这将必须做得很好。

  9.   阿德里安

    很好!

    首先,我想向您表示祝贺,我发现它很容易理解,并且确实有助于遵循指南以进行bash编程,特别是对于开始编程的人。

    但是,我发现了一些细节,我认为应该更正。

    首先:在第2节中。 脚本的结构»该函数未关闭,在脚本中执行该函数时会导致问题。
    解决方案是在“退出”命令之后向其添加一个右括号。

    第二:第«4节。 读取用户输入»您确认用户可以输入的参数的范围是$ 0到无穷大,但是bash»只能解释从$ 0到$ 9,因为$ 10等于$ 1 + 0。
    要解决此问题,您可以使用“ shift”命令获取以下变量。 或者在大括号“ $ {10}”中指定变量,以便bash将值合计,而不是$ 1 + 0。

    事不宜迟,问候!

    1.    不来自布鲁克林

      谢谢你的评论。 在脚本和函数中完全无法解释退出的正确用法。 至于$ {10},我从来没有遗赠过这么多东西,所以我还没有遇到这个问题,很高兴知道有解决方案(我已经淘汰了今天学到的新知识thing)。

  10.   io

    非常感谢您的文章! 您提到的某些事情仍然缺乏澄清。 例如,getops。
    在屏幕输出部分,您必须提及猫,稍后再提及...
    猫<
    ***************************************
    *此表格非常具有表达力*
    ***************************************
    EOF

    在您的示例中:
    猫《 EOF》 test.sh
    应该提到两件事……>>是“追加”,也就是说,如果重复相同的命令,则整个脚本将重复一遍……您应该只使用一个……
    猫<< EOF> script.sh
    是的,它也应该称为script.sh
    然后在
    如果[-z“ $ 1”] || [“ $ 1” ==“ -h”] || [“ $ 1” ==“ -help”]]]; 然后
    帮助
    fi

    我认为应该写...
    如果[[-z“ $ 1”] || [“ $ 1” ==“ -h”] || [“ $ 1” ==“ -help”]]]; 然后
    ...

    BASH还有更多发现。
    您可以将其命名为“基本”吗? 🙂
    例如,参数'testers'类似于-z来查看它们是否为空,或者像-f一样来查看它是否作为文件存在。

    再次感谢您的努力。
    阿尔贝托

  11.   小丑

    一个非常好的bash脚本教程!

  12.   OCZ

    -编码:UTF-8-

    这是我第一次看到该行在bash脚本中设置字符编码。 在我看来,Python比Bash更像Python。 真的有必要吗? 我在Google上搜索了参考文献,但找不到任何东西,您手边有一个谈论此事的链接吗? 特别是关于那条线的适用性。

    我认为,要使用UTF-8在Bash中编写脚本,您只需要保存文本文件(没有BOM),并正确设置某些环境变量(LANG和LC_ *)。
    然后,显然,有必要为ASCII以外的其他编码准备执行的命令。 例如,如果我们要大写,这似乎不起作用:
    «Echoáéíóú| 特拉兹(AZ)»
    o:
    «Echoáéíóú| tr [:较低:] [:较高:]»
    最好使用:
    «Echoáéíóú| awk'{print toupper($ 0)}'»。

    1.    不来自布鲁克林

      有关 ”编码»之前在此博客中已提及:

      Bash:如何使脚本可执行
      安装后实用程序脚本

    2.    像你这样的borriquito

      有人纠正了我,但该编码行(#--编码:UTF-8--)与bash或shell没有关系:它是一条注释行(以#开头),用于告诉EDITOR我们用来编写脚本(vim,emacs ...)的文件编码。

      实际上,bash看不到这样的行,因为它是注释行。

  13.   1987年JoRgE

    出色的教程,因为Sysadmin知道Bash中的脚本是必不可少的,它对所有内容都非常有用。

    非常非常棒!

    的问候!

  14.   爱德华多·库莫(Eduardo Cuomo)

    如果这对任何人都有用,则可以使用以下几种用法和示例来创建自己的脚本: https://github.com/reduardo7/hsabx

  15.   利托·布莱克

    很好。 新内容添加到我的脚本中。 encodig和printf东西没有它。
    谢谢!!!

  16.   xxxtonxxx

    太好了! 我将其保留为收藏夹,它可以纠正错误,甚至提供更多内容来扩展。 为所有这些信息鼓掌!