1 名前:シェルスクリプトライター mailto:sage [2011/12/10(土) 20:06:40.38 ] シェルスクリプトの総合スレです。 スクリプトのお勉強・自慢・腕試しなどにどうぞ。 □お約束 ・特記なき場合は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 でトレースしましょう。 前スレ シェルスクリプト総合 その18 hibari.2ch.net/test/read.cgi/unix/1308195527/ 次スレは >>970 で。
361 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/22(水) 23:40:20.00 ] >>358-360 実は自演
362 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/23(木) 00:25:07.78 ] 純正なのに bash/zsh なの?
363 名前:340 mailto:sage [2012/02/23(木) 00:58:08.13 ] 普通のファイルの意味はわかりました。 ところで /etc/rcの先頭に >stty status '^T' が有るというのは、 rcスクリプトが読まれ始めるときは、sttyの設定がされてないので rcスクリプトから実行されるプログラムの ステータス情報をキーボードから^Tと入力すれば表示できるようにするため に設定していると言う理解で良いでしょうか?
364 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/23(木) 01:22:49.78 ] $ (ba|z)sh
365 名前:名無しさん@お腹いっぱい。 [2012/02/23(木) 01:37:03.64 ] うちのsttyにはstatusって指定できないから意味自体分からんのよな。
366 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/23(木) 08:28:33.61 ] >>363 デフォルトの設定がユーザを混乱させるからなんじゃないかな。 > ステータス情報をキーボードから^Tと入力すれば表示できるようにするため 多分違う、^Tを入力するとカーネルに対して、「何か」をしろという指令が非同期に飛んでいく。 カーネルはユーザーの端末に対してメッセージを出すことはしない。 「何か」が何なのかは、statusなんて機能は使ったことないから知らない。
367 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/23(木) 10:49:16.92 ] "stty status" でググるといろいろ出てくるね。
368 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/23(木) 11:56:49.03 ] screenコマンドのstatus lineみたいな奴。 表示する方法、される内容はカーネル、端末依存。
369 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/23(木) 12:09:58.01 ] >>367 ああ、なるほど。googleでトップに来てる freebsd.g.hatena.ne.jp/minus_zero/20070903 で実験して納得した。 rcの中でハングったりした時に、すかさずC-tするとどのプロセスが刺さってるかわかるんだな。 これはいい事を憶えた。
370 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/24(金) 23:41:20.22 ] 大量のメールアドレスの一部分をマスクしたい。例えば foo.bar@example.com → foo****@example.com ドメイン部分はそのままで、先頭3文字程度残して、残りの部分はメールアドレスの文字数が変わらないように 任意の文字で埋めたい。今は下のように変数にメールアドレスを入れて処理しているけど、ちょっと不恰好 MADR=foo.bar@example.com MASK='*' RC=3 DOM="${MADR##*@}" let MC="${#MADR}"-"$RC"-"${#DOM}"-1 echo "$MADR" echo "${MADR:0:$RC}`yes "$MASK" |tr -d '\n' |head -c"$MC"`@$DOM" もう少し楽に処理できないでしょうか?
371 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 03:53:15.28 ] 素直にrubyで echo foo.bar@example.com | ruby -pe '$_.sub!(/(?<=[^@]{3})[^@]*(?=@\w+)/){|s|"*"*s.size}' perlならもっと短くできるんじゃないかなぁ。
372 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 04:08:45.24 ] >>370 sedを使うのはいかが? echo "user@example.com" | sed -e 's/\(...\).*@\(.*\)/\1...@\2/g' ユーザ名が必ず3文字以上ならこれで良いはず。 ユーザ名が2文字以下だとそのまま出力される。 (元のスクリプトでも2文字以下ならそのままっぽいが。)
373 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 05:22:15.23 ] 長さ保存してないじゃんそれ
374 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 06:52:42.61 ] >>373 あ、長さが変わらないように、か。 「長さが分からないように」と読み違えてた。すまん。
375 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 08:28:46.14 ] >>370 をもとに、おもにyes|trの部分を改良してみた。 不要なクォートや不要な変数も削除した。 ↓ MADR=foo.bar@example.com MASK=* RC=3 DOM=${MADR##*@} echo "$MADR" echo "${MADR:0:$RC}"`echo "${MADR:$RC:${#MADR}-RC-${#DOM}-1}" | sed "s/./$MASK/g"`@"$DOM"
376 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 09:18:35.26 ] つーか、見るからに遅そう。 > 大量のメールアドレスの一部分をマスクしたい。例えば 千通突っ込む気にならない。
377 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 09:27:28.61 ] awkでやってみたよ。 RC=3 MASK='*' echo "$MADR" | awk -F@ -vn="$RC" -vm="$MASK" '{t=substr($1,n+1,length($1));gsub(".",m,t);print(substr($1,1,n) t "@" $2);}'
378 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 09:37:42.09 ] 速度優先ならC言語一択だろ。 標準入力から1行ずつ複数のメールアドレスを読む仕様。 gets()使うなとか、エラーチェックなしとかの突っ込みはなしな #include <stdio.h> #define RC 3 #define MASK '*' int main() { int i; char buf[1024]; while (gets(buf) != NULL) { for (i = RC; buf[i] != '@'; i++) { buf[i] = MASK; } puts(buf); } return 0; }
379 名前:名無しさん@お腹いっぱい。 [2012/02/25(土) 11:10:48.60 ] シェルスクリプトスレでなんという暴論
380 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:17:36.53 ] 速度がそんなに重要じゃないからここで聞いてんのにな。
381 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:19:51.26 ] >>380 >>370 >大量のメールアドレスの一部分をマスクしたい。 速度が重要という質問ですが・・
382 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:20:58.69 ] だが正論。これをシェルスクリプトでというのはコスト高くないかな
383 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:21:00.66 ] 「大量」としか言ってないじゃん。 量は多いけど時間は多少かかってもかまわないんでしょ。
384 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:22:45.37 ] たとえば退社前に処理を開始して 次の日の出社までに終わってればいい、なんてケースだと 7時間が4時間に短縮されてもあんまり意味ない。
385 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:52:15.99 ] 皆さん、レスありがとう御座います 初めは>>372 のように考え、どうしても長さが保存できないので何かやり方は無いかと質問しました >>371 ,377 もっとさくっと書けるコマンドがあるかなと思っていたけど、やはりスクリプト言語使うしかないですか それにしてもrubyは短く書けるんですね。今のシステムには入れていませんが勉強になります >>375 なるほど。任意の長さの文字列を作るのにsedで置換を使う方法は思いつかなかった それを元にすると最終的にこんな感じでしょうか? MADR=foo.bar@example.com MASK=* RC=3 DOM=${MADR##*@} MINV=${MADR:$RC:${#MADR}-RC-${#DOM}-1} echo "$MADR" echo "${MADR:0:$RC}${MINV//?/*}@$DOM" これなら、外部のプログラムを呼び出さないのでそこそこ速そう ただ、bashで動くことは確認したけど、汎用性を考えるとawkを使う>>377 ? 速度についてですが、何度も変換するものではないし、 寝ている間に終わればいいなと思っていたのでシェルスクリプトで十分でした
386 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:54:23.14 ] 訂正:echo "${MADR:0:$RC}${MINV//?/*}@$DOM" → echo "${MADR:0:$RC}${MINV//?/$MASK}@$DOM"
387 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 01:55:24.94 ] Å ヽ('A`)ノ、スーパーちんぽマン参上!! / ( ) \ んヘヽヽ〜'
388 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 10:43:00.23 ] # Set shell to ignore SIGINT (signal 2), but not children; shell catches # SIGQUIT (signal 3) and returns to single user after fsck. trap : 2 trap : 3 # shouldn't be needed という一文が有るのですが、 SIGINITとSIGQUITを無視(ignore)するならば trap ' ' 2 trap ' ' 3 と言う書き方になるような気がするんですが、 :はどういう意味が有るのでしょうか?
389 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 10:55:51.64 ] >>388 trap '' 2 は、 親(シェル自身)も子プロセス(外部コマンド)もSIGINTを無視する。 trap : 2 は、 親(シェル自身)はSIGINTを無視するが、子プロセス(外部コマンド)はデフォルト動作に戻 る。 あと、' ' じゃなくて '' (空文字列)な。
390 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 11:23:35.81 ] 半二重なら trap : 2、全二重なら trap : 2と trap : 3が要るんじゃねーのー
391 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 22:34:59.64 ] >>389 >>390 :ってヌルコマンドって奴ですか? そうすると、 親(シェル自身)はSIGINTを無視するが、子プロセス(外部コマンド)はデフォルト動作に戻る という解釈どうして出てくるかさっぱりなので、教えてください お願いします
392 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 01:17:55.06 ] trapがそういう仕様だから。man読め。
393 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 07:26:12.43 ] シェルのマニュアルのtrap項目だと、指定コマンドが空文字列だと そのシグナルを無視し、子プロセスも無視するとは書かれているけど、 これだけだとわかりにくいかも。 trapで何らかのコマンドを指定すると、それはシグナルハンドラが設定されるので、 シグナルの一般仕様により、シグナルハンドラが設定されている場合の子プロセスでは シグナル設定はデフォルトに戻る。 よって、ダミーのシグナルハンドラを設定するために、: コマンドを指定している。
394 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 13:56:39.45 ] awkで複数のファイルに対して一括処理するときに変数xを初期化したいのですがうまくいきません。 何が間違っているのでしょうか? BEGIN{x = 0} printf("%d\n",x++) END{x=0 }
395 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 14:04:05.23 ] awkがそういう仕様だから。man読め。
396 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 14:11:30.36 ] >>394 BEGIN{}等は使わない ↓ #!/bin/awk -f FNR==1{x=0} {printf("%d?n",x++)}
397 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 15:17:34.24 ] >>391 ":"がnull commandなのは先頭語に出てきた場合だけ。 trapが第一引数の":"をどう解釈しようと自由。 ただnull commandからの類推で「無視するが〜」としただけ。
398 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 15:22:42.53 ] >>397 ちがうよ。 trapは、第1引数を改めてコマンドとして解釈する(2回解釈する)ので、 結局 : は先頭に出てきたのと同じで、null command として解釈される。 (eval : の場合と似てる) trapが:を特別に解釈しているわけではない。 たとえば、trap true 2 って書いても trap : 2 と同じ。
399 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 15:54:02.25 ] むしろ特別に扱っているのは""の方。 これでSIG_IGNにすることになってる。
400 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:12:06.60 ] awkのフィールド分割的なことやるのに while read hoge hage ; do : done <file とかよくやるけど、1行の文字列を分割しようとして echo "hoge hage" | read hoge hage ってやってみても、$hoge にも $hage にも何も入らない なんで?
401 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:28:41.94 ] そういう仕様じゃないから
402 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:29:53.91 ] kshだとできるよ。
403 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:31:57.84 ] echo "hoge hage" | { read hoge hage echo hoge=$hoge hage=$hage }
404 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:36:20.13 ] >>403 おおー入った! \(@o@)/ どういう仕様になってるんだろう サブシェル的な問題?
405 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 08:06:57.00 ] >>404 その通りだが、そうならないシェルもある。自分なら read hoge hage <<<"hoge hage" って書く
406 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 10:45:26.99 ] ヒアストリングってbash/zsh以外でも使えんの?
407 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 11:12:25.51 ] 古典ヒアストリングならな。
408 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 18:54:44.50 ] ソラリスのkshは冷やすとリング使えないのに、 リナックスのkshは冷やすとリング使える不思議
409 名前:400 mailto:sage [2012/02/28(火) 22:39:16.48 ] ヒアストリングってスレの初めの方で出てたやつですか オイラの読んだ入門書には載ってなかったんだよなぁ と思いながら試してみたら Syntax error: redirection unexpected sh -> dash なうちのDebianじゃダメみたい (・ω・` ) ステキな機能だけに残念 やっぱこういう場合はset使うべきなんですかね…
410 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 22:52:20.02 ] >>403 じゃまずいの? 一行で書きたいならセミコロン echo hoge hage | { read hoge hage; echo hoge=$hoge hage=$hage; }
411 名前:名無しさん@お腹いっぱい。 [2012/02/29(水) 02:06:19.12 ] getoptsにて「-yx」のように複数文字のオプションを判定することは可能なのでしょうか? xxx.sh -a test -yx #!/bin/ksh while getopts a:yx opt do case ${opt} in a) YY=${OPTARG} echo "オプション[-a]の引数は${YY}だよ。" ;; yx) echo "オプション[-yx]があるよ。" ;; esac done
412 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 08:15:39.53 ] >>411 getoptsでは、-yx は -y -x と指定したのと同じに解釈されるから無理。
413 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 10:48:10.11 ] 代わりに --xy を使うとよろし。
414 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 10:50:38.33 ] >>413 すみませんが詳しい方のみ回答をお願いします
415 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 10:54:40.48 ] ああ --yx か。とにかく>>412 のいう通りってこった。
416 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 11:34:25.80 ] getopts y: として $OPTARG が x かどうか判定すればいいんじゃね? -y x も受けつけちゃうけど。
417 名前:名無しさん@お腹いっぱい。 [2012/02/29(水) 14:08:24.59 ] どうもこんにちは〜 list=`cat ./file | grep aaa` って感じでlistにaaaを持つ行を全部放り込んでるのですが、 これらを別々の1行ずつに分割して なおかつlistを配列にして格納する事はできますか。 具体的には、fileの中にはaaaの文字列を持つ行が5つあるのですが それをlist[0]〜list[4]に格納したいのです。 よろしくご指導お願いしますm(_ _)m
418 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 14:10:31.36 ] なんで cat 通すんだろ。 grep aaa file でよくね?
419 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 15:35:13.71 ] >>417 IFSに改行コードのみを代入した状態で、list配列に一括代入する文法を使う。 #!/bin/bash IFS=' ' list=(`grep aaa file`)
420 名前:名無しさん@お腹いっぱい。 [2012/02/29(水) 16:42:01.73 ] >>419 ありがとうございます! できました!
421 名前:400 mailto:sage [2012/02/29(水) 23:33:48.87 ] ロングオプションは getopt でいけるけど何か問題もあったんだっけ >>410 パイプ通すとブレースもサブシェルで動作してるのか 外からは参照できないみたいなんですよね いやもちろん最初の例もサブシェル作ってるんですが (;´Д`) 処理の内容にもよるけど、やっぱりグローバルで使いたいってなると 関数に括り出してバッククォートで呼んだりして結局同じようなことなのかなぁと そんな感じの意味です でも勉強になりましたみなさんありがとう
422 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/01(木) 06:47:03.28 ] >>421 getopt(外部コマンド)はスペース入りファイル名などの引数を正常に扱えない などの仕様バグの固まり。getoptsを使うべし。
423 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 08:04:37.31 ] とあるソースから #define HOGE MAGE HOGE の定義値を抽出したい。 grep HOGE header.h |grep define |awk print $NF みたいな書き方(うろ覚え)すると キャリッジリターンも拾うわ、 タブ(スペース)数でフィールド変わるわなんですが うまい方法ないですか?
424 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 08:12:54.29 ] >>423 $ cat header.h #define HOGE MAGE $ (cat header.h; echo HOGE) | gcc -E -P - MAGE
425 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 08:25:52.14 ] プリプロセッサに置き換えられるからプリプロセッサに置き換えさせるとかワロタw
426 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 09:38:08.86 ] でもうまい方法でしょ?
427 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 10:17:08.26 ] #ifとか考え出したらそれ一択。
428 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 12:00:16.07 ] 複数行に渡るマクロもあるしな。 けどお題はもっと単純な話なんじゃないのかな。 マクロの展開を止めたいなら、 (#define MAGE 〜があってもMAGEを出力したい場合) awkスクリプトになってしまったが、こんな感じ。 awk '$0 ~ /^#define[ ]+HOGE/ { $1=""; $2=""; print $0 }' []の中はスペースとタブ
429 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 22:50:17.04 ] 質問です。 あるディレクトリにある全部のファイルに対して コンパイルをかけるスクリプトをつくりたいです。 TESTLISTには ソース名 コンパイラオプション が書いてあります(hoge.c 5みたいに) --------------------------------------------- #!/bin/sh # プログラム、コンパイルオプション一覧リストを指定 LIST=/home/shell/TESTLIST # コンパイラのパスを設定 CCOM=/home/shell/cc.sh # コンパイルをかける while read ARG1 ARG2 do ${CCOM} ${ARG1} ${ARG2} done < ${LIST} -------------------------------------------- のような簡単な奴で良いんですが、
430 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 22:51:02.05 ] 続き cc.shの中に、 -------------------------------------------- if [ ${RETCD} -ne 0 ] then echo "コンパイルログを表示しますか?" RCV="" while [ `echo "${RCV}" | sed -ne '/^[ ]*[yYNn][ ]*$/p' | wc -l` -eq 0 ] do read RCV done if [ `echo "${RCV}" | sed -ne '/^[ ]*[yY][ ]*$/p' | wc -l` -ne 0 ] then more ${コンパイルログ} fi fi ------------------------------------------- のように書いてあり、コンパイルに失敗した場合、 「コンパイルログを表示しますか?」が端末に表示されたままで、「N」や「Y」を 入力しても反応がなく、Ctr-Cで実行を打ち切っている状態です。
431 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 22:52:03.41 ] 続き コンパイルに失敗した場合、Ctr-Cを入力すると 次のファイルにコンパイルをかけるようにしたいのですが、 -------------------------------------------- #!/bin/sh # プログラム、コンパイルオプション一覧リストを指定 LIST=/home/shell/TESTLIST # コンパイラのパスを設定 CCOM=/home/shell/cc.sh # Ctr-Cを無視するように設定(サブシェルには有効) trap : 2 # コンパイルをかける while read ARG1 ARG2 do #サブシェル化 (${CCOM} ${ARG1} ${ARG2}) done < ${LIST} --------------------------------------------- でオッケーでしょうか? ちなみにMakeは使用不可です。また、cc.shはいじれません。
432 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 11:06:00.37 ] >ちなみにMakeは使用不可です。また、cc.shはいじれません。 この状況を何とかした方が建設的かと。
433 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 19:10:20.96 ] >>431 > でオッケーでしょうか? つまり俺たちにデバッグしろと言っているのか?
434 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 19:12:06.02 ] はい
435 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 19:19:26.97 ] はいじゃないだろうが!
436 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 19:21:31.59 ] はいじゃないが
437 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 20:23:39.44 ] はいはい。
438 名前:名無しさん@お腹いっぱい。 [2012/03/06(火) 21:07:07.27 ] >>429 コンパイルに失敗した場合、「N」や「Y」を入力しても反応がない原因を 教えてやる。 >>429 の while do .. done ループで、done < ${LIST} となってるので、 標準入力が ${LIST} にリダイレクトされたままになってて、 その状態で cc.sh が起動されてる。 cc.shの中でキーボードを読んでるつもりが、${LIST}を読んでしまうので、 「N」や「Y」を入力しても反応しない。 解決方法は、>>429 で、 ---------------------------- exec 3< ${LIST} while read ARG1 ARG2 do ${CCOM} ${ARG1} ${ARG2} done 0<&3 ---------------------------- とすること。標準入力をキーボードにしたまま、readには記述子3を読ませる。
439 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 21:12:06.05 ] >>438 おいおい、そのリダイレクト方法だと結局同じ理由で駄目だよ。 標準入力を退避しておいて復帰する。 exec 3<&0 while read ARG1 ARG2 do ${CCOM} ${ARG1} ${ARG2} 0<&3 done < ${LIST}
440 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 21:17:04.64 ] >>439 の方法でもいいが、 >>438 が言いたかったのは ↓じゃないかな exec 3< ${LIST} while read ARG1 ARG2 0<&3 do ${CCOM} ${ARG1} ${ARG2} done
441 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 22:15:57.04 ] >431 > でオッケーでしょうか? オッケーだと言う人がいたらしいよ。 ただし私は、貴方の環境と責任を共有していないので、自己責任でやって下さいね。
442 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:36:49.85 ] テキストから読み込んだ文字列内の「\\」をそのまま変数に入れたり表示させたりする方法を 探しています。OSはCentOS6、シェルはbashです 以下のような問題に対処したいのですが、何か手段はありますでしょうか? 以下のsampletext.txt(「\\」や「\」を含む)を、readecho.shのようにreadで読み、 echoで出力すると、「\」がエスケープか何かされているようで、表示されません bashやechoのmanにある-Eオプションを明示的に付与してみても変化が無いようです awkprint.shのようにawkで行うと期待した結果が出るのですが、他の処理の関係上、 できればawkは使わずに、シェルスクリプトで実現させる方法を知りたく思ってます テキストを事前に「\\」から「\\\\」としておく等の対処はせずに済ませたいです $ cat sampletext.txt \\winsv\a\b\c \\sambasv\d\e\f $ cat readecho.sh #! /bin/sh while read STRING do echo -E "${STRING}" done < sampletext.txt $ ./readecho.sh \winsvabc \sambasvdef ←「\\」が「\」になり、「\」が消えている。NG $ cat awkprint.sh #! /bin/sh cat sampletext.txt | awk '{print $0}' $ ./awkprint.sh \\winsv\a\b\c \\sambasv\d\e\f ←上記のような問題はない。OK
443 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:42:21.68 ] >>442 read -r
444 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:42:48.66 ] つread -r
445 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:45:02.83 ] 普通はread -rだけどbashは知らん。
446 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:48:20.73 ] >>443-445 情報ありがとうございました うまくいきました bashでもreadは「Backslash does not act as an escape character.」だそうです なるほどreadで対処するのか... $ cat readecho.sh #! /bin/sh while read -r STRING do echo -E ${STRING} done < sampletext.txt $ ./readecho.sh \\winsv\a\b\c \\sambasv\d\e\f
447 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:55:51.24 ] >>446 > bashでもread -rは「Backslash does not act as an escape character.」だそうです と書きたかったのか?
448 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 22:27:14.08 ] AとBの処理があって、 Aを開始、 Bを開始 Bの中でAの処理中を待つことできますか? 意味わかりませんかね・・・ mkdirとかロック待ちみたいなやつです。
449 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 22:43:33.00 ] ロック待ちがわかるんなら、そのまんま A で mkdir lock して B で [ -d lock ] かければ? while 文で無限ループ作って、sleep でも挟めば十分「処理待ち」になると思うけど。
450 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 22:44:29.80 ] >>448 FreeBSDなら lockf(1)、Linuxならflock(1)を使ってなんとかしろ。
451 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 23:06:08.54 ] >>449-450 ありがとうございます。 がんばってみます。
452 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 23:18:55.14 ] >>450 なんで似てるようで違う名前なの?
453 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/10(土) 00:14:30.88 ] カレーライスとライスカレーみたいなモン
454 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/10(土) 09:50:04.49 ] うまいなあ。それイタダキマス。
455 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 03:13:24.48 ] a=0 for FILE in `find / \( -iname "zoo*.png" -o -iname "land*.png" -o -iname "zoo*.txt -o -iname "land*.txt" \)`; do rm -vf $FILE echo $a done 初心者です、スクリプト書いてみたんですが、この$aで表示される数がおかしくてこまってます。 なぜかrmコマンドでは1つも削除されておらずメッセージも表示されていないのに4と表示されるのです。 やりたい事としてはこうです↓ 「zoo*.png、land*.png、zoo*.txt、land*.txtというファイル名のファイルを全て削除し、その数をカウントする」 何がおかしいのでしょうか?
456 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 04:32:12.07 ] >>455 4が表示されるのはオカルト。君もうすぐ死ぬんじゃない? ファイルを削除して数をカウントしたいだけなら find ほにゃらら -print0 | xargs -0 rm -v | wc -l でよい。変数もforも必要ない。 4が出るのは君がオリジナルのスクリプトをここにコピペするときに何か端折ったせいだろう。
457 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 04:53:51.30 ] >>456 ごめんなさい、a=$(($a + 1))が抜けてました... にしてもこんなにコンパクトになるもんなんですね ありがとうございました
458 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:05:01.28 ] xargsは原始人の道具。 find ほにゃらら -exec rm -v {} + | wc -l で良い。
459 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:11:05.46 ] -deleteが使えるfindもある find ほにゃらら -delete -print | wc -l
460 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:14:18.54 ] >>458 -exec の方が古い感覚だけどどうなんだろ?
461 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:17:25.43 ] >>460 -exec ';' なら古い感覚 -exec + は新しい感覚