わかりました-bash: cd ..: command not found
。
指定されたディレクトリを繰り返すスクリプトを作成しました。いつも効果がありましたが、今は何が変わったのかわかりません。
$ type up
up is a function
up ()
{
local arg="$@";
if [ -z "$arg" ]; then
cd ..;
return 1;
fi;
local arr=();
local sep='/';
local IFS="$sep";
local DIRS;
read -ra DIRS <<< "$(pwd)";
for ((i=${#DIRS[@]}-1; i>=0; i-- ))
do
if [ "${DIRS[i]}" = "$arg" ]; then
local first=${arr[0]};
arr=("${arr[@]:1}");
$(printf "%s" "cd $first" "${arr[@]/#/$sep}" && echo "/");
return 1;
else
arr+=('..');
fi;
done;
echo "Directory \"$arg\" could not be found in path. Check spelling and try again." 1>&2;
return 0
}
スピード
- パラメータが渡されない場合は、以前のディレクトリに移動します。
- パラメータが渡される場合:
つかんで
pwd
分離/
キューの後ろから来るディレクトリのリストを繰り返します。
現在のディレクトリがパラメータと一致しない場合は、
..
リストに追加してください。dirがコマンドラインargと一致する場合は、区切り文字を
..
解凍し、/
文字列をコマンドとして実行します。printf "%s" "cd $first" "${arr[@]/#/$sep}" && echo "/" # printf "%s" "cd $first" : prints 'cd ..' (command & the first placeholder) # "${arr[@]/#/$sep}" : prints the remaining '..' joined by '/' # echo "/" : adds a trailing '/' to the relative path # which could have been included in the # previous step but separated for comprehension # Given, pwd = /Users/dev/workspace/project/foo # `up workspace` navigates to 'cd ../../'
デバッグ(ターミナルから)
> cd ..
# works as expected
> $(echo "cd ..")
# works as expected --> maybe something with the "/" is breaking it?
> $('cd ..')
# -bash: cd ..: command not found
> $('cd ../')
# -bash: cd ../: No such file or directory
> which cd
# /usr/bin/cd
> echo $PATH
# /usr/bin
> type cd
# cd is a shell builtin
> alias cd
# -bash: alias: cd: not found
> shopt expand_aliases
# expand_aliases on
OSXのbash3.2では、ほとんどの環境変数(CDPATHなど)の設定を解除したり、クリーンな環境(たとえば)でシェルを開くことはenv -i bash --noprofile --norc
役に立ちません。
コメント
私のbashは少し錆びたので、それを維持するためのより良い方法を自由に指摘してください。私はそれがおそらく必要ないか正確ではないことを知っており、より効率的であるかもしれませんが、従うのがより難しいreturn
いくつかの実装を見ました。find
答え1
$(echo "cd ..")
シェルコマンドecho "cd .."
(たとえば、echo
単一の引数を持つコマンドcd ..
)を実行し、出力(cd ..
)を取得し、その出力を空白(およびワイルドカード、ここでは重要ではありません)に分割し、2つの単語の合計を取得して引数を使用しcd
ます..
。これは、シェルコマンドを実行する複雑でエラーが発生しやすい方法です。cd
..
cd ..
とは別にここでスラッシュを設定すると、IFS
単語が部分に分割されます。空白で区切るのではなく、スラッシュで分けてください。。
したがって、たとえばを実行すると、コマンド$(echo "cd ../..")
置換の結果はに分割されずに分割されます。ここにあるスペースは、シェルのコマンドラインに入力するのと同じように、コマンド名の一部になります。cd
../..
cd ..
..
"cd .." ..
単語の区切りに依存せず(特にディレクトリ名にスペースが含まれている場合は区切ります)、コマンドと引数を区切ることをお勧めします。変数にディレクトリ名を作成して使用します。例:
dir=$(printf "../..")
cd -- "$dir"
またはより正確には
printf -v dir "../.."
cd -- "$dir"
また、おそらくそこにいる必要はありませんprintf
。を使用する"${arr[*]}"
と、 の最初の文字に関連付けられた配列要素を取得できるため、 をIFS
使用するとIFS=/
スラッシュで連結されます。
たとえば、
arr=(.. .. ..)
IFS=/
dir="${arr[*]}"
dir
に設定../../..
。