予期しない動作が発生しましたbash
。これは私の入力/出力です。
nepumuk@pc:~$ type URL
URL is a function
URL ()
{
echo -e "${_//%/\\x}"
}
nepumuk@pc:~$ URL %2f
URL
nepumuk@pc:~$ URL %2f
/
nepumuk@pc:~$ URL %2F
/
nepumuk@pc:~$ type URL
URL is a function
URL ()
{
echo -e "${_//%/\\x}"
}
nepumuk@pc:~$ URL %2f
URL
nepumuk@pc:~$ URL %2f
/
nepumuk@pc:~$ URL %2f
/
nepumuk@pc:~$ URL %2f
/
nepumuk@pc:~$ URL %2f
/
nepumuk@pc:~$ URL %2f
/
Bash関数ファイルの対応する部分は次のとおりです。
url() {
: "${*//+/ }"
echo -e "${_//%/\\x}"
}
export -f url
URL() {
echo -e "${_//%/\\x}"
}
export -f URL
URL
テスト中に変更があることを確認するために項目を変更しましたecho -e "${@//%/\\x}"
。新しい端末(エミュレータ?)ウィンドウを開き、後者を使用すると
nepumuk@pc:~$ URL %2f
/usr/share/bash-completion/bash_completion
nepumuk@pc:~$ URL %2f
/
nepumuk@pc:~$ URL %2f
/
正確に再現できますが(そして希望の出力を提供するので前者を使用する)、説明をいただければ幸いです。
答え1
以前に実行したコマンドの最後の引数に変数bash
を展開します($_
他のものの間)。
url() { : "${*//+/ }" echo -e "${_//%/\\x}" }
拡張が最初にno-opコマンド${*//+/ }
に任意の引数として渡されるため、意味があります。:
これは+
、位置引数のsを空白に置き換え、結果の文字列を間の最初の文字に関連付けることです($IFS
引用時の一般的な効果)。$*
次に、2番目のコマンドは結果文字列を取得して%
sに置き換え、\x
結果をに渡しますecho
。
とオプションがすべて有効になっていないbash
場合は、一部のエスケープシーケンスを拡張するために使用できるオプションのサポートが組み込まれています。したがって、対応するバイト値に置き換えられ、実際にURI%XXデコードが行われます。posix
xpg_echo
echo
-e
\xHH
%HH
:
最初のコマンドを削除すると、2番目のコマンドには、$_
関数を呼び出す前に実行されるコマンドに渡された最後の引数が含まれます。
ここで関数を書いた人は、一時的な変数の使用を避けるためにこのトリックを使用したようです$_
。しかし、これはコードが不必要に複雑になり、読みやすく理解しにくくなります。
uri_decode() {
local IFS=' ' # make sure arguments are joined with spaces rather than
# make some assumption on what $IFS may currently contain
local tmp="$*" # positional parameters joined with spaces
tmp=${tmp//+/ } # replace +s with spaces
tmp=${tmp//[%]/\\x} # replace % with \\x. Using [%] instead of % for
# increased portability.
printf '%b\n' "$tmp" # pass the result to printf for expanding of the \x
# sequences, avoiding echo whose behaviour depends on
# the environment, and would give incorrect results
# for strings like -Enee
}
+ - >空白変換を行わない変形が必要な場合は、そのtmp=${tmp//+/ }
部分を削除してください。