Bash:如果在for循环中嵌套

时间:2012-08-19 21:53:20

标签: bash if-statement for-loop ls

我是bash脚本的新手,所以这可能是一个愚蠢的语法错误,但为什么这段代码无效?

for x in $(ls)
do
  if [ -d $x ]
  then
  echo $x
  fi
done

单独的for和if部分可以自行处理,但这不会产生任何输出。

感谢。

4 个答案:

答案 0 :(得分:22)

两件事。切勿使用ls来迭代文件,并引用参数扩展"$x"。 for和if语法本身是正确的。我更喜欢将dothen放在同一行但是

for file in *; do
    if [[ -d "$file" ]]; then
        echo "$file is a directory"
    elif [[ -f "$file" ]]; then
        echo "$file is a regular file"
    fi
done

对于学习bash,我建议阅读http://mywiki.wooledge.org/BashGuide大多数其他教程和指南遗憾的是不是很好。

不执行for x in $(ls)迭代文件的原因是for迭代ls输出带有文件名的行。如果这些文件名碰巧包含空格,那么这些文件名将被进一步拆分为单词,因此您将迭代文件名的单词,而不是文件名。显然,对于有效的简单案例,但为什么在处理所有案例时采用更简洁,更优雅的方式使用半工作解决方案?

使用for x in *,shell将*替换为当前目录中与该模式匹配的所有文件名(称为路径名扩展),每个文件名将是一个单独的单词,因此无论什么字符都可以使用文件名包含。文件名可以包含除/和NUL字节(\ 0)之外的任何字符(包括换行符)。

有关详情,请参阅http://mywiki.wooledge.org/ParsingLs

至于使用[[ vs [[是从bourne shell继承的命令,用于测试字符串,文件和数字。 Bash添加了一个功能更强大的[[关键字,可以执行[可以执行的所有操作。如果您正在编写sh脚本,则必须使用[,但在bash脚本中,您应该使用功能更强大的[[((语法。有关[[[之间差异的详情,请参阅http://mywiki.wooledge.org/BashFAQ/031

答案 1 :(得分:5)

也许用于分隔语句不同部分的字符存在问题?

如果你尝试了怎么办?

for x in $(ls); do if [ -d $x ]; then echo $x; fi; done

这会产生输出吗?

答案 2 :(得分:1)

1)语法完全合法

2)是的,您可以在循环中嵌套“if / else”块。您还可以在外部循环中嵌套内部循环:)

3)“if [-d $ x]”检查“x”是否为“目录”。

如果您没有看到任何输出,那么您可能没有任何子目录?

建议:

  • 打开终端窗口

  • 运行您的脚本。看看你是否得到任何输出。

  • 如果没有,请输入mkdir moose。这将创建一个名为(uncoincidentally)“moose”的子目录。

  • 重新运行您的脚本。你应该看到至少“moose”。

答案 3 :(得分:-1)

#!/bin/bash

name=c
for command in "cd $home" " cd XSStrike" "python xsstrike.py"
do
    if [[ $name == "c" ]]; 
    then
        echo "<==========> access granted <==========>"
        $command
    else
        echo "<==========> access denied <==========>"
    fi
done