在 shell 脚本中的变量名之前插入“local"会导致错误 [英] Inserting “local” before variable name in a shell script leads to an error

查看:217
本文介绍了在 shell 脚本中的变量名之前插入“local"会导致错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这段代码(它是 shell 函数的一部分)运行良好:

This code (it’s a part of a shell function) works perfectly:

    output=$(\
            cat "${vim_file}" | \
            sed -rne "${EXTRACT_ENTITIES}" | \
            sed -re "${CLEAR_LEADING_QUOTES}" | \
            sed -re "${NORMALIZE_NAMES}" \
    )

但是当我试图在作业前插入local"这个词时……

But when I’m trying to insert the word "local" before the assignment…

    local output=$(\
            cat "${vim_file}" | \
            sed -rne "${EXTRACT_ENTITIES}" | \
            sed -re "${CLEAR_LEADING_QUOTES}" | \
            sed -re "${NORMALIZE_NAMES}" \
    )

...我收到一个奇怪的错误:

…I get a strange error:

local: commands.: bad variable name

代码中没有错误的不可见字符:只有制表符在其他地方缩进和空格.该脚本以#!/bin/sh"开头.在函数中的其他变量之前插入local"不会导致任何问题.用另一个任意字符串替换输出"(变量名)不会有任何改变.操作系统是Linux.

There are no wrong invisible characters in the code: only tabs making indentations and spaces in the other places. The script begins with "#!/bin/sh". Inserting the "local" before other variables in the function doesn’t lead to any problem. Replacing "output" (the name of the variable) with another arbitrary string changes nothing. The OS is Linux.

推荐答案

非常简短的回答:使用更多引号!

Really short answer: Use more quotes!

local output="$(\
        cat "${vim_file}" | \
        sed -rne "${EXTRACT_ENTITIES}" | \
        sed -re "${CLEAR_LEADING_QUOTES}" | \
        sed -re "${NORMALIZE_NAMES}" \
)"

更长的答案:双引号变量引用和命令替换几乎总是一个好主意.双引号可防止它们受到分词和文件名通配符扩展的影响,这很少是您想要的,并且可能会导致混淆问题.

Longer answer: It's almost always a good idea to double-quote variable references and command substitutions. Double-quoting prevents them from being subject to word splitting and filename wildcard expansion, which is rarely something you want, and can cause confusing problems.

在某些情况下,不使用双引号是安全的,但规则令人困惑且难以记住,并且容易出错.这是那些令人困惑的案例之一.不会发生分词和通配符扩展的情况之一(因此保留双引号是安全的)是在赋值的右侧:

There are situations where it's safe to leave the double-quotes off, but the rules are confusing and hard to remember, and easy to get wrong. This is one of those confusing cases. One of the situations where word splitting and wildcard expansion don't happen (and therefore it's safe to leave the double-quotes off) is on the right-hand side of an assignment:

var=$othervar           # safe to omit double-quotes
var2=$(somecommand)     # also safe
var="$othervar"          # this also works fine
var2="$(somecommand)"    # so does this

某些 shell 将此扩展到作为命令一部分的赋值,例如 localexport:

Some shells extend this to assignments that're part of a command, like local or export:

export var=$othervar         # *Maybe* ok, depending on the shell
local var2=$(somecommand)    # also *maybe* ok

bash 将这些视为一种赋值,因此它不会对值进行拆分扩展.但是 dash 更像是一个常规命令(其中参数确实被拆分扩展),因此如果您的脚本在 dash 下运行,它可能会出现这样的问题.

bash treats these as a type of assignment, so it doesn't do the split-expand thing with the values. But dash treats this more like a regular command (where the arguments do get split-expanded), so if your script is running under dash it can have problems like this.

例如,假设 somecommand 打印export 和 local 是 shell 命令".然后在破折号中,local var2=$(somecommand) 将扩展为:

For example, suppose somecommand prints "export and local are shell commands." Then in dash, local var2=$(somecommand) would expand to:

local var2=export and local are shell commands.

...将声明局部变量 var2(设置为export")、andlocalareshell.它还会尝试将 commands. 声明为局部变量,但会失败,因为它不是合法的变量名.

...which would declare the local variables var2 (which gets set to "export"), and, local, are, and shell. It would also try to declare commands. as a local variable, but fail because it's not a legal variable name.

因此,使用更多引号!

export var="$othervar"         # Safe in all shells
local var2="$(somecommand)"    # also safe

或分开声明(或两者兼而有之!):

Or separate the declarations (or both!):

export var
var=$othervar         # Safe in all shells, with or without quotes
local var2
var2=$(somecommand)    # also safe, with or without quotes

这篇关于在 shell 脚本中的变量名之前插入“local"会导致错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