Bashでは、エコリストは「/」を削除します。

Bashでは、エコリストは「/」を削除します。

私が見つけたこの便利な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シェルで変数を引用することを忘れてしまうセキュリティリスクそしてスペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?

これは、元のスクリプトが失敗した理由ではなく、例が失敗した理由を示しています。私が知る限り、原文のすべての内容は正確に引用されました。

関連情報