D0375.quote-in-param-expansion.sh (8755B)
1 #!/bin/bash 2 3 ## 結論: ${var#text} の text を quote する場合、 4 ## 1. 解析時に shopt -u extquote で、 5 ## 2. ${} 全体が "" で囲まれていて、 6 ## 2. $'' の形式の quote の時にうまくいかない。 7 ## それ以外の場合には期待通りに quote 除去が行われる。 8 9 shopt -s extquote 10 function check_ltrim_extquote { 11 echo check_ltrim_extquote 12 local hello=check:hello 13 [[ "${hello#'check'}" == ':hello' ]] || echo Error 14 [[ "${hello#$'check'}" == ':hello' ]] || echo Error 15 [[ "${hello#"check"}" == ':hello' ]] || echo Error 16 [[ ${hello#'check'} == ':hello' ]] || echo Error 17 [[ ${hello#$'check'} == ':hello' ]] || echo Error 18 [[ ${hello#"check"} == ':hello' ]] || echo Error 19 20 [[ $(echo "${hello#'check'}" ) == ':hello' ]] || echo Error 21 [[ $(echo "${hello#$'check'}") == ':hello' ]] || echo Error 22 [[ $(echo "${hello#"check"}" ) == ':hello' ]] || echo Error 23 [[ $(echo ${hello#'check'} ) == ':hello' ]] || echo Error 24 [[ $(echo ${hello#$'check'} ) == ':hello' ]] || echo Error 25 [[ $(echo ${hello#"check"} ) == ':hello' ]] || echo Error 26 } 27 check_ltrim_extquote 28 29 shopt -u extquote 30 function check_ltrim_noextquote { 31 echo check_ltrim_extquote 32 local hello=check:hello 33 [[ "${hello#'check'}" == ':hello' ]] || echo Error1 34 [[ "${hello#$'check'}" != ':hello' ]] || echo Error2 # これだけ違う 35 [[ "${hello#"check"}" == ':hello' ]] || echo Error3 36 [[ ${hello#'check'} == ':hello' ]] || echo Error4 37 [[ ${hello#$'check'} == ':hello' ]] || echo Error5 38 [[ ${hello#"check"} == ':hello' ]] || echo Error6 39 40 [[ $(echo "${hello#'check'}" ) == ':hello' ]] || echo Error1 41 [[ $(echo "${hello#$'check'}") != ':hello' ]] || echo Error2 42 [[ $(echo "${hello#"check"}" ) == ':hello' ]] || echo Error3 43 [[ $(echo ${hello#'check'} ) == ':hello' ]] || echo Error4 44 [[ $(echo ${hello#$'check'} ) == ':hello' ]] || echo Error5 45 [[ $(echo ${hello#"check"} ) == ':hello' ]] || echo Error6 46 } 47 check_ltrim_noextquote 48 49 ## 結論: ${var:offset} の offset を quote する場合、 50 ## 1. shopt -s extquote が設定されていて (解析時・実行時の両時点で) (1/2)、 51 ## 2. ${} 全体が "" で囲まれていて (1/2)、 52 ## 3. offset の quote が $'' である (1/3) 53 ## 場合にのみ認められる。それ以外 (2*2*3-1 = 11 パターン) は構文エラーになる。 54 shopt -s extquote 55 function check_quoted_offset_extquote { 56 local digits=0123456789 57 echo 'check_quoted_offset_extquote' 58 # echo "${digits:'1'}" # error 59 echo "${digits:$'1'}" 60 # echo "${digits:"1"}" # error 61 # echo ${digits:'1'} # error 62 # echo ${digits:$'1'} # error 63 # echo ${digits:"1"} # error 64 } 65 check_quoted_offset_extquote 66 67 shopt -u extquote 68 function check_quoted_offset_noextquote { 69 local digits=0123456789 70 echo 'check_quoted_offset_noextquote' 71 # echo "${digits:'1'}" # error 72 # echo "${digits:$'1'}" # error 73 # echo "${digits:"1"}" # error 74 # echo ${digits:'1'} # error 75 # echo ${digits:$'1'} # error 76 # echo ${digits:"1"} # error 77 } 78 check_quoted_offset_noextquote 79 80 ## 結論: ${var#text} の場合と同じパターンである。 81 ## 但し算術式が構文エラーになり実行が停止する。 82 shopt -s extquote 83 function check_quoted_sub_extquote { 84 local -a digits=({0..9}) 85 echo 'check_quoted_sub_extquote' 86 [[ "${digits['1']}" == 1 ]] || echo Error1 87 [[ "${digits[$'1']}" == 1 ]] || echo Error2 88 [[ "${digits["1"]}" == 1 ]] || echo Error3 89 [[ ${digits['1']} == 1 ]] || echo Error4 90 [[ ${digits[$'1']} == 1 ]] || echo Error5 91 [[ ${digits["1"]} == 1 ]] || echo Error6 92 } 93 check_quoted_sub_extquote 94 95 shopt -u extquote 96 function check_quoted_sub_noextquote { 97 local -a digits=({0..9}) 98 echo 'check_quoted_sub_noextquote' 99 [[ "${digits['1']}" == 1 ]] || echo Error1 100 # [[ "${digits[$'1']}" != 1 ]] || echo Error2 # 構文エラー 101 [[ "${digits["1"]}" == 1 ]] || echo Error3 102 [[ ${digits['1']} == 1 ]] || echo Error4 103 [[ ${digits[$'1']} == 1 ]] || echo Error5 104 [[ ${digits["1"]} == 1 ]] || echo Error6 105 # echo "${digits:'1'}" # error 106 # echo "${digits:$'1'}" # error 107 # echo "${digits:"1"}" # error 108 # echo ${digits:'1'} # error 109 # echo ${digits:$'1'} # error 110 # echo ${digits:"1"} # error 111 } 112 check_quoted_sub_noextquote 113 114 ## ここでまでのまとめ 115 ## 116 ## shopt -u extquote の時 117 ## 118 ## 1. ${var#a}, ${var[a]} の形式では基本的に a に quote が含まれて良い。 119 ## 但し、全体が "" で囲まれている場合は $''/$"" の quote は除去されない。 120 ## 特に ${var[a]} では算術式の構文エラーになる。 121 ## 2. ${var:offset} の形式では基本的に offset に quote を含めると 122 ## 算術式の構文エラーになる。 123 ## 124 ## shopt -s extquote の時は 125 ## 126 ## 全体が "" で囲まれている場合に $''/$"" が除去される様になる。 127 ## 128 ## 129 ## 以降は二重に ${} が入れ子になっている場合に "${ ${} }" 130 ## と ${} のどちらと同じ振る舞いになるかについてである。 131 132 133 # (1) "${ :- ${var#text} }" について → "${var#text}" と同じ 134 shopt -s extquote 135 function check_qrltrim_extquote { 136 echo check_qrltrim_extquote 137 local hello=check:hello n= 138 [[ "${n:-${hello#'check'}}" == ':hello' ]] || echo Error1 139 [[ "${n:-${hello#$'check'}}" == ':hello' ]] || echo Error2 140 [[ "${n:-${hello#"check"}}" == ':hello' ]] || echo Error3 141 [[ $(echo "${n:-${hello#'check'}}" ) == ':hello' ]] || echo Error1 142 [[ $(echo "${n:-${hello#$'check'}}") == ':hello' ]] || echo Error2 143 [[ $(echo "${n:-${hello#"check"}}" ) == ':hello' ]] || echo Error3 144 } 145 check_qrltrim_extquote 146 147 shopt -u extquote 148 function check_qrltrim_noextquote { 149 echo check_qrltrim_noextquote 150 local hello=check:hello n= 151 [[ "${n:-${hello#'check'}}" == ':hello' ]] || echo Error1 152 [[ "${n:-${hello#$'check'}}" != ':hello' ]] || echo Error2 153 [[ "${n:-${hello#"check"}}" == ':hello' ]] || echo Error3 154 [[ $(echo "${n:-${hello#'check'}}" ) == ':hello' ]] || echo Error1 155 [[ $(echo "${n:-${hello#$'check'}}") != ':hello' ]] || echo Error2 156 [[ $(echo "${n:-${hello#"check"}}" ) == ':hello' ]] || echo Error3 157 } 158 check_qrltrim_noextquote 159 160 # (2) "${ :- ${var:offset} }" について → "${var:offset}" と同じ 161 shopt -s extquote 162 function check_qroffset_extquote { 163 local digits=0123456789 n= 164 echo 'check_qroffset_extquote' 165 # echo "${n:-${digits:'1'}}" # error 166 echo "${n:-${digits:$'1'}}" 167 # echo "${n:-${digits:"1"}}" # error 168 } 169 check_qroffset_extquote 170 171 shopt -u extquote 172 function check_qroffset_noextquote { 173 local digits=0123456789 n= 174 echo 'check_qroffset_noextquote' 175 # echo "${n:-${digits:'1'}}" # error 176 # echo "${n:-${digits:$'1'}}" # error 177 # echo "${n:-${digits:"1"}}" # error 178 } 179 check_qroffset_noextquote 180 181 # (3) "${ :- ${arr[index]} }" → "${arr[index]}" と同じ 182 183 shopt -s extquote 184 function check_qrsub_extquote { 185 local digits n= 186 digits=({0..9}) 187 echo 'check_qrsub_extquote' 188 [[ "${n:-${digits['1']}}" == 1 ]] || echo Error1 189 [[ "${n:-${digits[$'1']}}" == 1 ]] || echo Error2 190 [[ "${n:-${digits["1"]}}" == 1 ]] || echo Error3 191 } 192 check_qrsub_extquote 193 194 shopt -u extquote 195 function check_qrsub_noextquote { 196 local digits n= 197 digits=({0..9}) 198 echo 'check_qrsub_noextquote' 199 [[ "${n:-${digits['1']}}" == 1 ]] || echo Error1 200 # [[ "${n:-${digits[$'1']}}" != 1 ]] || echo Error2 # 構文エラー 201 [[ "${n:-${digits["1"]}}" == 1 ]] || echo Error3 202 } 203 check_qrsub_noextquote 204 205 # (4) "$(( ${var#text} ))" → なんと ("${}" ではなくて) ${} と同じ振る舞いである。 206 shopt -s extquote 207 function check_qaltrim_extquote { 208 echo check_qaltrim_extquote 209 local hello=321123 n= 210 [[ "$((${hello#'321'}))" == '123' ]] || echo Error1 211 [[ "$((${hello#$'321'}))" == '123' ]] || echo Error2 212 [[ "$((${hello#"321"}))" == '123' ]] || echo Error3 213 } 214 check_qaltrim_extquote 215 216 shopt -u extquote 217 function check_qaltrim_noextquote { 218 echo check_qaltrim_noextquote 219 local hello=321123 n= 220 [[ "$((${hello#'321'}))" == '123' ]] || echo Error1 221 [[ "$((${hello#$'321'}))" == '123' ]] || echo Error2 222 [[ "$((${hello#"321"}))" == '123' ]] || echo Error3 223 } 224 check_qaltrim_noextquote 225 226 # (1) "${var: ${var#text} }" について → "${var#text}" と同じ 227 shopt -s extquote 228 function check_qoltrim_extquote { 229 echo check_qoltrim_extquote 230 local hello=123 var=abcde 231 [[ "${var:${hello#'12'}}" == de ]] || echo Error1 232 [[ "${var:${hello#$'12'}}" == de ]] || echo Error2 233 [[ "${var:${hello#"12"}}" == de ]] || echo Error3 234 } 235 check_qoltrim_extquote 236 237 shopt -u extquote 238 function check_qoltrim_noextquote { 239 echo check_qoltrim_noextquote 240 local hello=123 var=abcde 241 [[ "${var:${hello#'12'}}" == de ]] || echo Error1 242 [[ "${var:${hello#$'12'}}" != de ]] || echo Error2 243 [[ "${var:${hello#"12"}}" == de ]] || echo Error3 244 } 245 check_qoltrim_noextquote