云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

大带宽_华为云服务器怎么用_试用

小七 141 0

在Linux中使用Go作为脚本语言

在Cloudflare,我们喜欢去。我们在许多内部软件项目以及更大的管道系统中使用它。但是,我们能否将Go提升到下一个级别,并将其用作我们最喜爱的操作系统Linux的脚本语言?3.0 Renee French编写的gopher image CC基于OpenClipart向量的Tux图像CC0为什么要把Go当作脚本语言简而言之:为什么不呢?Go相对容易学习,不太冗长,并且有一个巨大的库生态系统,可以重用这些库,以避免从头开始编写所有代码。它可能带来的其他一些潜在优势:针对您的Go项目的基于Go的构建系统:gobuild命令主要适用于小型的、独立的项目。更复杂的项目通常采用一些构建系统/脚本集。为什么不把这些剧本也写在围棋里呢?简易的非特权包管理开箱即用:如果你想在你的脚本中使用第三方库,你可以简单地去获取它。由于代码将安装在GOPATH中,因此获得第三方库不需要系统的管理权限(与其他一些脚本语言不同)。这在大型企业环境中尤其有用。项目早期阶段的快速代码原型:当您编写代码的第一次迭代时,通常需要进行大量的编辑,甚至使其编译,并且您必须在"编辑->构建->检查"周期中浪费大量的按键。相反,您可以跳过"构建"部分,直接执行源文件。强类型脚本语言:如果你在脚本中间的某个地方犯了一个小的错误,那么大多数脚本都会执行到那时为止的所有操作,并且在这个错误本身上失败。这可能会使系统处于不一致的状态。对于强类型语言,在编译时可以捕捉到许多类型错误,因此有缺陷的脚本将不会首先运行。Go脚本的当前状态乍一看,Go脚本似乎很容易实现,因为Unix支持shebang lines for scripts。shebang行是脚本的第一行,以#开头!并指定用于执行脚本的脚本解释器(例如#!/bin/bash或#!/usr/bin/env python),因此无论使用何种编程语言,系统都知道如何执行脚本。而且Go已经支持使用Go-run命令对.Go文件进行类似解释器的调用,所以只需添加一个适当的shebang行,比如#!/usr/bin/env运行到任何.go文件,设置可执行位,我们就可以开始了。但是,直接使用go-run存在一些问题。这篇伟大的文章详细描述了围棋的所有问题和潜在的解决办法,但要点是:go-run不会将脚本错误代码正确地返回到操作系统,这对于脚本很重要,因为错误代码是多个脚本相互作用和操作系统环境的最常见方式之一。在有效的.go文件中不能有shebang行,因为go不知道如何处理以#开头的行。其他脚本语言不存在此问题,因为大多数脚本语言都是一种指定注释的方法,因此最终解释程序只会忽略shebang行,但是Go comments以//开头,而Go run on invocation只会产生如下错误:主包装:你好,开始:1:1:非法字符U+0023'#'这篇文章描述了解决上述问题的几种方法,包括使用自定义包装程序gorun作为解释器,但所有这些方法都不能提供理想的解决方案。你要么:必须使用非标准的shebang线,它以//开头。从技术上讲,这甚至不是shebang行,而是bashshell处理可执行文本文件的方式,因此这个解决方案是bash特有的。另外,由于go-run的特定行为,这一行相当复杂,并不明显(参见原始帖子中的示例)。必须在shebang行中使用一个自定义包装程序gorun,该程序运行良好,但是最终得到的是.go文件,由于非法字符,这些文件不能用标准go build命令编译。Linux如何执行文件好吧,似乎shebang方法并不能为我们提供一个全面的解决方案。还有什么可以用的吗?让我们更仔细地了解一下Linux内核首先是如何执行二进制文件的。当您尝试执行一个二进制/脚本(或任何设置了可执行位的文件)时,您的shell最终将只使用Linux execve system call向它传递有关二进制文件的文件系统路径、命令行参数和当前定义的环境变量。然后内核负责正确解析文件,并使用文件中的代码创建一个新进程。我们大多数人都知道Linux(和许多其他类似Unix的操作系统)对其可执行文件使用ELF二进制格式。然而,Linux内核开发的核心原则之一是避免任何子系统的"供应商/格式锁定",这是内核的一部分。因此,Linux实现了一个"可插拔"的系统,它允许内核支持任何二进制格式—您所要做的就是编写一个正确的模块,它可以解析您选择的格式。如果你仔细看一下内核源代码,你会发现Linux支持更多现成的二进制格式。例如,对于最近的4.14Linux内核,我们可以看到它至少支持7种二进制格式(对于各种二进制格式的树型模块,其名称中通常有binfmt_u前缀)。值得注意的是binfmt_脚本模块,它负责解析上述shebang行并在目标系统上执行脚本(不是每个人都知道shebang支持实际上是在内核本身实现的,而不是在shell或其他守护进程/进程中实现的)。从用户空间扩展支持的二进制格式但是既然我们得出结论,shebang不是我们Go脚本的最佳选择,那么我们似乎还需要一些其他的东西。令人惊讶的是,Linux内核已经有了一个"something else"二进制支持模块,它有一个恰当的名称binfmt_misc。该模块允许管理员通过定义良好的procfs接口,直接从用户空间动态地添加对各种可执行格式的支持,并且有很好的文档记录。让我们按照文档说明,尝试为.go文件设置二进制格式说明。首先,指南告诉您将特殊的binfmt_misc文件系统安装到/proc/sys/fs/binfmt_misc。如果您使用的是相对较新的基于systemd的Linux发行版,那么很可能已经为您安装了文件系统,因为systemd默认情况下会为此安装特殊的挂载和自动挂载单元。要再次检查,只需运行:$mount | grep binfmt_其他systemd-1打开/proc/sys/fs/binfmt_misc type autofs(rw,relatime,fd=27,pgrp=1,timeout=0,minproto=5,maxproto=5,direct)另一种方法是检查/proc/sys/fs/binfmt_misc中是否有任何文件:正确安装的binfmt_misc文件系统将在该目录中创建至少两个名为register和status的特殊文件。接下来,由于我们确实希望.go脚本能够正确地将退出代码传递到操作系统,因此我们需要自定义gorun包装器作为我们的"解释器":$去拿github.com/erning/gorun$sudo mv~/go/bin/gorun/usr/local/bin/从技术上讲,我们不需要将gorun移到/usr/local/bin或任何其他系统路径,因为binfmt帴misc无论如何都需要解释器的完整路径,但是系统可能以任意权限运行此可执行文件,因此从安全角度限制对文件的访问是一个好主意。现在让我们创建一个简单的toy Go脚本你好,开始验证我们能成功地"解释"它。剧本:主包装进口("fmt""操作系统")函数main(){s:="世界"如果len(操作系统参数)>1个{s=操作系统参数[1]}印刷品("你好,%v!",秒)正式印刷品("")如果s=="失败"{操作系统退出(三十)}}检查参数传递和错误处理是否按预期工作:$戈伦你好,开始你好,世界!$echo$?0$戈伦你好,开始地鼠你好,地鼠!$echo$?0$戈伦你好,开始失败你好,失败!$echo$?30现在我们需要告诉binfmt_misc模块如何使用gorun执行.go文件。根据文档,我们需要以下配置字符串:高朗:E::go::/usr/local/bin/高伦:OC,它基本上告诉系统:"如果遇到扩展名为.go的可执行文件,请使用/usr/local/bin/gorun解释器执行它"。字符串末尾的OC标志确保脚本将根据脚本本身设置的所有者信息和权限位执行,而不是根据解释器二进制文件设置的位来执行。这使得Go脚本的执行行为与Linux中的其他可执行文件和脚本相同。让我们注册新的Go脚本二进制格式:$echo':高朗:E::go::/usr/local/bin/高伦:OC'sudo tee/proc/sys/fs/binfmt_misc/register:高朗:E::go::/usr/local/bin/高伦:OC如果系统成功注册了格式,则在/proc/sys/fs/binfmt_misc目录下会出现一个新文件golang。最后,我们可以本机执行.go文件:$chmod u+x你好,开始$ ./你好,开始你好,世界!$ ./你好,开始地鼠你好,地鼠!$ ./你好,开始失败你好,失败!$echo$?30就这样!现在我们可以编辑你好,开始根据我们的喜好,在下一次执行文件时,更改将立即可见。此外,与前面的shebang方法不同,我们可以随时使用go-build将此文件编译为真正的可执行文件。无论您喜欢Go还是深入研究Linux内部,我们都可以同时为其中一个或这些甚至两个都有位置。查看我们的职业页面。