bash中的for循环只运行一次

时间:2016-10-27 02:49:32

标签: bash macos

我正在使用bash进行解析检查,但是这个循环只运行一次并结束而没有错误:

for file in *; do \
  WIDTH = $(identify -ping -format '%h' $file) \
  HEIGHT = $(identify -ping -format '%w' $file) \
  if [ "$WIDTH" -ge 500 ]; then \
    echo width greater than 500 \
  elif ["HEIGHT" -ge 500]; then \
    echo height greater than 500 \
  fi \
done

输出

height greater than 500 fi done

为什么不检查所有文件?

2 个答案:

答案 0 :(得分:1)

#!/bin/bash
# using bash, not sh, ensures that <(), (( )), and other extensions are available.

for file in *; do
  IFS=: read -r width height < <(identify -ping -format '%w:%h\n' "$file")
  if (( width >= 500 )); then
    printf '%s\n' "$file has width greater than 500"
  elif (( height >= 500 )); then
    printf '%s\n' "$file has height greater than 500"
  fi
done
  • 运行identify两次会使调用外部命令的性能影响加倍;最好只运行一次,并在一次传递中读取这两个变量。用于将identify命令的输出收集到流中的语法是process substitution,而read命令在BashFAQ #001the relevant bash-hackers wiki page中进行了相当全面的讨论。
  • 反斜杠续行;当你有一个跨越多行的简单命令(不是像这样的复合命令)时,它们是合适的。在这种情况下,他们完全错了。
  • [命令,命令名称需要通过空格与参数分隔。就像您运行ls -l而不是ls-l一样,您无法运行[foo;它必须是[ foo,作为两个单独的单词。 (如果更清楚,请考虑使用同义词testif test "$width" -ge 500; then ...)。
  • 指定所有大写字母变量名称by POSIX-defined convention用于具有系统和shell含义的名称,而具有至少一个小写字符的名称保留供应用程序使用。 (该约定明确适用于环境变量,但shell变量共享相同的命名空间:设置一个名称与环境变量重叠的shell变量将覆盖后者)。
  • 使用printf而不是echo具有更好定义的行为:the POSIX specification for echo保留了大范围的行为未定义,如果打印包含文字反斜杠的文件名,{{1}的行为变得依赖于实现,因此不可移植。请参阅链接页面的“应用程序使用”部分。
  • 使用echo将您置于数学上下文中,其中可以使用变量名称而不使用前面的(( )),并且可以使用更自然的C样式数学语法,例如$而不是>=。 (这是一个基础 - POSIX sh仅指定-ge,它具有相似的行为但是是替换命令;因此,在POSIX sh中,可以改为编写$(( ))来测试此替换的结果)

答案 1 :(得分:0)

过早地被问到,使用这个很棒的助手 - shellcheck来解决这个问题:

ui.mask