私が見つけたこの便利なbash機能しばらく前のブランチを選択して確認するために使用されました。それは魅力のように動作します。主な内容は次のとおりです。
BRANCHES=(
$(
git reflog |
egrep -io "moving from ([^[:space:]]+)" |
awk '{ print $3 }' | # extract 3rd column
awk ' !x[$0]++' | # Removes duplicates. See http://stackoverflow.com/questions/11532157
egrep -v '^[a-f0-9]{40}$' | # remove hash results
while read line; do # verify existence
([[ $CHECK_EXISTENCE = '0' ]] || git rev-parse --verify "$line" &>/dev/null) && echo "$line"
done |
head -n "$NUM"
)
)
if [[ $INTERACTIVE = '1' ]]; then
PS3="Choose a branch: "
select d in "${BRANCHES[@]}"; do
test -n "$d" && break
echo ">>> Invalid Selection"
done
git checkout "$d"
else
printf '%s\n' "${BRANCHES[@]}"
fi
私たちの支店名はすべてbug/...
または形式ですtask/...
。
何らかの理由で今日から失敗し始めました。set -x
。を使用してデバッグすると、参照されていないコンテンツが評価され削除されることecho ${BRANCHES[@]}
がわかりました。select
/
問題を単純化/確認するために、以下を実行しました。
foo=( "a/b" "c/d" )
echo $foo
# prints a b
echo ${foo[@]}
# prints a b c d
echo "${foo[@]}"
# prints a/b c/d
予想していたのですが、この問題は私のエイリアス/関数に大きなダメージを与えました。
奇妙なことは、スクリプトの関数が次のように印刷されることです。
1) master
task
2) 16658-...
task
3) 16525-...
Choose a branch:
foo
期待どおりに印刷作品から選択:
select f in "${foo[@]}"; do
echo $f
break
done
# prompts:
# 1) a/b
# 2) c/d
したがって、根本的な原因については間違っているかもしれませんが、疑わしいです。1
上記のプロンプトでエコーを選択しますa b
。
実際に...
foo=a/b
echo $foo
# prints a b
echo "$foo"
# prints a/b
foo="a/b"
echo $foo
# prints a/b
重要なのは、Unix bashではなくWindowsでgit-bashを使用していますが、それが問題だとは想像できません。
どんなアイデアがありますか?
答え1
引用符のないコンテンツをエコーすると、スプリット+グローブ(split+glob)という内容が適用されます。つまり、エコーする内容は変数のすべての文字に分割され、globとして扱われ、IFS
一致するものがあればglobが拡張されます。ここで注目する部分は分割です。説明する内容は、デフォルト値(スペース、タブ、および改行)を使用してもIFS
発生しません。この動作が表示された場合は、ユーザー(またはシェルセッションのエントリ)がIFS
次を表示するように設定されています/
。
$ foo=( "a/b" "c/d" )
$ echo ${foo[@]}
a/b c/d
## Now, change IFS
$ IFS='/'
$ echo ${foo[@]}
a b c d
## Of course, properly quoting fixes it
$ echo "${foo[@]}"
a/b c/d
## And so does un-setting IFS
$ unset IFS
$ echo ${foo[@]}
a/b c/d
これが常に変数を引用しなければならない理由の1つにすぎません。詳細については、次を参照してください。bash / POSIXシェルで変数を引用することを忘れてしまうセキュリティリスクそしてスペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?。
これは、元のスクリプトが失敗した理由ではなく、例が失敗した理由を示しています。私が知る限り、原文のすべての内容は正確に引用されました。