在bash中的测试语句中运行命令

时间:2012-12-28 15:13:01

标签: bash shell

我有一段代码可以找到目录中的第一个文件:

bash~> $( echo eval "ls | head -1" )
arguprog.sh

然后将此片段添加到if语句中,以便在该文件为arguprog.sh时运行另一组命令:

bash~>  if [[ $( echo eval "ls | head -1" ) == "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi;
FALSE

然而,这并不是我想要的。即使第一个文件是arguprog.sh!

,它也返回FALSE

有没有办法在完全在测试块中进行字符串比较的同时解决这个问题?

3 个答案:

答案 0 :(得分:7)

首先,eval是邪恶的,特别是当它不需要时。在您的情况下,eval 需要!

将您展示的编码恐怖替换为:

ls | head -1

并将其包含在您的测试声明中:

if [[ $(ls | head -1) = "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi

但这是错误和破坏(见下文)。

现在更通用:不解析ls 的输出。如果要在当前目录中找到第一个文件(或目录或...),请使用globs和此方法:

shopt -s nullglob
files=( * )
# The array files contains the names of all the files (and directories...)
# in the current directory, sorted by name.
# The first one is given by the expansion of "${files[0]}". So:
if [[ "${files[0]}" = "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi

请注意,解析ls的方法错误。看:

$ # Create a new scratch dir
$ mkdir myscratchdir
$ # Go in there
$ cd myscratchdir
$ # touch a few files:
$ touch $'arguprog.sh\nwith a newline' "some other file"
$ # I created 2 files, none of them is exactly arguprog.sh. Now look:
$ if [[ $(ls | head -1) = "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi
TRUE
$ # HORROR!

对此有扭曲的解决方法,但实际上,最好的方法就是我给你的方法。

完成!

答案 1 :(得分:1)

$( echo eval "ls | head -1" )的值为"eval ls | head -1"而非"arguprog.sh",因此您获得FALSE的原因。

看看这个:

$ a=$( echo eval "ls | head -1" )
$ echo $a
eval ls | head -1

运行arguprog.sh时看到bash~> $( echo eval "ls | head -1" )的原因是因为bash执行eval ls | head -1命令并返回arguprog.sh的结果。

为了在你的if语句中做同样的事情,你需要将它包含在另一组$(...)中来执行它,如下所示:

$ if [[ $($( echo eval "ls | head -1" )) == "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi;
TRUE

但不要那样做!简单地使用它会容易得多:

$ if [[ $(ls | head -1) == "arguprog.sh" ]]; then echo "TRUE"; else echo "FALSE"; fi;
TRUE

另请注意,解析ls的输出不是好习惯。有关详细信息,请参阅ParsingLs

答案 2 :(得分:0)

尝试这种方式:

 if [[ `ls | head -1` = "04 dynamic-programming.pdf" ]]; then 
      echo "TRUE"
 else 
      echo "FALSE"
 fi

您应该只使用=代替==并跳过eval部分。