私の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/bar
andに置き換えます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に送信して変数にキャプチャします。doStuff
echo
printf
stuff
ディレクトリに改行文字が含まれている場合でも、問題が発生する可能性があります。しかし、これはシェルの制限です。ファイルパスに含めることができない唯一の文字はNULL文字(\0
)です。ただし、bashや他のシェルは文字列にNULL文字を格納できないため(すべてではありませんが、多数。zshは可能であることを知っている)、区切り文字として使用することはできません。
答え2
良い努力ですが、bash
実際には単純なスクリプト言語ですが、プログラミング言語のように書こうとしていることを示しています。あなたの構造の問題は、それがあなたが思うことを意味しないstuff=doStuff arg
ということです。bash
Toはbash
変数stuff=doStuff
割り当てとarg
コマンドです。次の2つのリンクを読んでください。
- コマンドの戻り値および/または出力を変数にどのように格納できますか?
- 関数から文字列(または大きな数字または負数)を返す方法は? 「return」を使用すると、0から255までの数字のみを指定できます。
あなたが持っているものと同様の動作バージョンは次のとおりです
doStuff () {
echo "$1/hello"
}
stuff=$(doStuff "$i")
答え3
エラーが発生した行は、思ったように機能しません。
まず、環境変数 stuff を文字列 "doStuff" に設定し、次に ${i} をコマンドとして実行しようとします。 ${i} はディレクトリなので、指定されたエラーメッセージで失敗します。