Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用bash eval内置函数允许ini文件中包含命令字符串_Bash_Shell_Variables_Eval - Fatal编程技术网

使用bash eval内置函数允许ini文件中包含命令字符串

使用bash eval内置函数允许ini文件中包含命令字符串,bash,shell,variables,eval,Bash,Shell,Variables,Eval,我一直在编写一个bash脚本,该脚本接受一个ini文件(使用与脚本一起开发的格式),并读取该文件,执行指定的操作 ini格式的其中一个函数允许使用eval传入并运行shell命令。当命令包含变量名时,我遇到了一个问题 eval(或者通常的shell)似乎没有正确地替换值,而且大多数情况下,它似乎用空格替换所有变量名,从而破坏了命令。创建字符串输出的子shell似乎也有同样的问题 奇怪的是,这在我的开发机器(运行LinuxMint13)上起作用,但当我将脚本移动到运行CentOS5.8的目标机器上

我一直在编写一个bash脚本,该脚本接受一个ini文件(使用与脚本一起开发的格式),并读取该文件,执行指定的操作

ini格式的其中一个函数允许使用
eval
传入并运行shell命令。当命令包含变量名时,我遇到了一个问题

eval
(或者通常的shell)似乎没有正确地替换值,而且大多数情况下,它似乎用空格替换所有变量名,从而破坏了命令。创建字符串输出的子shell似乎也有同样的问题

奇怪的是,这在我的开发机器(运行LinuxMint13)上起作用,但当我将脚本移动到运行CentOS5.8的目标机器上时,这些问题就出现了

我从ini文件中读取的一些代码示例:

shellcmd $toolspath/program > /path/file

shellcmd parsedata=$( cat /path/file )
它们通过一个脚本函数,该函数去掉前导的
shellcmd
,然后使用

eval ${scmd}
关于是什么导致了这种奇怪的行为以及我能尝试解决问题的方法,有什么想法吗?我的最终目标是能够从文件中读入一行,让脚本执行它,并能够正确处理read-in命令中的脚本变量。

使用Bash 3.2.25(CentOS 5)我尝试了这一点,效果很好:

toolspath='/bin'
while read prefix scmd
do
    if [[ $prefix == 'shellcmd' ]]
    then
        echo "Evaluating: <$scmd>"
        eval ${scmd}
    else
        echo "$prefix ignored"
    fi
done < ini
显然,我必须设定路径。最有可能的是,在切换机器时,您必须更改路径。你的路径有嵌入的空格吗


你是怎么传送文件的?你可能是从窗户进去的吗?我一时兴起,在
ini
文件上执行了
unix2dos
,得到了与您描述的类似的症状。这是我最好的猜测。

我找到了一个合适的替代命令,该命令是导致此问题的原因,因此我将此问题标记为已解决


从我所有的调查来看,我似乎在bashshell中发现了一个模糊的bug。我试图求值的特定命令在其输出中返回了一个终端代码,并且由于shell处于读取循环中,输入从文件重定向,因此导致了一些奇怪的行为。我的解决方案是将对这个特定命令的调用移到读取循环之外。它仍然不能解决根本问题,我认为这是bashshell中的一个bug。希望这能帮助遇到相同(模糊)问题的其他人。

最好创建一个带有硬编码命令的最小示例,其中
eval
的行为不符合您的要求。例如:
a=1;cmd='echo$a>foo';eval$cmd
既然你说它可以在LinuxMint13上运行,但不能在CentOS5.8上运行,那么它可能来自不同的bash版本或shell?(例如,/bin/sh在debian和Ubuntu上默认为dash。)谢谢你的建议。您的代码似乎工作正常,但我仍然不明白为什么我的代码不工作(即使您的代码几乎相同)。路径没有空格,但在某些目录前面有一个点(.)。设置变量时会引用路径。这些文件完全是在linux机器上开发的,直接使用thumb驱动器传输(windows没有接触这些文件)。我通过dos2unix运行这些文件只是为了确保它没有改变任何东西。我建议您尝试使用一条失败的语句,并使用
bash-x script name
运行它以获得跟踪。如果我没听错的话,我的代码正常,而你的代码却失败了?也许如果你发布了你所有的代码,我们可能会有一个更好的主意。我想我可能已经追踪到了我试图对其进行评估的特定命令。我试图调用的工具是一个不断更新屏幕的监控工具,但是它有一个选项,只显示一个输出勾号,而不是一个不断更新。当我手动编辑文件时,它会清除屏幕并只显示文件的内容,当我在gedit中打开文件时,我会在顶部看到一些非打印字符。在脚本模式下运行与以交互方式运行时,可能会有一些不同之处,导致脚本在看到非打印字符时表现出不同的行为。经过进一步调查,这个问题似乎与我需要使用脚本调用的特定工具有关。它在输出的开头放入一个终端代码^[H^[J(其中^[是转义字符)出于某种原因,这似乎会导致shell出现问题。我尝试通过sed管道传输输出以删除该字符,但在运行任何应急代码来解决该问题之前,它似乎会导致问题。有没有关于如何让bash暂时忽略终端代码的建议?显而易见的答案是chang生成这些字符的工具。为什么要生成它们?我想说,这是生成这些字符的代码中的错误,而不是Bash。
shellcmd $toolspath/ls > /home/user1/file     
shellcmd parsedata=$( cat /home/user1/file )
shellcmd echo $parsedata