A shell parser, formatter, and interpreter. Supports POSIX Shell, Bash, andmksh. Requires Go 1.16 or later.
To parse shell scripts, inspect them, and print them out, see the syntaxexamples.
For high-level operations like performing shell expansions on strings, see theshell examples.
go install mvdan.cc/sh/v3/cmd/shfmt@latest
shfmt
formats shell programs. See canonical.sh for aquick look at its default style. For example:
shfmt -l -w script.sh
For more information, see its manpage, which can beviewed directly as Markdown or rendered with scdoc.
Packages are available on Alpine, Arch, Docker, FreeBSD, Homebrew,MacPorts, NixOS, Scoop, Snapcraft, Void and webi.
go install mvdan.cc/sh/v3/cmd/gosh@latest
Proof of concept shell that uses interp
. Note that it's not meant to replace aPOSIX shell at the moment, and its options are intentionally minimalistic.
We use Go's native fuzzing support, which requires Go 1.18 or later. For instance:
cd syntax
go test -run=- -fuzz=ParsePrint
$ echo '${array[spaced string]}' | shfmt
1:16: not a valid arithmetic operator: string
$ echo '${array[dash-string]}' | shfmt
${array[dash - string]}
$((
and ((
ambiguity is not supported. Backtracking would complicate theparser and make streaming support via io.Reader
impossible. The POSIX specrecommends to space the operands if $( (
is meant.$ echo '$((foo); (bar))' | shfmt
1:1: reached ) without matching $(( with ))
export
and let
are parsed as keywords.This allows statically building their syntax tree,as opposed to keeping the arguments as a slice of words.It is also required to support declare foo=(bar)
.Note that this means expansions like declare {a,b}=c
are not supported.A subset of the Go packages are available as an npm package called mvdan-sh.See the _js directory for more information.
To build a Docker image, checkout a specific version of the repository and run:
docker build -t my:tag -f cmd/shfmt/Dockerfile .
This creates an image that only includes shfmt. Alternatively, if you want animage that includes alpine, add --target alpine
.To use the Docker image, run:
docker run --rm -v $PWD:/mnt -w /mnt my:tag <shfmt arguments>
It is possible to use shfmt with pre-commit and a local
repo configuration like:
- repo: local
hooks:
- id: shfmt
name: shfmt
minimum_pre_commit_version: 2.4.0
language: golang
additional_dependencies: [mvdan.cc/sh/v3/cmd/shfmt@v3.2.2]
entry: shfmt
args: [-w]
types: [shell]
The following editor integrations wrap shfmt
:
shell script
pluginOther noteworthy integrations include:
.sh 基础语法 1. 开头 程序必须以下面的行开始(必须方在文件的第一行): #!/bin/sh 符号 #! 用来告诉系统它后面的参数是用来执行该文件的程序。在这个例子中我们使用 /bin/sh 来执行程序。 当编写脚本完成时,如果要执行该脚本,还必须使其可执行。 要使编写脚本可执行: 编译 chmod +x filename 这样才能用./filename 来运行 2. 注释 在进行 shel
1、sh是linux中运行shell的命令,是shell的解释器,shell脚本是百linux中壳层与命令行界面,用户可以在shell脚本输入命令来执行各种各样的任务。要运行shell脚本,首选需. 那能不能告诉我sh这个命令到底是起是起什么作用的?谢谢 sh或是执行脚本,或是切换到sh这个百bash里,默认的shell是bash,你可以试试tcsh啊,csh啊,ksh,zsh什么的,度看看别的s
#!是一个特殊符号,/bin/sh是用来解释该脚本的的shell路径 #!/bin/sh指该脚本使用/bin/sh来执行 sh只是其中一种解释方式,通过如下命令可以查到支持的shell解释方式: xx@xxx$ sudo cat /etc/shells # /etc/shells: valid login shells /bin/sh /bin/bash /bin/rbash /bin/dash
1. 可能需要的执行方式 linux下执行.sh文件的方法 .sh文件就是文本文件,如果要执行,需要使用chmod a+x xxx.sh来给可执行权限。 2. 开头:#!/bin/sh shell程序必须以“#!/bin/sh”开始。shell中#一般表示注释的意思,所以很多时候认为"#!"也是注释,但实际上并不是。 "#!/bin/sh"是对shell的声明,说明你所用的是哪种类型的shell及
目录 我的sh文件目录:/home/java/start.sh 我的sh文件内容: 一、将sh文件写入/etc/rc.d/rc.local(最终失败了,这个文件死活开机不运行,知道的道友麻烦教一下) 1、给sh文件添加可执行权限 2、将脚本添加到rc.local最后一行 3、添加可运行权限 4、重启 二、使用 crontab(成功) 1、通过 crontab -e 来设置 2、问题 3、解决问题
sh是在当前线程执行,如果当前连接关掉后,会停止sh文件的执行。 nohup:不挂断的运行,和用户终端没有关系,例如我们断开SSH连接都不会影响他的运行。 &是指在后台运行,但当用户推出(挂起)的时候,命令自动也跟着退出。 注意:nohup没有后台运行的意思;&才是后台运行。 nohup COMMAND & 这样就能使命令永久的在后台执行 例如: sh xxx.sh & 将sh xxx.sh任务
linux下面用命令执行.sh文件有两种方法: 一、直接./加上文件名.sh,如运行hello.sh为./hello.sh【hello.sh必须有x权限】 二、直接sh 加上文件名.sh,如运行hello.sh为sh hello.sh【hello.sh可以没有x权限】 方法一:当前目录执行.sh文件 【步骤一】cd到.sh文件所在目录 【步骤二】给.sh文件添加x执行权限 比如以hello.sh文
有时候做项目,我们经常会遇到一个东西要调试非常多次,然后修改的东西不多,相同的代码要敲非常多次,代码少还好,代码多的话会比较浪费时间。 首先,通过touch xxxx.sh创建一个xxxx.sh文件 接着,在第一行输入#!/bin/sh或者#!/bin/bash 符号#!用来告诉系统它后面的参数是用来执行该文件的程序。 一般来说都是输入#!/bin/bash,sh一般设成bash的软链,sh识别不
最近在使用csh时,遇到的一些他与sh的区别,特此记录以备后用: 1、shell脚本引用的区别: sh类型脚本开头为:#!/bin/sh csh类型脚本开头为:#!/bin/csh 2、变量的区别: sh中的变量不需要先定义,例如可以像下面这样使用变量: for arch in $(ls -l *.log | grep -v _20 | awk '{print $8}'); do tail
问题内容: 我使用Java中的以下代码使用HMAC-SHA1哈希一些值: 属于 在PHP中,有一个类似的函数可用来比较Java实现返回的值。 因此,首先尝试是: 返回: 我的Java函数也会返回。 好的,看来可行。然后,我尝试使用一个更复杂的键: 返回: 这次,我的Java展示返回了: 我的PHP代码返回的哈希值不等于我的Java函数返回的值,而且我找不到原因。 有小费吗? 问题答案: 在您的PH
问题内容: 这是代码段: 之后遇到错误: 所有其他方法都可以正常工作。试图进行大量研究但徒劳无功。任何线索将不胜感激 问题答案: 这表明Spark版本不匹配。在Spark 2.3 方法之前,仅接受两个参数: 从2.3开始,它需要三个参数: 在您的情况下,Python客户端似乎调用了后者,而JVM后端使用了较旧的版本。 由于初始化在2.4中进行了重大更改,这将导致上的失败,因此您可能使用: 2.3.
问题内容: 在我一直在构建的应用程序中,我们相当依赖于SharedPreferences,这使我思考了访问SharedPreferences时的最佳实践。例如,许多人说通过此调用可以访问它: 但是,这似乎很危险。如果您有依赖于SharedPreferences的大型应用程序,则可能会有密钥重复,尤其是在使用某些也依赖SharedPreferences的第三方库的情况下。在我看来,更好的使用方法是:
问题内容: 我在Oracle的Java标准加密提供程序中发现了困难的方法 使用以SHA-1实例化的MFG1;SHA-256仅用于对标签进行哈希处理(实际上是空的)。我发现在MFG1中实际使用SHA-256的唯一解决方案(得到该答案和注释的帮助)是使用以下替代形式Cipher.init: 问:有没有转变是会认识到,与类似的效果,除了与MGF1使用SHA-256? 问题答案: 不,没有。 Java是开
问题内容: Java有一种称为的模式RSA/ECB/OAEPWithSHA-256AndMGF1Padding。那有什么意思? RFC3447,公开密钥密码标准(PKCS)#1:RSA密码规范2.1版,第7.1.2节解密操作说,哈希和MGF都是RSAES-OAEP-DECRYPT的选项。MGF是它自己的功能,在B.2.1节MGF1中定义,并且还具有自己的Hash“选项”。 也许RSAES-OAEP
问题内容: 这个问题与这个问题相反:JGit如何从RevCommit获得SHA1?。 如果给我特定提交的SHA1 ID作为字符串,如何在JGit中获取ObjectId或关联RevCommit? 这是一个可能的答案,它遍历所有RevCommits: 有什么比上面的实现更好的了吗? 问题答案: 首先将字符串转换为an ObjectId,然后再RevWalk查找它可能会更容易。
问题内容: 我想从Java程序中异步运行Shell脚本-即在Java程序开始执行该Shell脚本之后,它会继续执行其他操作-并且仅当Shell脚本返回对其的响应时才做进一步的工作..即,它不会显式停止并等待shell脚本的响应。 这可能/可行吗?如何实现这种功能? 基本上,我将使用一个将管理所有这些服务器的服务器来监视多个服务器-为此,它将在每个服务器上运行shell脚本…因为有许多服务器,因此在
问题内容: 我读到JVM在内部存储短,整数和长为4个字节的内容。我是从2000年的一篇文章中读到的,所以我不知道现在有多真实。 对于较新的JVM,使用short而不是integer / long可以提高性能吗?自2000年以来,实施的那部分是否发生了变化? 谢谢 问题答案: 使用您需要的东西,我认为短裤由于范围小而很少使用,并且采用大端格式。 任何性能上的提升都是最小的,但是就像我说的,如果您的应