Bashで基本REPLを構築しようとしています。このスクリプトは、ユーザーが実行するディレクトリのファイルのリストを動的に入力します。
ファイルスペース:
|
|\ scripts/
|| script1.sh
|| script2.sh
|
\ shell/
| shell.bashrc
| shell.desktop
shell.bashrcで、次のコマンドを使用してファイル名の配列を取得します。
readarray -d " " filenames < <(find ../bin -type f -executable)
filenames
配列はうまく印刷でき、期待どおりに保存されるスペースで区切られた文字列が含まれています"script1.sh script2.sh"
。
ただし、配列の最初の要素にアクセスしようとすると、echo ${filenames[0]}
すべての要素が印刷されます。 0以外のインデックスは空の文字列を返します。
私のbashバージョンは5.0.17で、ファイルの最初の行は次のようになります。#!/bin/bash
同様の結果として、以下を試した後、「readarray」を使用するように切り替えました。
filenames=($(find "../bin" -type f -executable))
編集:愚かな解決策を見つけましたが、それでも元の投稿に何が問題なのか疑問に思います。解決策:
readarray -d " " filenames < <(find ../bin -type f -executable)
arr=($filenames)
echo ${arr[1]}
予想通り、配列の6番目の要素を印刷します。
答え1
デフォルトでは、find
出力は改行で区切られます。 mapfile/readarray コマンドでこれを設定すると、-d " "
次のような結果が出ます(名前がないと仮定)。含む空白文字)すべての結果は、改行などの1つの文字列に連結されます。それからあなたはecho ${filenames[0]}
(一緒に引用しない変数拡張${filenames[0]}
とデフォルトのspace-tab-newline値IFS
)、シェルは改行文字に分割し、スペース1をecho
使用して結果を再組み立てします。
代わりに使用
readarray -t filenames < <(find ../bin -type f -executable)
入力を改行で区切られたデータに解析しますが、保存された要素から末尾の改行を削除します。または - より良い方法は - あなたのbashバージョンがそれをサポートしている場合、
readarray -t -d '' filenames < <(find ../bin -type f -executable -print0)
改行文字の代わりにヌルバイトを使用します(改行文字を含むファイル名を含むすべての正当なファイル名を安全にします)。