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
Nesting if in a for loop
提问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 ls
to iterate files, and quote parameter expansions "$x"
. The for and if syntax itself is correct. I prefer to put the do
and then
on the same line though
两件事情。切勿用于ls
迭代文件和引用参数扩展"$x"
。for 和 if 语法本身是正确的。我更喜欢把do
和then
放在同一条线上
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 for
iterates wordsand ls
outputs 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