shell编程培训

shell编程培训

顾名思义,shell脚本是您希望您的计算机执行的逐行语句,就像您手动执行一样。赛斯·肯伦

本文导航

你好世界…… 16%

-删除空网格…21%

-删除空网格V2.0…47%

-删除空网格V2.5…61%

-如果和测试…75%

编译自: https://opensource.com/article/17/1/getting-started-shell-scripting

作者:塞思·肯伦

译者:hkurj

世界上对shell脚本最好的概念性介绍来自一个老的美国电话电报公司培训视频[1]。在视频中,Brian w . kernighan(awk中的“k”)和Lorinda l . Cherry(BC的作者之一)演示了UNIX的一个基本原则是让用户通过使用现有的实用程序来定制和创建复杂的工具。

用Kernighan[2]的话说,“UNIX系统程序基本上是…你可以用来创造东西的积木。…..管道的概念是[UNIX]系统的基础;你可以把一堆程序…首尾相连,让数据从左边的一个流到右边的一个,系统自己管理所有的连接。程序本身对连接一无所知;对他们来说,他们只是在和终端对话。”

他说的是给普通用户编程的能力。

POSIX操作系统本身就像一个API。如果您能弄清楚如何在POSIX shell中完成一项任务,那么您就可以自动化这项任务。这就是编程,这种日常POSIX编程方法的主要方式就是shell脚本。

顾名思义,shell脚本是您希望您的计算机执行的逐行语句,就像您手动执行一样。

因为shell脚本包含常见的日常命令,所以熟悉UNIX或Linux(通常称为POSIX系统)是有帮助的。您对shell的经验越多,编写新脚本就越容易。这就像学习一门外语:你脑子里的单词越多,就越容易组织复杂的句子。

当你打开一个终端窗口时,你打开了一个外壳。shell有几种,本教程适用于bash、tcsh、ksh、zsh等。在接下来的几节中,我提供了一些特定于bash的示例,但是最终的脚本不会使用这些示例,所以您可以切换到在bash中设置变量的课程,或者进行一些简单的语法调整[3]。

如果你是新手,就用bash。是一个很好的外壳,有很多友好的功能。是Linux,Cygwin,WSL,Mac的默认shell,BSD上也支持。

Hello world

您可以从终端窗口生成自己的hello world脚本。注意你的引号;单双会有不同的效果。

$ echo “#\!/bin/sh” > hello.sh

$ echo ” echo ‘ hello world ‘ ” & gt& gthello.sh

如您所见,编写shell脚本就是这样,除了第一行,它只是将命令“回显”或粘贴到文本文件中。

像运行应用程序一样运行脚本:

$ chmod +x hello.sh

$ ./hello.sh

你好世界

反正这是一个shell脚本。

现在让我们来处理一些有用的东西。

去除空格

如果说有什么东西会干扰计算机与人类的交互,那就是文件名中的空框。你在互联网上看过一些网站,比如http://example.com/OMG% 2 cutest % 20 cat % 20 photo % 21% 211.jpg。或者,当你不顾一切地运行一个简单的命令时,文件名中的空框会让你掉进坑里:

$ cp llama pic.jpg ~/photos

cp:无法统计“llama”:没有这样的文件或目录

cp:无法stat ‘pic.jpg ‘:没有这样的文件或目录

解决方案是用反斜杠或引号“转义”空大小写:

$ touch foo\ bar.txt

$ ls “foo bar.txt “

foo bar.txt

这些都是需要知道的重要技能,但是不方便。为什么不写个脚本把这些烦人的空框从文件名里删掉呢?

