猛砸解析如果[“$ S1” ==“S2”]作为命令

问题描述:

这里是我的bash脚本:

#!/bin/bash -x 
for file in /home/sam/Desktop/RecoveredPix/* 
do 
    model=$(exif -m -t Model $file) 
    if ["$model"=="Canon EOS REBEL T3i"]; then 
    echo $file >> /home/sam/Desktop/mypix.txt; 
    fi 
done 

嗨, 我有一堆我恢复的图片和我专门为拍摄者看通过我的相机,一个T3i。我编写了这个脚本查看exif数据中的模型,如果它匹配“Canon EOS REBEL T3i”,它的路径将被附加到文件中。然而,在运行此脚本,我得到这个返回的终端:

+ for file in '/home/sammeh/Desktop/100CANON/*' 
++ exif -m -t Model /home/sammeh/Desktop/100CANON/IMG_0019.JPG 
+ model='Canon EOS REBEL T3i' 
+ '[Canon EOS REBEL T3i==Canon EOS REBEL T3i]' 
/home/sammeh/Desktop/Search Pix.sh: line 5: [Canon EOS REBEL T3i==Canon EOS REBEL T3i]: command not found 

这是上只是功能性的验证已知拍摄的照片进行。但是,您可以看到,bash将if语句解析为一个命令,以解释任何原因。任何帮助?谢谢!

我运行Ubuntu 13.04 64

+0

快速回答 - 在'[',在'=='周围,在']'之前放一个空格。更完整的答案:[意外\'然后'bash脚本](http://*.com/questions/16092963/unexpected-then-bash-script) – 2013-04-29 23:51:08

你以后和以前[],分别缺失的空间。可能还在==附近:

if [ "$model" == "Canon EOS REBEL T3i" ]; then 
+2

这是因为'['实际*是*一个命令。它是现代shell中的内置,但曾经是(并且在某些系统上仍然是)'/ bin/['(它是'/ bin/test'的硬链接)。 'if'语句需要*任何*命令并根据其返回码进行操作。 – 2013-04-29 23:55:51

由bash解释的shell脚本语言很奇怪。您的问题在于,您需要在[之后和]之前放置空格。此外,您需要使用一个=,而不是像==那样的一对。将其组合在一起:

if [ "$model" = "Canon EOS REBEL T3i" ]; then 

其实,[在shell脚本是针对test命令语法糖。要找出你可以或不能[做什么,请阅读测试的手工录入:

# man 1 test 

据我所知,在原来的Bourne shell,[从来都不是一个内置的,当sh正在运行一个shell脚本,它依赖于一个实际的可执行程序/usr/bin/[!但在Bash中它是一个内置的。因此在Bash中使用[可避免运行额外进程的开销。由于它是内置的,因此您应该将bash的手册页视为法律语法的最终权威,但我认为在实践中它与test命令中记录的内容相同。

无论如何,因为在Bourne shell中它是一个正在执行的实际命令,它需要在它将命令从它的参数中分离出来之后留有空白空间,我猜想在Bash中他们只是继续执行该语法来使Bash脚本更加便携系统使用sh而不是bash

P.S.我喜欢使用更现代的语言来制作非平凡的脚本。如果你继续处理你的脚本,并且shell脚本语法变得很痛苦,请考虑用Python或其他一些更现代的语言来重写。