.bashrc
ファイルにfunction
があります。私はそれが何をしているのか知っています、それはcd
でX個のディレクトリをステップアップします
ここにあります:
up()
{
local d=""
limit=$1
for ((i=1 ; i <= limit ; i++))
do
d=$d/..
done
d=$(echo $d | sed 's/^\///')
if [ -z "$d" ]; then
d=..
fi
cd $d
}
しかし、これらの3つのことを私に説明できますか?
d=$d/..
sed 's/^\///'
d=..
なぜこのようにしないのですか?
up()
{
limit=$1
for ((i=1 ; i <= limit ; i++))
do
cd ..
done
}
使用法:
<<<>>>~$ up 3
<<<>>>/$
d=$d/..
は、_d
変数の現在の内容に/..
を追加します。 d
は空から始まり、最初の反復で/..
、2番目の/../..
などになります。
sed 's/^\///'
は最初の/
を削除するため、/../..
は../..
になります(これは、パラメータ拡張d=${d#/}
を使用して実行できます)。
d=..
は、その条件のコンテキストでのみ意味があります。
if [ -z "$d" ]; then
d=..
fi
これにより、この時点でd
が空の場合は、親ディレクトリに移動します。 (引数なしのup
はcd ..
と同等です。)
このアプローチは、cd ..
を保持するため、反復的なcd -
よりも優れています。これは、1ステップで(ユーザーの観点から)前のディレクトリに戻る機能です。
関数は簡略化できます:
up() {
local d=..
for ((i = 1; i < ${1:-1}; i++)); do d=$d/..; done
cd $d
}
これは、少なくとも1レベル上に移動することを想定し、n-1レベルを追加するため、先頭の/
を削除したり、チェックしたりする必要はありません。空の$d
の場合。
Athena jot
(Debianのathena-jot
パッケージ)の使用:
up() { cd $(jot -b .. -s / "${1:-1}"); }
( gleant jackman によって提案された variant に基づいています)。
しかし、これらの3つのことを私に説明してくれませんか?
d = $ d/..
これは、var d
の現在の内容を/..
と連結し、それをd
に割り当てます。
最終結果は、d
を/../../../..
のような繰り返し文字列にすることです。
sed 's/^ ///'
投稿したコードの指定された文字列d
(echo $ d)から先頭の/
を削除します。
おそらくバックスラッシュを避けるためにsed 's|^/||'
と書く方が良いでしょう。
代替(より速く、より簡単)はd=${d#/}
を書くことです。
d = ..
文字列..
を変数d
に割り当てます。
これは、テスト..
が変数d
が空であることを通知する場合に、d
に少なくともoneif [ -z "$d" ]; then
があることを確認する方法としてのみ意味があります。これは、sedコマンドがd
から1文字を削除しているためにのみ発生します。
dから文字を削除する必要がない場合、sed
またはif
は必要ありません。
あなたの質問のコードは常に少なくとも1つのディレクトリ上に移動します。
local d
は、変数が空であることを確認するのに十分であり、他には何も必要ありません。
ただし、localはbashやdashなどの一部のシェルでのみ機能します。具体的には、ksh
(yash
として)にはlocal
コマンドがありません。よりポータブルなソリューションは次のとおりです。
[ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
for((
構文は移植できません。次のようなものを使用するほうがよい:
while [ "$((i+=1))" -lt "$limit" ]; do
壮健。
関数の最初の引数に与えられた値が負またはテキストである可能性がある場合、関数はそれらの値を処理するために堅牢でなければなりません。
最初に、値を数値のみに制限します(c
にはcount
を使用します):
c=${1%%[!0-9]*}
そして、カウント値を正の値のみに制限します。
let "c = (c>0)?c:0"
この関数は快く0または任意のテキスト(エラーなし)を受け入れます。
up()
{
[ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
c=${1%%[!0-9]*}
c=$(((c>0)?c:0))
while [ "$((i+=1))" -le "$c" ]; do d="$d../"; done
echo \
cd "${d%/}" # Removing the trailing / is not really needed for cd
# but it is Nice to know it could be done cleanly.
}
up 2
up 0
up asdf
関数をテストしたら、echo \
を削除します。