创建一个文件来保存发布shebang[4](#!),让系统知道文件应该在shell中运行:

$ echo ‘#!/bin/sh’ > despace

好的代码从文档开始。明确目的,让我们知道该怎么做。这里有一个很好的自述:

despace is a shell script for removing spaces from file names.

用法:

$ despace “foo bar.txt “

现在让我们弄清楚如何手动操作以及如何构建脚本。

假设您的目录中只有一个foo bar.txt文件,比如:

$ ls

hello.sh

foo bar.txt

计算机只不过是输入和输出。在这种情况下,输入是对特定于ls的目录的请求。输出是您所期望的:目录文件的名称。

在UNIX中,您可以通过“管道”将输出用作另一个命令的输入,无论管道的另一端是什么过滤器。tr程序恰好是专门设计来修改传输给它的字符串的;对于本例,您可以使用- delete选项删除引号中定义的字符。

$ ls “foo bar.txt” | tr –delete ‘ ‘

foobar.txt

现在,您已经获得了所需的输出。

在Bash shell中,您可以将输出存储为变量。一个变量可以被看作是空位,其中存储着信息:

$ NAME=foo

当需要返回信息时,可以通过在变量名前加一个美元符号($)来引用位置。

$ echo $NAME

富(中国姓氏)

要获得删除了空网格的输出,并将其放在一边以备后用,请使用一个变量。将命令的结果放入变量中,并使用反引号(`)来完成它:

$ NAME=`ls “foo bar.txt” | tr -d ‘ ‘`

$ echo $NAME

foobar.txt

我们已经完成了目标的一半,现在我们可以从源文件名确定目标文件名。

到目前为止,脚本看起来是这样的:

#!/bin/sh

NAME = ` ls ” foo bar . txt ” | tr-d ‘ ‘ ` 1

echo $NAME

第二部分必须重新命名。现在您可能已经知道了这个命令:

$ mv “foo bar.txt” foobar.txt

但是,请记住,在脚本中,您使用了一个变量来保存目标名称。你已经知道如何引用变量:

#!/bin/sh

NAME = ` ls ” foo bar . txt ” | tr-d ‘ ‘ ` 1

echo $NAME

mv “foo bar.txt” $NAME

您可以将它标记为可执行文件,并在测试目录中运行它。确保您有一个名为foo bar.txt的测试文件(或者您在脚本中使用的任何名称)。

$ touch “foo bar.txt”

$ chmod +x despace

$ ./取消空格

foobar.txt

$ ls

foobar.txt

去除空格 v2.0

该脚本可以工作,但并不完全像您的文档中描述的那样。目前非常具体,只适用于一个名为foo\ bar.txt的文件,其他都不适用。

POSIX命令将它的命令本身称为[67],并将在它之后键入的任何内容命名为、、等等。您的shell脚本也可以像这样算作POSIX命令,所以尝试用替换foo\ bar.txt。

#!/bin/sh

NAME=`ls | tr -d ‘ ‘ `

echo $NAME

mv $ 1 $名称

创建几个新的测试文件,名称中包括空:

$ touch “one two.txt”

$ touch “猫狗. txt “

然后测试您的新脚本:

$ ./despace “one two.txt”

ls:无法访问“one”:没有这样的文件或目录

ls:无法访问“two.txt”:没有这样的文件或目录

看来你找到了一个漏洞!

这其实不是bug。一切按设计运行,但不是你想要的。你的脚本真的把变量“扩展”成了“one two.txt”,麻烦的是你试图消除的麻烦的空网格。

解决方案是将变量封装在引号中,以封装文件名:

#!/bin/sh

NAME = ` ls ” $ 1 ” | tr-d ‘ ‘ ` 1

echo $NAME

mv “” $NAME

做另一个测试:

$ ./despace “one two.txt”

onetwo.txt

$ ./despace c*g.txt

catdog.txt

该脚本的行为类似于任何其他POSIX命令。您可以将它与其他命令结合使用,就像您想使用的任何POSIX程序一样。您可以通过以下命令使用它:

$ find ~/test0 -type f -exec /path/to/despace {} \;

或者您可以将它用作循环的一部分:

$ for FILE in ~/test1/* ; do /path/to/despace $FILE ; done

等一下。

去除空格 v2.5

这个删除脚本已经可以工作了,但是在技术上可以优化,可以做一些可用性的提升。

首先,实际上并不需要变量。shell可以一次性计算出所需的信息。

POSIX shell有一个操作序列。在数学中,同样的方法用于先处理括号中的语句。在执行该命令之前,shell将解析Bash中的反引号`或$()符号。因此,以下声明:

$ mv foo\ bar.txt `ls foo\ bar.txt | tr -d ‘ ‘`

将转化为:

$ mv foo\ bar.txt foobar.txt

然后执行实际的mv命令,并获得foobar.txt文件。

了解了这一点,您可以将shell脚本压缩成:

#!/bin/sh

mv ” $ 1 ” ` ls ” $ 1 ” | tr-d ‘ ‘ ` 1

这似乎简单得令人失望。您可能认为没有必要将脚本缩减为一行,但是很少几行shell脚本是有意义的。即使是用简单命令编写的紧凑脚本也可以防止您犯致命的键入错误,这在移动文件时尤其重要。

另外,你的剧本还是可以改进的。更多的测试发现了一些弱点。例如,不带参数运行despace会产生一个无意义的错误:

$ ./despace

ls:无法访问“”:没有这样的文件或目录

mv:’ ‘后缺少目标文件操作数

有关更多信息,请尝试“mv – help”。

这些错误令人困惑,因为它们是为ls和mv发出的,但据用户所知,它们运行的不是ls或mv,而是despace。

你想想,如果它没有得到一个文件作为命令的一部分,这个小脚本甚至不应该尝试重命名文件,请尝试使用你知道的变量和测试函数来解决。

if 和 test

if语句将把你的小despace工具从脚本转换成程序。这涉及到代码领域,不过不用担心,也很好理解和使用。

If语句是一个开关;如果某件事是真的,那么你会做一件事,如果是假的,你会做不同的事。这个if-then指令的二元决策恰好是计算机擅长的;你需要做的是给计算机定义什么是真,什么是假,什么最终会被执行。

测试真假最简单的方法是测试工具。不用直接调用,用它的语法就行。在终端尝试:

$ if [ 1 == 1 ]; then echo “yes, true, affirmative”; fi

是的,真实,肯定

$ if[1 = = 123];然后附和“是,真,肯定”;船方不负担装货费用

$

这就是测试的工作原理。你有各种各样的速记方法可供选择。这里使用了-z选项,它检测字符串的长度是否为零(0)。将这个想法转化为您的despace脚本是:

#!/bin/sh

if[-z ” $ 1 “];然后

“echo”提供一个“文件名”,使用引号来消除空格。

1号出口

船方不负担装货费用

mv ” $ 1 ” ` ls ” $ 1 ” | tr-d ‘ ‘ ` 1

为了提高可读性,if语句放在单独的一行,但概念仍然是:如果变量中的数据是空(零个字符存在),则打印一条错误语句。

试试看:

$ ./despace

提供一个“文件名”,使用引号使空格无效。

$

成功!

嗯,其实是失败,但这是一个美丽的失败,更重要的是,一个有意义的失败。

请注意exit 1语句。这是当POSIX应用程序遇到错误时向系统发送警报的一种方式。这个函数对于您或其他需要在脚本中使用despace并依赖其成功执行来顺利运行的人来说非常重要。

最后一个改进是添加了一些东西来保护用户不会意外覆盖文件。理想情况下,你可以把这个选项传递给脚本,所以它是可选的;但是为了简单起见,这里是硬编码的。I选项告诉mv在覆盖现有文件之前请求许可:

#!/bin/sh

if[-z ” $ 1 “];然后

“echo”提供一个“文件名”,使用引号来消除空格。

1号出口

船方不负担装货费用

mv-I ” $ 1 ” ` ls ” $ 1 ” | tr-d ‘ ‘ ` 1

现在你的shell脚本是有意义的、有用的、友好的——你是程序员,所以不要停下来。学习新命令,在终端中使用它们,写下您的操作,然后编写脚本。最终,你会从工作中解脱出来。等你的机器人仆人运行了shell脚本,下辈子就好办了。

黑客快乐!

关于作者:

Seth Kenlon是独立的多媒体艺术家、自由文化倡导者和UNIX极客。他是基于Slackware的多媒体制作项目(http://Slackware . ml)的维护者之一。

via:https://open source . com/article/17/1/getting-started-shell-scripting

作者:塞斯·肯伦[5]译者:hkurj校对:wxy

本文最初由LCTT[6]编译,由Linux中国介绍。

[1]: at&t培训视频-https://youtu.be/XvDZLjaCJuw

[2]:克尼根-https://youtu.be/tc4ROCJYbm0

[3]:语法调整-http://hyperpolyglot . org/UNIX-shell

[4]:发布合作伙伴-https://Linux . cn/article-3664-1 . html

[5]:塞斯·肯伦-https://opensource.com/users/seth

[6]:https://github.com/LCTT/TranslateProject的LCTT

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论