ディレクトリ名を関数に渡そうとすると、「ディレクトリです」というエラーが発生します。

ディレクトリ名を関数に渡そうとすると、「ディレクトリです」というエラーが発生します。

私のBashスクリプトでは、findを使用してワイルドカードにフォルダ名を取得します。

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard});
do
  stuff=doStuff ${i}
done

doStuff() {
  echo ${1}
  return ${1}'/hello';
}

問題は、これを実行すると次のエラーが発生することです($ {i}が「home / me / my_directory」に対応すると仮定)。

line 111: '/home/me/my_directory': is a directory. 

(ライン111は「doStuff」のあるラインです)

私はこれを試しましたが、役に立ちませんでした。

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard});
do
  stuff=doStuff "${i}"
done

明らかに、これはプログラムがディレクトリを実行しようとしているためですが、私はそれを操作できる文字列として欲しいです。

ベストアンサー1

引用符とコマンドの置換が問題です。

あなたが経験している具体的な問題は、シェルが/home/me/my_directory環境変数を使用して呼び出されたコマンドを実行しようとするためですstuff=doStuff
あなたが本当に望むのは、(私が正しく解釈したら)doStuffの値を$i引数として使用して実行し、出力を変数に割り当てることですstuff。これを行う方法は、コマンドを$()

stuff="$(doStuff "$i")"

私がすべてに引用符を入れたことに注意してください。これは、シェルがトークン化したくないことをトークン化するのを防ぐためです(/foo/bar baz単一の引数を/foo/barandに置き換えますbaz)。

また、関数の出力はreturn

より多くの引用符を使用する必要があるため、他のすべての項目にも追加する必要があります。以下はスクリプトのフルバージョンです。

doStuff() {
  echo "${1}" >&2
  printf '%s/hello' "$1";
}

IFS=$'\n'
for i in $(find "${directory}" -mindepth 1 -type d -name "${wildcard}");
do
  stuff="$(doStuff "${i}")"
done

関数定義を使用する前に最初に置く必要があります。シェルは、ファイルを複数回渡すコンパイルされたプログラムのように解析しません。これはトップダウンです。また、STDERRに送信するように
変更し、端末に表示してからSTDOUTに送信して変数にキャプチャします。doStuffechoprintfstuff

ディレクトリに改行文字が含まれている場合でも、問題が発生する可能性があります。しかし、これはシェルの制限です。ファイルパスに含めることができない唯一の文字はNULL文字(\0)です。ただし、bashや他のシェルは文字列にNULL文字を格納できないため(すべてではありませんが、多数。zshは可能であることを知っている)、区切り文字として使用することはできません。

おすすめ記事