bash 在 for 循环中嵌套 if

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12030316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:34:01  来源:igfitidea点击:

Nesting if in a for loop

bashfor-loopif-statement

提问by James Jenkinson

I'm fairly new to bash scripts, so this is probably a stupid syntax error, but why is this code not working?

我对 bash 脚本还很陌生,所以这可能是一个愚蠢的语法错误,但为什么这段代码不起作用?

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

The separate for and if section work fine on their own, but this produces no output.

单独的 for 和 if 部分可以正常工作,但这不会产生任何输出。

回答by geirha

Two things. Never use lsto iterate files, and quote parameter expansions "$x". The for and if syntax itself is correct. I prefer to put the doand thenon the same line though

两件事情。切勿用于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

For learning bash, I recommend reading http://mywiki.wooledge.org/BashGuidemost other tutorials and guides are unfortunately not very good.

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

The reason for not doing for x in $(ls)to iterate files is because foriterates wordsand lsoutputs lines with filenames. if those filenames happen to contain whitespace, those filenames will be split up further into words, so you'll be iterating the wordsof the filenames, not the filenames. Obviously, for the simple cases that works, but why use a half-working solution when there's a shorter and more elegant way that handles all cases?

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

With for x in *the shell replaces the *with all filenames matching that pattern in the current directory (called pathname expansion), and each filename will be a separate word so it will work no matter what characters the filename contains. Filenames can contain any character (including newlines), except /and the NUL byte (\0).

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

See http://mywiki.wooledge.org/ParsingLsfor more on that.

有关更多信息,请参阅http://mywiki.wooledge.org/ParsingLs

As for using [[vs [. [is a command inherited from the bourne shell, used to test strings, files and numbers. Bash has added a more powerful [[keyword that can do everything [can and more. If you're writing an sh script, you must use [, but in bash scripts you should use the more powerful [[and ((syntaxes. See http://mywiki.wooledge.org/BashFAQ/031for more about the difference between [and [[.

至于使用[[vs [[是一个继承自 bourne shell 的命令,用于测试字符串、文件和数字。Bash 添加了一个更强大的[[关键字,可以做任何事情[,甚至更多。如果您正在编写 sh 脚本,则必须使用[,但在 bash 脚本中,您应该使用更强大的[[((语法。有关和之间区别的更多信息,请参阅http://mywiki.wooledge.org/BashFAQ/031[[[

回答by imm

Maybe there's a problem with the characters being used to separate the different parts of the statement?

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

What if you tried:

如果您尝试过会怎样:

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

Does that produce output?

那会产生输出吗?

回答by paulsm4

1) the syntax is perfectly legal

1) 语法完全合法

2) Yes, you can nest "if/else" blocks inside a loop. You can also nest inner loops within an outer loop :)

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

3) "if [ -d $x ]" checks if "x" is a "directory".

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

If you don't see any output, then perhaps you don't have any subdirectories?

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

SUGGESTION:

建议:

  • open a terminal window

  • Run your script. See whether or not you get any output.

  • If not, then type mkdir moose. This will create a subdirectory called (uncoincidentally) "moose".

  • Re-run your script. You should see at least"moose".

  • 打开终端窗口

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

  • 如果没有,则键入mkdir moose。这将创建一个名为(意外地)“moose”的子目录。

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

回答by SahItaN

#!/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