我正在编写我的第一个bash脚本,用于分析具有不同正则表达式的文本文档。以下命令完全符合它应该做的事情:
egrep "\\i(\[.*\])?" "$1" | cut -d "{" -f2 | cut -d "}" -f1
我决定将此命令移动到一个函数,因为我需要多次执行它。问题是:我得到一个" egrep:没有这样的文件或目录" -Error在函数内部时出现错误。这是代码:
function printThis() {
egrep "\\i(\[.*\])?" "$1" | cut -d "{" -f2 | cut -d "}" -f1
}
...
printThis
我确定我犯了一个完整的初学者错误,但我似乎无法找到它。我还替换了我的代码,所以它以cat命令开头。在这种情况下,我得到了与" cat:..."
相同的错误感谢您的时间。
答案 0 :(得分:1)
您在没有参数的情况下调用printThis()
,但它期望一个($1
) - 实际上,您将传递给空字符串作为egrep
的文件名,这就是它抱怨的内容。
更新:事实证明,OP错误的假设是函数会看到相同的位置参数($1
,$2
,... 。)作为封闭的脚本范围。
相反,必须将参数传递给显式 ;例如,传递第一个参数:printThis "$1"
;使用"$@"
通过传递所有参数。
本答案的其余部分涉及如何在函数内检查强制参数。
如果您希望printThis()
使用 stdin 输入,只需删除"$1"
:grep
默认会从stdin获取输入(但会如果给出至少1个文件名操作数,则忽略stdin输入。
如果您确实要传递文件名操作数:强制执行的一种简单方法是传递一个是{{1构造,退出整个shell - 而不仅仅是函数! - 如果${1:?<errMsg>}
丢失或为空,则显示给定的错误消息和退出代码1
; e.g:
$1
注意:虽然上述使用有意义的错误消息强制存在参数值的方法很方便,但由于以下几个原因这很棘手:
function printThis() {
: "${1:?$FUNCNAME: ERROR: Please specify a filename.}"
egrep "\\i(\[.*\])?" "$1" |
cut -d "{" -f2 | cut -d "}" -f1
}
# ...
# Calling `printThis` without a filename now aborts the script and
# reports "... printThis: ERROR: Please specify a filename."
printThis
只会终止cat -n "${1:?missing file}" | ...
运行的子shell,而不是当前shell(默认情况下,所有管道段都在自己的子shell中运行)。这就是为什么上面的代码使用cat
null utility作为自己的语句来检查参数的原因。:
因此,更好 - 尽管更详细 - 的方法是使用显式检查:
/Users/jdoe/scripts/foo: line 7: