我是bash脚本的新手,所以这可能是一个愚蠢的语法错误,但为什么这段代码无效?
for x in $(ls)
do
if [ -d $x ]
then
echo $x
fi
done
单独的for和if部分可以自行处理,但这不会产生任何输出。
感谢。
答案 0 :(得分:22)
两件事。切勿使用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
对于学习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