私はディレクトリを引数として受け入れ、そのリスト、テストファイル、およびディレクトリを印刷する単純なbashスクリプト(非常に初めてです!)を書いています。これが私が処理する方法です。
#!/bin/bash
# Lists all files and directories (non-recursively) in a specified directory
if [ $# -gt 1 ]; then
echo "Error. Please specify only one directory. ($#)"
exit
fi
if [ -z $1 ]; then
echo "No directory specified. Exiting."
exit
fi
echo "Listing for $1:"
$dirs=`ls $1`
echo "Dirs: $dirs" # Just to confirm if all is well
# Loop through and print
for i in $dirs;
do
if [ -f $i ]; then
echo "File: $i"
elif [ -d $i ]; then
echo "Directory: $i"
fi
done
問題は私のforループにあります。このスクリプトを実行してホームディレクトリに入力すると、次のエラーが発生します。
./list_files_and_dirs.sh: line 16: =Calibre: command not found
変数に関連するコマンド置換で間違いをしていることを知っていますが、何かはわかりません。誰か助けてください!
=================更新===================
答えに基づいて入力された新しい(最後の部分)コードは次のとおりです。
dirs=`ls "$1"`
#echo "Dirs: $dirs" # Just to confirm if all is well
IFS=$'\n'
# Loop through and print
for i in $dirs;
do
if [ -f "$i" ]; then
echo "File: $i"
elif [ -d "$i" ]; then
echo "Directory: $i"
fi
done
答え1
注:私は自分でBashを学んでいると仮定します。本番環境ではこのコードを使用しないでください。find "$directory" -maxdepth 1 -type d
ディレクトリと-type f
ファイルが提供されます。
16行について文句を言うので見てみましょう。
$dirs=`ls $1`
変数に割り当てるには、変数を含めないでください$
。
dirs=`ls $1`
今何が起こっているのかは次のとおりです。
$dirs
空になる可能性があるため、置き換えることはありません。- コマンド
ls
が実行され、その出力が「コマンド」に置き換えられます。 - ディレクトリの最初のファイルは、
Calibre
次のコマンドを残します。=Calibre x y z ...
=Calibre
有効なコマンドではないため、エラーが発生します。
しかし、まだそうしていません。ファイル名にスペースが含まれているとエラーが発生します。この問題を解決するには、さらにいくつかの作業を行う必要があります。
IFS=$'\n'
ループの前のどこかに含める必要がありますfor
。これにより、フィールド区切り文字が改行文字に設定され、ループがファイルをスペースまたはタブにfor
分割するのを防ぎます(技術的にはファイル名に改行文字も含まれているため、このような状況が発生する可能性はほとんどありません)。そのようなファイルに会っても深刻な問題は発生しませんが、問題になる場合に備えて可能性に注目する価値があります。-f
スペースを含むファイル名がおよび他のさまざまなパラメータに変更されないようにするには、-d
名前の周りに引用符を入れる必要があります$i
。 (したがって:[ -f "$i" ]
と[ -d "$i" ]
.スペースを含むディレクトリをサポートするには、$1
それを使用するたびに同じ操作を実行する必要があります。
答え2
Marinusはこのエラーが発生する理由を説明しました。ここではこれが必要ないことを指摘したいと思いますls
。これにより、それに伴うすべての問題を回避できます。出力の解析。次のことができます。
#!/bin/bash
# Lists all files and directories (non-recursively) in a specified directory
if [ "$#" -gt 1 ]; then
echo "Error. Please specify only one directory. ($#)"
exit
fi
if [ -z "$1" ]; then
echo "No directory specified. Exiting."
exit
fi
echo "Listing for $1:"
# Loop through and print
for i in "$1"/*;
do
if [ -f "$i" ]; then
echo "File: $i"
elif [ -d "$i" ]; then
echo "Directory: $i"
fi
done