bash - 在 shell 脚本中的变量名前插入“local”会导致错误
问题描述
这段代码(它是 shell 函数的一部分)完美运行:
output=$(\
cat "${vim_file}" | \
sed -rne "${EXTRACT_ENTITIES}" | \
sed -re "${CLEAR_LEADING_QUOTES}" | \
sed -re "${NORMALIZE_NAMES}" \
)
但是当我试图在作业前插入“本地”这个词时……</p>
local output=$(\
cat "${vim_file}" | \
sed -rne "${EXTRACT_ENTITIES}" | \
sed -re "${CLEAR_LEADING_QUOTES}" | \
sed -re "${NORMALIZE_NAMES}" \
)
…我收到一个奇怪的错误:
local: commands.: bad variable name
代码中没有错误的不可见字符:只有制表符在其他地方产生缩进和空格。该脚本以“#!/bin/sh”开头。在函数中的其他变量之前插入“local”不会导致任何问题。用另一个任意字符串替换“输出”(变量的名称)不会改变任何事情。操作系统是Linux。
解决方案
非常简短的回答:使用更多引号!
local output="$(\
cat "${vim_file}" | \
sed -rne "${EXTRACT_ENTITIES}" | \
sed -re "${CLEAR_LEADING_QUOTES}" | \
sed -re "${NORMALIZE_NAMES}" \
)"
更长的答案:双引号变量引用和命令替换几乎总是一个好主意。双引号可防止它们受到分词和文件名通配符扩展的影响,这很少是您想要的,并且可能会导致令人困惑的问题。
在某些情况下,去掉双引号是安全的,但规则令人困惑,难以记住,而且容易出错。这是那些令人困惑的案例之一。不会发生分词和通配符扩展的情况之一(因此可以安全地去掉双引号)是在赋值的右侧:
var=$othervar # safe to omit double-quotes
var2=$(somecommand) # also safe
var="$othervar" # this also works fine
var2="$(somecommand)" # so does this
一些 shell 将此扩展到作为命令一部分的分配,例如local
or export
:
export var=$othervar # *Maybe* ok, depending on the shell
local var2=$(somecommand) # also *maybe* ok
bash 将这些视为一种赋值,因此它不会对值进行拆分扩展。但是 dash 更像是一个常规命令(其中参数确实被拆分扩展),所以如果你的脚本在 dash 下运行,它可能会遇到这样的问题。
例如,假设somecommand
打印“export and local are shell commands”。然后在破折号中,local var2=$(somecommand)
将扩展为:
local var2=export and local are shell commands.
...这将声明局部变量var2
(设置为“export”)、and
、local
、are
和shell
. 它也会尝试声明commands.
为局部变量,但会失败,因为它不是合法的变量名。
因此,使用更多的引号!
export var="$othervar" # Safe in all shells
local var2="$(somecommand)" # also safe
或分开声明(或两者!):
export var
var=$othervar # Safe in all shells, with or without quotes
local var2
var2=$(somecommand) # also safe, with or without quotes
推荐阅读
- html - 引导程序中剩余的空间
- c# - TextBox 不更新 Observable 集合
- python - 在给定图像链接的情况下处理烧瓶中的图像
- java - 构建项目期间的 Eclipse 202003 javaIO 错误
- c# - RavenDB:如何防止 $type 被保存到动态类型属性?
- swift - 继续获取范围之外的索引并且表格无法正确显示,可能是由于 DispatchQueue
- google-data-studio - 谷歌数据工作室 User_Pass 授权
- java - 如何使用 maven shade 插件捆绑来自不同模块的类
- python-3.x - 如何将重复的行数据转换为python中的列?
- wordpress - 重力形式 - 嵌套条件合并标签