デフォルトでは、ディレクトリがなくなったディレクトリが見つかるまで、サブディレクトリを繰り返し一覧表示しようとします。ここでの問題は、与えられた関数に引数を渡すとlsコマンドが機能しないことです。 $ varを引用符で囲まないと、lsはスペースで区切られた文字列を複数の引数として扱います。
なぜこれが起こり、それを防ぐ方法は何ですか?
#! /bin/bash
function subdir_check(){
local var="$*"
ls -F -b "$var" | grep '/' | sed 's/\///g'
}
directory="$1"
if [[ $(subdir_check $directory) != "" ]]
then
pick=$(subdir_check $directory | rofi -dmenu -p 'Select Subdirectory')
directory="${directory}/${pick}"
while [[ $(subdir_check $directory) != "" ]]
do
pick=$(subdir_check $directory | rofi -dmenu -p 'Select Subdirectory')
directory="${directory}/${pick}"
done
fi
echo $directory
答え1
これには2つの問題があります。最初は引用です。このような習慣を育てなければなりません。いつも変数を参照してください。これについて詳しくは、次をご覧ください。
しかし、これが実際にスクリプトを破損するわけではありません。次の問題は、解析を試みたときに発生しますls
。これが悪い考えである理由は、次を参照してください。
特にここでの問題は、これを使用すると、名前でマークされた-b
ディレクトリが発生することです。メニューセレクタで選択すると、引数として実行されます。これは引用されており(関数内で引用されている)、リテラルで実行しようとしているため、エスケープされたスペースは引用されているため、エスケープされたものとは読み取られません。ただし、引用しないと、2つの別々のパラメータとして扱われます。だから、すべてが少し混乱しています。dir one
dir\ one
subdir_check
dir\ one
var
ls
dir\ one
以下は、いくつかの修正を加えた基本的なアプローチを使用するスクリプトの作業バージョンです。
#! /bin/bash
function subdir_check(){
## globs that don't match anything should expand to the empty string
## instead of expanding to the glob itself as happens by default
shopt -s nullglob
## save all sub directories in the 'dirs' array
local dirs=("$@"/*/);
## Print each dir on its own line and remove the trailing '/'.
printf '%s\n' "${dirs[@]}" | sed 's|/$||'
}
## Remove the trailing '/' from the input.
directory=$(sed 's|/$||'<<<"$1")
## Quote all the things!
if [[ $(subdir_check "$directory") != "" ]]
then
## You don't need a second variable. Just one: directory. This will now
## include the path.
directory=$(subdir_check "$directory" | rofi -dmenu -p 'Select Subdirectory')
while [[ $(subdir_check "$directory") != "" ]]
do
directory=$(subdir_check "$directory" | rofi -dmenu -p 'Select Subdirectory')
done
fi
echo "$directory"