選択ループは配列に格納された文字列のスペースを処理しません。

選択ループは配列に格納された文字列のスペースを処理しません。

課題のオプション部分として、selectを使用して対話型メニューを作成し、スペースを含むファイルとディレクトリ名をサポートするようにしています。要点は、ユーザーがインタラクションメニューですでに決定されている特定の機能を使用して、インタラクションするファイルまたはディレクトリを選択できることです。要件の一部としてselectを使用する必要があります。この例では、catを使用してファイルの保存情報を取得しようとしています。

しかし、これはうまくいきません

shopt -s nullglob
FARRAY= (*)
shopt -u nullglob
PS3= "Please select a file"
select SHOLDER in "${FARRAY[@]}"
do
   if  test -d "${FARRAY[$SHOLDER]}"
   then
       echo "Please select a file"
   else
       cat "${FARRAY[$SHOLDER]}"
       break
   fi
done

エラーが発生します。式に構文エラーがあります(エラートークンは「そこ」です)。こんにちは私がテストしたファイル名です。

選択ループとcat部分の配列名の前に「!」を追加すると、機能しますが、 "${!FARRAY[@]}" 実際には使用できないファイル名ではなく、配列インデックスのみが表示されます。なぜこれが起こるのか、そしてスクリプトがこの部分を正しく実行するには、どのような手順を実行する必要があるのか​​を知りたいです。

ベストアンサー1

からhelp select

select: select NAME [in WORDS ... ;] do COMMANDS; done

[...]行が表示されている単語の1つに対応する数字で構成されている場合、NAMEはその単語に設定されます。

たとえば、

$ select foo in abc def; do echo "foo is '$foo'"; break; done
1) abc
2) def
#? 2
foo is 'def'

つまり、名前付きファイルを選択してfoo.c(ファイル数の代わりに)SHOLDERに設定すると、配列にインデックスを付けるときに算術エラーが発生します。foo.c

selectオプションの番号は1から始まり、Bash配列のインデックスは0から始まるため、問題が発生する可能性があります。

質問を複雑にする誤字を避けるために、ここで質問にコードをコピーして貼り付けるのが最善です。この割り当ての空白と同様に、FARRAY= (*)構文エラーが発生します。

おすすめ記事