1 名前:名無しさん@お腹いっぱい。 [2009/07/01(水) 09:42:48 ] シェルスクリプトの総合スレです。 スクリプトのお勉強・自慢・腕試しなどにどうぞ。 まずは注意点、リンク、地鎮祭など(>>1-6 くらい)をご覧ください。 □お約束 ・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。 Linuxユーザは/bin/shの正体がbashなので特に注意。 FreeBSDユーザは/bin/shの正体がashなので注意。 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。 src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/ heirloom.sourceforge.net/sh.html ・csh/tcshのシェルスクリプトは推奨されません。 (理由は「csh-whynot」でググれ) ・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。 manや参考リンクを見ましょう。 aproposないしはman -kでそれらしい単語による簡単な検索もできます。 ・シェルスクリプトのことをシェルってゆーな ・シェルで使えるワイルドカード等は正規表現ではありません。 正規表現の話題はスレ違い(正規表現スレへ) □初心者へのアドバイス: ・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも RubyやPerlの方が適した仕事には素直にそちらを使いましょう。 ・知らないコマンドが出てきたらmanを引きましょう。 ・思い通りに動かないときは、まずは sh -x でトレースしましょう。 前スレ シェルスクリプト総合 その14 pc12.2ch.net/test/read.cgi/unix/1233179688/
201 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/05(水) 00:56:33 ] FreeBSDの/bin/shってボーンシェルじゃないの?もしかして
202 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/05(水) 01:33:46 ] もしかしても糞もなくボーンシェルじゃありません
203 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/05(水) 02:09:21 ] BシェルというのはBourne Shell=/bin/sh だと思ってたけど違うの? ボーンシェルでない/bin/shというのはBシェルでもなく一体なんなんですか?
204 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/05(水) 02:17:07 ] >>1 読めよ
205 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/05(水) 06:22:27 ] Bourne Shell ≠ ボーンシェル Bourne Shell = ブールネシェル
206 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/05(水) 17:46:17 ] >>201 >>203 どのバージョンからかだったかは忘れたが、 FreeBSD や NetBSD の /bin/sh は Bourne Shell ではなくその互換再実装の Almquist Shell だよ >AUTHORS > This version of sh was originally written by Kenneth Almquist.
207 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/05(水) 19:45:44 ] 386BSDはすでにashだった。
208 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 06:48:56 ] >>206 なるほど、ashはbourne shellであってはいけないのか。 en.wikipedia.org/wiki/Bourne_shell > Due to copyright issues surrounding the Bourne Shell as it was > used in historic CSRG BSD releases, Kenneth Almquist developed > a clone of the Bourne Shell
209 名前:名無しさん@お腹いっぱい。 [2009/08/06(木) 15:38:32 ] 44,555 34,567 0 143,456 1,235,004 44 0 0 55 みたいな数字の列があるのですが、これのトータルを計算したいと思ってます。 問題は数字の3桁ごとに,が入ってることなのですが、Bashスクリプトでこれを取りつつ合計を計算 する方法ってあるでしょうか? どうかよろしくお願いします。
210 名前:名無しさん@お腹いっぱい。 [2009/08/06(木) 15:54:06 ] sed -e "s/,//g" で出来ましたが、合計の計算ができません。 44555 34567 0 143456 1235004 44 0 0 55 から、全部の合計を出したいです。
211 名前:名無しさん@お腹いっぱい。 [2009/08/06(木) 15:57:01 ] sed -e "s/,//g" | xargs echo | sed -e "s/ /+/g" | bc これで出来た。
212 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 15:59:44 ] 何万行もあると破綻しそうな
213 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 16:17:27 ] >>209 #!/bin/bash n=0 while IFS=, read line do ((n += line)) done echo $n
214 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 16:25:39 ] >>213 それ、カンマの除去処理がおかしい >>209 #!/bin/bash n=0 while read line do ((n += ${line//,/})) done echo $n
215 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 17:07:33 ] { echo 0; sed -e 's/,//g' -e 's/$/+/'; echo p; } |dc
216 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 17:12:10 ] sed 's/,//g'| paste -s -d+ | bc
217 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 17:22:53 ] >>215 それだったら、 sed 's/,//g; s/$/+/; $s/$/0/' | bc の方が簡潔。
218 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 17:31:47 ] >>217 bcだと、途中改行できないから不可。 sedでさらに行末にバックスラッシュを付加してやればそれでも動くかな。 >>215 echoとsedと一緒に使うと無駄。 sed '1s/^/0 /; s/,//g; s/$/+/; $s/$/p/' | dc でいいだろ。
219 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 17:34:20 ] >>217 実行してから因縁つけろ。カス sed 's/,//g; s/$/+/; $s/$/0/' file| bc (standard_in) 2: syntax error (standard_in) 3: syntax error (standard_in) 4: syntax error (standard_in) 5: syntax error (standard_in) 6: syntax error (standard_in) 7: syntax error (standard_in) 8: syntax error (standard_in) 9: syntax error
220 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 17:42:32 ] みなさん、質問を良く読みましょうね。 >>209 さんは、 > Bashスクリプトで って言ってますよ。 よって、>>214 が正解ですね。 すでに正解が出ているのに >>215 以降に何か書いてるおともだちがいますが、 Bashも使っていないし、質問の答としてはふさわしくありませんね。
221 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 17:44:22 ] Bash: not found だから>>214 は不正解だな。
222 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/06(木) 17:58:51 ] >>221 そういうことしか言えないようだから >>214 が正解だな
223 名前:名無しさん@お腹いっぱい。 [2009/08/06(木) 23:36:58 ] >>218 それで処理すると、 dc: stack empty dc: stack empty dc: stack empty と出ます。
224 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/07(金) 07:05:39 ] >>223 スペースも含めてちゃんとコピペしろ。
225 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/10(月) 15:20:35 ] シェルスクリプトって、ほんとツンデレだよな。 理解するまで四苦八苦ツンツンしてるくせに、一旦わかってしまうと、とたんにデレデレ。
226 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/10(月) 16:25:01 ] 別にそれはシェルスクリプトに限ったことでもなかろう
227 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/11(火) 18:17:01 ] しばらく使わないと忘れちゃってまたツン期に入るのが…
228 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/11(火) 23:15:11 ] bashで変数の置換と切り出しとかを一緒にできないですかね? echo ${HOGE//a/A} echo ${HOGE:0:8} これをひとつにしたい感じです
229 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/12(水) 00:02:16 ] もちろん、できません
230 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/15(土) 15:52:19 ] bash です。 date | read HOGE これやっても変数 HOGE が空なんだけど、どうして?
231 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/15(土) 15:55:14 ] readはサブシェルで実行されて瞬殺で終了するから。
232 名前:230 mailto:sage [2009/08/15(土) 16:05:15 ] >>231 即答サンクス! そうだった、パイプラインはそれぞれサブシェルで動くんだった。 つーことは、date 出力を変数に入れるには、素直に HOGE=`date` でよい、と。
233 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/15(土) 16:57:18 ] >>232 × パイプラインはそれぞれサブシェルで動く ○ 1個以上のパイプを含んだパイプラインはそれぞれサブシェルで動く 普通のコマンド1個だけでも「パイプライン」なので。
234 名前:232 mailto:sage [2009/08/15(土) 17:37:04 ] >>233 訂正サンクス! 確かに。 サブシェルと「環境」について、いまいち理解できない…
235 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/15(土) 17:47:10 ] バッドノウハウよりもっと有用な事を覚えよう
236 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/15(土) 20:09:24 ] バッドノウハウを覚えることは有益 バッドノウハウをあれこれ考えることは無益
237 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/15(土) 20:50:30 ] バッドノウハウって、具体的に何のこと言ってるの?
238 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/15(土) 20:55:52 ] 定義にこだわるふりをして、干されている現実から目をそらす>>233 の手法。
239 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 06:30:05 ] la -Alでファイルサイズとファイル名のみほしいので la -Al | cut -d " " -f 5,9 とかやるとうまくいきません。どうすればいいですか?
240 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 06:43:43 ] >>239 cutでうまういかないのは、複数のスペースがすべて「区切り」とみなされるから。 awk使った方がいい ↓ ls -Al | awk '{print $5 " " $9}'
241 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 07:29:22 ] >>240 awkはシェルにあらず。 シェルスレなんだからシェルでやれ ls -lA | while read line; do set -- $line; echo $5 $9; done
242 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 08:51:13 ] >>239 >>240 あざーす もうひとつ聞きたいのですが 文字列の先頭の1文字目のみ切り出す ってどうやればいいでしょうか? val1=abc val1=`expr "$val1" : "\(.\).*"` とかでいいですか?
243 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 09:38:43 ] >>242 bashなら、 var=abc echo "${var:0:1}"
244 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 12:23:11 ] >>243 あざーす
245 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 17:19:44 ] >>241 > awkはシェルにあらず。 > シェルスレなんだからシェルでやれ 濡れた。 アッーーーー
246 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 21:32:10 ] 便乗質問。 >>241 の手法に感心したんだけど、わざわざ set で位置パラメータを再設定して 使うっていう方法は、普通にアリなの? set はシェル動作制御用コマンドの側面が強くないですか? そうでもない?
247 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 21:51:50 ] >>246 set使わずに、 ↓でもいいんだけどね ls -lA | while read x x x x s x x x f x; do echo $s $f; done
248 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/17(月) 23:25:45 ] (純正シェルで)使える機能は何でも使うのがシェルプログラミングの作法。
249 名前:246 mailto:sage [2009/08/17(月) 23:51:47 ] >>247 これはすげえ! 強引!w >>248 そうかあ。使えるものは使う、と。自分専用ツールならなおさらだね。 ううむ、シェルは深いなあ。でも楽しい。 覚えると明らかに生産性が上がる。
250 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/18(火) 00:57:44 ] >>247 すげえ・・・目から鱗・・・
251 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/18(火) 11:43:54 ] >>247 はわりとよく見かけると思うが……。 >>241 の方法は元々の$@が破壊されるのでよほどのことがないかぎりやらない。
252 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/18(火) 11:51:59 ] >>251 >>241 の方法を使っても、readのパイプがサブシェルだから、 それを抜けたら $@ は破壊されていない。
253 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/20(木) 01:48:49 ] echo に渡すのがスマートでないですか? ls -Al | xargs -l echo | cut -d" " -f5,9
254 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/20(木) 01:51:38 ] というか ls -Al | xargs -l | cut -d" " -f5,9 これでよかった・・・・
255 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/20(木) 16:46:23 ] で、改行、空白を含むファイル名を正しく扱えるのはどの回答?
256 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/20(木) 16:52:37 ] >>255 ls 使ってる時点で改行、空白を含むファイル名は最初から考えられてない。
257 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/20(木) 21:13:57 ] コマンドなしのxargsってどういう意味?
258 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/20(木) 21:16:00 ] >>257 2個以上のスペースを1個だけにするもの。 >>240 も参照。
259 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/20(木) 21:26:14 ] echoの省略形
260 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/20(木) 21:32:38 ] >>259 それは知ってるよ(>>253 )。そのechoが何の意味があるかの質問だろ。
261 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/21(金) 09:59:17 ] だから2個以上のスペースを1個にするんだって。
262 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/21(金) 10:10:39 ] そもそも human readableな ls の output を filtering するというのが bad design なんんだよな。 次期 ls には是非、 --format='%f %s' 的な optionを appendしていただくことを wishする。
263 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/21(金) 10:14:50 ] stat(1)あたりをposixに入れる方が早くないか?
264 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/21(金) 12:51:07 ] >>262 英語使って、かっこつけているつもり?
265 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/21(金) 16:40:18 ] ルー語はカッコよかったんか
266 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/22(土) 11:36:50 ] csh の存在価値はなんだろう。 bash でいいじゃん。
267 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/22(土) 12:07:49 ] それはこっちで ↓ C shell 撲滅委員会 pc12.2ch.net/test/read.cgi/unix/1094041299/
268 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/22(土) 18:50:28 ] bashが無駄に重くなっていってくれたおかげで tcshは無難に使えるログインシェルという位置を確保できたw そしていろいろと便利な設定をするためにcshスクリプトの書き方を知る必要がある。
269 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/22(土) 19:37:03 ] ksh93を使ってる俺は勝ち組
270 名前:名無しさん@お腹いっぱい。 [2009/08/25(火) 17:34:40 ] 質問です 1 12 123 1 2 23 のようなテキストを xx1xx12x123 xx1xxx2xx23 (x=空白) のように幅を揃えるにはどうすればいいですか?
271 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/25(火) 17:44:42 ] awk '{printf("%3d%3d%4d\n",$1,$2,$3);}' < test.txt
272 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/25(火) 17:50:50 ] >>271 勝手に桁数決め打ちしていいのか? 同じカラム上にある最大桁数をサーチした上で %*d (*は数字)に しなければならないという質問だと思うが。
273 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/25(火) 17:57:58 ] それは質問者が言うべきこと。
274 名前:270 mailto:sage [2009/08/25(火) 18:09:22 ] すいません。実際の数字は一行に数千あって行も数千あります。 でも一つの区切りの中の数字は三桁までです。
275 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/25(火) 18:15:40 ] 絵に描いたような後出しw
276 名前:ruby,perl等のほうが早いかも mailto:sage [2009/08/25(火) 19:34:46 ] >>274 一行にある数字の数は固定している?それとも変動もある?
277 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/25(火) 21:29:45 ] >>270 >>274 #!/bin/sh while read line do set $line while [ $# -ge 1 ] do printf '%3d ' $1 shift done echo done
278 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/25(火) 21:30:54 ] >>276 固定してます。
279 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/25(火) 21:36:54 ] >>277 だったら forの方がいい。 #!/bin/sh while read line do for n in $line do printf '%3d ' $n done echo done >>278 直前の回答読めよ。
280 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/25(火) 21:44:07 ] すいませんリロードしてませんでした。 上手く行きそうです。みなさんありがとうございました。
281 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/26(水) 00:47:55 ] >>279 | sed 's/ $//'したいな
282 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/26(水) 06:48:36 ] >>279 いや、行末のスペースを取ることを考えると、 >>277 の方式の方がいいんだよ。 #!/bin/sh while read line; do set -- $line while [ $# -ge 2 ]; do printf '%3d ' $1 shift done if [ $# -eq 1 ]; then printf '%3d' $1 fi echo done
283 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 11:50:33 ] execute.shellを実行し、psコマンドを実行すると以下のように表示されます。 PID TTY TIME CMD 13219 pts/1 00:00:00 bash 17938 pts/1 00:00:30 java 17222 pts/1 00:00:37 java 25353 pts/1 00:00:00 ps CMDのjavaがexecute.shellのプロセス名みたいなんですが、 これをexcecuteと表示させることは可能ですか?
284 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 12:28:06 ] >>283 コマンド自身がargv[0]を書き換えてるか、 またはexecute.shellは単なる起動スクリプトで、実際にjavaがexecされてるから、 元のコマンドのexcecuteを表示させることは無理。
285 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 12:39:26 ] コマンドライン引数にかけらが有るかもしれない。 ps -a
286 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 13:59:26 ] >>284 了解です。レスありがとうございます。 >>285 ありがとうございます。 ps -aしてみましたが表示は変わらなかったです。 2重起動を防止するため、プロセス名を取得しようとしていたのですが無理のようなのであきらめました。 PID番号付きのファイルを作成することにしました。ファイルはなるべく作りたくなかったのですが。
287 名前:名無しさん@お腹いっぱい。 [2009/08/27(木) 17:29:53 ] sedコマンドをつかって aaa|abc|bef|efg||||aa の文字列(|は区切り文字)の一番最後のフィールドのaaの部分をbcdに変えて aaa|abc|bef|efg||||bcd と出力させるにはどのようにすればよいのでしょうか?
288 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 17:48:38 ] 最後はどれもbcdに変えるのか、aaになってるものだけ変えるのか
289 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 17:54:37 ] >>287 sed指定の質問ならsedスレへ ↓ sed pc12.2ch.net/test/read.cgi/unix/1085730992/
290 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 17:57:51 ] >>287 sed 's/|[^|]*$/bcd/'
291 名前:名無しさん@お腹いっぱい。 [2009/08/27(木) 17:58:17 ] sygwinでのbashなんですが declare -a userhome userhome=($(cut -d":" -f6 /etc/passwd)) とすると、/etc/passwdの6番目の要素がnullの場合 配列に何も代入されません。 何か文字を代入したい場合はどうすればいいんでしょうか?
292 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 18:04:24 ] >>291 userhome=($(cut -d":" -f6 /etc/passwd | sed 's/^$/none/'))
293 名前:名無しさん@お腹いっぱい。 [2009/08/27(木) 18:10:41 ] >>290 ありがとうございます
294 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 18:15:40 ] #!/bin/sh s="~/work/" ls $s としても、 No such file or directoryと言われます。 たぶん~が展開されていないと思うのですが、 どうすれば展開できますか?
295 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 18:26:29 ] >>294 eval ls $s または、最初から s=?/work/ で代入。(ダブルクォートなし)
296 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 18:37:12 ] >>288 > 最後はどれもbcdに変えるのか、aaになってるものだけ変えるのか ↑ そんなの質問の意図を読めばわかる。 >>290 みたいに回答した方が早い。
297 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 18:48:08 ] >>290 sed 's/|[^|]*$/|bcd/' だろw >>293 ありがたいか?w
298 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 19:10:28 ] >>294 由緒正しきshは~は使えない。$HOME使え。
299 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 19:28:05 ] トホホの自民 生き残れるのはひと握り 大マスコミの選挙予測によると、自民党は壊滅状態で、当確を数えたほうが早いほど。 小選挙区で確実に生き残れるのは元・現閣僚が7人ほど、石原伸晃など地盤が強固な世襲議員が6人ほど、重鎮が3人。 ほかに5人程度のひと握り。自民党が少数政党に転落し、永田町の勢力図が一変する可能性だってある。 gendai.net/?m=view&c=010&no=22639
300 名前:名無しさん@お腹いっぱい。 mailto:sage [2009/08/27(木) 21:04:45 ] 便乗質問だけど、 >>298 チルダ展開は bash だけなの? sh は展開してくれない?