参数中的变量值未得到解析,并且 echo 语句无法打印

参数中的变量值未得到解析,并且 echo 语句无法打印

我有一个子脚本,它将获取主脚本并将参数传递给主脚本中可用的函数并执行函数定义。函数调用对我来说工作正常,但我面临以下问题

  1. 第一个echo声明没有被打印

  2. 子脚本参数中的变量now未得到解析

    请在下面找到我的发现。

主要脚本

Function_1 ()
{
cd /home/test/

File_name="$1".txt

if [[ "$File_name" =~ ^[[:alnum:]][[$_."#&']] ]]; then
echo " For your Info, File name can be alpha numeric and can contain special characters like $_."&'#" please proceed "
fi

 if [[ -f "$File_name" ]];
then
echo "File Name - $File_name"
else 
echo "File Name - $File_name doesn't exists"
 fi

}

子脚本

export now=$( date '+%Y%m%d' )
Function_1 'abc_${now}' 

预期结果

For your Info, File name can be alpha numeric and can contain special characters like $_."&'#" please proceed 
File Name - abc_20200204.txt

实际结果

File Name - abc_$now.txt doesn't exists

答案1

if [[ "$File_name" =~ ^[[:alnum:]][[$_."#&']] ]]; then

您正在使用 a"和 a ,'因此表达式不完整,并且失败。

答案2

我认为您遇到的问题一般可以归因于处理特殊字符引用在你的 shell 脚本中。

作为主要评论:您没有提到您的子脚本如何访问主脚本中的函数,但我假设您做了类似的事情

~$ source main_script.sh
~$ export now=$( date '+%Y%m%d' )
~$ Function_1 'abc_${now}'

如果我这样做,我的 shell 会抱怨几个语法错误,并且脚本将无法工作。我假设您也使用了bash因为您使用了该标签,并且我承认我很惊讶您没有遇到这些错误。您可能仍然想考虑使用像shellcheck, available 这样的工具在线的或者作为许多 Linux 发行版中的软件包来验证您的 shell 脚本 - 它当然可以帮助我查找拼写错误等。

现在说说你遇到的问题。

您声明第一个echo输出永远不会发生。我认为这与正则表达式的构造以及特殊字符的使用有关:

  • 在测试语句中,您使用包含 shell 特殊字符的[[ "$File_name" =~ ^[[:alnum:]][[$_."#&']] ]]字符列表:例如,可能是[$_."#&']$_解释为最后一个 shell 参数,并且双引号"将被 shell 解释为文字字符串的开头,该字符串在下一行以命令"的第一行结尾echo。这应该会引发语法错误,因为 shell 会尝试按照 shell 的建议解释您的输出消息;当我尝试时确实如此。您应该确保转义这些字符以阻止 shell 进行不需要的解释,如 中所示\$_\"\#\&\'
  • 此外,您还可以使用双方括号[[ ... ]]来表示字符列表。然而,这在语法上是未定义的。什么[ ... ]定义的是一个仅包含一个字符的列表特点班级,例如[:alnum:]某种构造确实会写为[[:alnum:]],就像您在正则表达式的第一部分中所做的那样。因此,您应该省略“外部”方括号对。
  • 您已使用“开始锚点”开始正则表达式^。因此我假设您希望允许文件名开始包含常规字母或数字,但可能包含您提到的所有特殊字符。但是,您的正则表达式仅允许以以下内容开头的文件名字母数字字符,然后要求特殊字符之一作为第二个字符。如果您想确保除了字母数字字符之外还允许使用任意数量的字符,您可以编写类似^[[:alnum:]][[:alnum:]\$_.\"\#\&\']*$.第二部分是[ ... ]包含字符类[:alnum:]和的字符列表此外特殊字符$, _, ., ", #,&', 零次或多次 ( *) 直到字符串末尾 ( $)。最后一个锚字符确保全部的文件名仅包含您允许的字符。

您的下一点涉及${now}变量未解析(即“扩大”在 shell 术语中)。

  • 正如几条评论中已经指出的,参数扩展不会发生在单引号内' ... '。如果您使用双引号" ... ",则变量扩展将起作用。

  • 您似乎确定此时需要单引号。事实确实如此,你无能为力;在这种情况下,您可能需要进一步解释为什么您需要单引号(即您想要实现的目标,或者是否进一步处理表达式'abc_${now}' 包括稍后在此过程中需要引用)。

相关内容