私は bash スクリプトにかなり慣れていないので、これはおそらくばかげた構文エラーですが、このコードが機能しないのはなぜですか?
for x in $(ls)
do
if [ -d $x ]
then
echo $x
fi
done
個別の for セクションと if セクションはそれ自体で正常に機能しますが、出力は生成されません。
私は bash スクリプトにかなり慣れていないので、これはおそらくばかげた構文エラーですが、このコードが機能しないのはなぜですか?
for x in $(ls)
do
if [ -d $x ]
then
echo $x
fi
done
個別の for セクションと if セクションはそれ自体で正常に機能しますが、出力は生成されません。
2つのこと。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を読むことをお勧めします。他のほとんどのチュートリアルやガイドは、残念ながらあまり良くありません。
The reason for not doing for x in $(ls)
to iterate files is because for
iterates words and 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 words of 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?
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).
See http://mywiki.wooledge.org/ParsingLs for more on that.
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/031 for more about the difference between [
and [[
.
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?
1)構文は完全に合法です
2)はい、ループ内に「if/else」ブロックをネストできます。外側のループ内に内側のループをネストすることもできます:)
3)「if [-d $ x]」は、「x」が「ディレクトリ」であるかどうかをチェックします。
出力が表示されない場合は、サブディレクトリがない可能性がありますか?
提案:
ターミナルウィンドウを開く
スクリプトを実行します。出力が得られるかどうかを確認します。
そうでない場合は、と入力しmkdir moose
ます。これにより、(偶然にも)「moose」というサブディレクトリが作成されます。
スクリプトを再実行します。少なくとも「ムース」が見えるはずです。