シェルスクリプト総合 その7
■ このスレッドは過去ログ倉庫に格納されています
0001ミスターシェル
2006/09/07(木) 13:00:11スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
0611名無しさん@お腹いっぱい。
2006/12/16(土) 18:56:56別に中身は消えないんでしょうけどww
なんか気持ち悪いorz
すんませんありがとでございます
0612名無しさん@お腹いっぱい。
2006/12/16(土) 23:09:40「ディレクトリがなかったら作る」でいいんじゃないの?
こんな感じ↓でやれば、1行で済むじゃん。
[ ! -d ディレクトリ ] && mkdir ディレクトリ
0613名無しさん@お腹いっぱい。
2006/12/16(土) 23:57:530614名無しさん@お腹いっぱい。
2006/12/17(日) 01:06:26mkdir dir 2> /dev/null
でおけ。
0615名無しさん@お腹いっぱい。
2006/12/17(日) 14:11:54基本を身に付けたいorz
0616名無しさん@お腹いっぱい。
2006/12/17(日) 18:50:14set -e
で不都合が生じるから減点。
0617名無しさん@お腹いっぱい。
2006/12/17(日) 19:54:25mkdir -p dir 2>/dev/null || :
0618名無しさん@お腹いっぱい。
2006/12/17(日) 20:25:490619名無しさん@お腹いっぱい。
2006/12/19(火) 18:01:03標準入出力を意識(理解?)していない人は多いね。
たとえば、tar cf - . | ( cd /xxx && tar xpvf - ) とかすると
"-" について9割くらいは見ていた人に聞かれるし簡単には
何をやっているか理解してもらえない。
後は、3>&1 とか使えば多少は幅広がるのにね。
0620名無しさん@お腹いっぱい。
2006/12/19(火) 18:04:17またちょっと別の話かと。
0621名無しさん@お腹いっぱい。
2006/12/20(水) 06:17:18それぞれのオプションの意味を覚えていないやつってのはいるよね
結局伸びない
0622名無しさん@お腹いっぱい。
2006/12/20(水) 06:25:30そんな奴おらんやろ〜
0623名無しさん@お腹いっぱい。
2006/12/20(水) 07:40:370624名無しさん@お腹いっぱい。
2006/12/20(水) 07:45:47いるよ〜
>>623
paxもおすすめ
0625名無しさん@お腹いっぱい。
2006/12/20(水) 09:08:53zはgzだろ
xは解凍
cは圧縮
vは状況表示
fはファイル指定
じゃ無かったかな。
man tar してません。
0626名無しさん@お腹いっぱい。
2006/12/20(水) 09:22:560627名無しさん@お腹いっぱい。
2006/12/20(水) 09:26:12普段はファイラから解凍や圧縮してたんでじぇんじぇん覚えてにゃ
0628名無しさん@お腹いっぱい。
2006/12/20(水) 09:32:170629名無しさん@お腹いっぱい。
2006/12/20(水) 09:48:150630名無しさん@お腹いっぱい。
2006/12/20(水) 10:18:46その知識自体の価値ではなく、その人の性質というかそういうものについてだよね
0631名無しさん@お腹いっぱい。
2006/12/20(水) 11:27:320632名無しさん@お腹いっぱい。
2006/12/20(水) 13:42:15あと正規表現モナーですか?
0633名無しさん@お腹いっぱい。
2006/12/20(水) 19:39:44月が替わったりすると無理じゃね?w
20061125
20061201
20061231
20070101
よく月の1日にはリセットだなw
0634名無しさん@お腹いっぱい。
2006/12/20(水) 21:25:320635名無しさん@お腹いっぱい。
2006/12/20(水) 23:33:000636名無しさん@お腹いっぱい。
2006/12/21(木) 00:16:42BSD系なら
T=$(($(date +"%s") - 86400*10))
DATE=$(date -r $T +"%Y%m%d")
Linux (というかGNU coreutils) なら
DATE=$(date -d '10 days ago' +"%Y%m%d")
0637名無しさん@お腹いっぱい。
2006/12/21(木) 00:27:270638名無しさん@お腹いっぱい。
2006/12/21(木) 00:37:34-vはFreeBSD限定のような気がする
0639名無しさん@お腹いっぱい。
2006/12/21(木) 02:39:21rm `ls -t /directory/*.log | tail -n +11`
なんて方法もあるかなと。
0640名無しさん@お腹いっぱい。
2006/12/21(木) 08:04:44それいけるのか?
1日に複数個ログはいても
0641名無しさん@お腹いっぱい。
2006/12/21(木) 16:23:03ago だかなんかの引数で
0642名無しさん@お腹いっぱい。
2006/12/21(木) 16:29:37FreeBSDのdateは無理です
0643名無しさん@お腹いっぱい。
2006/12/21(木) 16:36:300644名無しさん@お腹いっぱい。
2006/12/21(木) 18:41:380645名無しさん@お腹いっぱい。
2006/12/23(土) 04:10:11foo *
というようなことをやりたいのですが、arg list too longというような
メッセージが出ます。
で、有名な
echo * | xargs foo
で解決と思いきや、xargsってARG_MAXを超えた引数については、fooを呼びなおすみたいですね。
fooは全てのファイルに対して1回だけ実行されないと困るんですが、何かいい方法はあるでしょうか?
0646名無しさん@お腹いっぱい。
2006/12/23(土) 09:36:470647名無しさん@お腹いっぱい。
2006/12/23(土) 09:45:32xargs でいいじゃん
0648名無しさん@お腹いっぱい。
2006/12/23(土) 10:11:400649名無しさん@お腹いっぱい。
2006/12/23(土) 10:27:411 fooをshell functionで書き直す。
2 arglist広げてシステム再構築。
3 fooを複数回実行されても困らないよう作り直す。
0650名無しさん@お腹いっぱい。
2006/12/23(土) 10:31:370651名無しさん@お腹いっぱい。
2006/12/23(土) 11:34:05find ... | xargs tar cvf hoge.tar
で ARG_MAX にあふれたファイルだけ入ったアーカイブ作ったことある。
たぶん受け側のプログラムを標準入力からファイル一覧読むように
改造するしかない。
0652名無しさん@お腹いっぱい。
2006/12/23(土) 12:20:28欲嫁。
>xargsってARG_MAXを超えた引数については、fooを呼びなおす
0653名無しさん@お腹いっぱい。
2006/12/23(土) 12:25:480654名無しさん@お腹いっぱい。
2006/12/23(土) 12:37:58xargsでいいじゃん
0655名無しさん@お腹いっぱい。
2006/12/23(土) 12:54:36欲嫁。
>xargsってARG_MAXを超えた引数については、fooを呼びなおす
0656名無しさん@お腹いっぱい。
2006/12/23(土) 13:05:47fooで同じファイルを二度処理するのはまずいってだけの話なら
xargsでいいんでないの?
一度のfooの実行で全ファイルを処理したいっつーんなら、
引数渡しでやるのは無理だわなそりゃ
0657645
2006/12/23(土) 13:58:06書き方が悪かったですが、fooは複数回実行されると困るというよりも、
全ファイルのデータを読み込んだ上でまあ数値計算みたいなものなんですが、
計算を行いたいわけです。
一度に処理されないと意味がない、ということです。
>>653
これ試してみましたけど、-n 100000とかやってもARG_MAXの壁は越えられないんで駄目でした。
どうもfoo内でフャ@イル一覧を読b゙ように書き換bヲるか、再構築bチてことみたいbナすね。
0658名無しさん@お腹いっぱい。
2006/12/23(土) 14:02:43ガベージアウト
0659名無しさん@お腹いっぱい。
2006/12/23(土) 15:50:070660名無しさん@お腹いっぱい。
2006/12/23(土) 15:58:380661名無しさん@お腹いっぱい。
2006/12/23(土) 16:19:21受け側のプログラムが引数使わないように修正する以外に方法はないって。
0662名無しさん@お腹いっぱい。
2006/12/23(土) 22:29:440663名無しさん@お腹いっぱい。
2006/12/23(土) 22:44:110664名無しさん@お腹いっぱい。
2006/12/23(土) 22:50:02kwsk
0665名無しさん@お腹いっぱい。
2006/12/25(月) 11:59:270666名無しさん@お腹いっぱい。
2006/12/25(月) 12:02:430点
0667名無しさん@お腹いっぱい。
2006/12/25(月) 12:06:06100点
0668名無しさん@お腹いっぱい。
2006/12/25(月) 12:16:32foo file1 file2 .... (すべてのファイル)
みたいに、1回だけで実行したいという質問なので、
>>665 は 0点。
0669名無しさん@お腹いっぱい。
2006/12/25(月) 12:26:590670名無しさん@お腹いっぱい。
2006/12/25(月) 13:13:180671名無しさん@お腹いっぱい。
2006/12/25(月) 17:00:20普通はプログラムを書き直すよな...
0672名無しさん@お腹いっぱい。
2006/12/27(水) 19:02:580673名無しさん@お腹いっぱい。
2006/12/28(木) 02:21:04上限なんだね。標準入力からN行読み込んでexecvpで直接渡すようなの
書いてみたら32768でアウト。
任意のコマンドのmainをフックして、単なる関数として渡すような形で
汎化しないと駄目だな。もっとも問題のプログラムが処理対象のリストを
標準入力から読んだほうがよほどいいと思うけど。
0674名無しさん@お腹いっぱい。
2006/12/28(木) 08:02:050675名無しさん@お腹いっぱい。
2006/12/28(木) 17:30:54バカか?
0676名無しさん@お腹いっぱい。
2006/12/28(木) 19:40:53レジスタ渡し、あるいはスタック渡しの部分で、malloc()で上書き。
.gdbinit で、がんがん代入。
実行開始。
ってのは、どう?
0677名無しさん@お腹いっぱい。
2006/12/28(木) 21:21:09-Dmain=xmain して、別途 dlsym(h, "xmain"); で呼び出すとか。
mainをそのまま直接呼ぶ方法あるのかな?ptraceとか使える?
0678名無しさん@お腹いっぱい。
2006/12/28(木) 21:27:020679名無しさん@お腹いっぱい。
2006/12/28(木) 22:49:41( cat <<EOFEOF
extern int printf(const char *,...);
main(int ac,char *argv[])
{
int i;
for(i=0;i<ac;i++)
printf("%d %s¥n",i,argv[i]);
}
EOFEOF
) | gcc -x c -
(
echo "b *main"
echo "run"
echo 'set $r3=3'
echo 'set *((char **)$r4) = "test1"'
echo 'set *((char **)$r4+1) = "test2"'
echo 'set *((char **)$r4+2) = "test3"'
echo 'set *((char **)$r4+3) = "test4"'
echo " c" ) | gdb ./a.out
(Mac OS X 限定...)
ってな感じで、symbol table がある場合は可能らしい。strip されている場合は、
entry point を根性で探してくれ。
0680名無しさん@お腹いっぱい。
2006/12/28(木) 22:52:07set $r4=(void *)malloc(1000)
とかで malloc() するのを忘れずに。
0681名無しさん@お腹いっぱい。
2006/12/29(金) 11:23:430682名無しさん@お腹いっぱい。
2006/12/29(金) 12:24:23環境なら)だから、そちらで調べた値をreadelfで得たエントリポイント
アドレスに足せばgdbのブレークポイント設定位置が判るよ。
後は$espから引数にアクセスして書きかえればいい。
この一連の操作はシェルスクリプトにできるから、xargsで扱えない
例外状況の処理用ツールになる(かもしれない)。
0683名無しさん@お腹いっぱい。
2006/12/29(金) 19:38:07例えば ./foo/bar/mbox を ./foo_bar_mbox にコピーしたい。
find . -type f -name mbox -exec cp {} `echo {}|tr '\/' '_'` \;
とかしても
cp: ./foo/bar/mbox and ./foo/bar/mbox are identical (not copied).とエラーになっちゃう。
スレ違いだったら誘導して
0684名無しさん@お腹いっぱい。
2006/12/29(金) 19:46:12シェルが先に ` ` を評価するから
実際に実行されるのは
find . -type f -name mbox -exec cp {} {} \;
になるな。
0685名無しさん@お腹いっぱい。
2006/12/29(金) 20:11:470686名無しさん@お腹いっぱい。
2006/12/29(金) 20:27:540687名無しさん@お腹いっぱい。
2006/12/29(金) 20:30:280688名無しさん@お腹いっぱい。
2006/12/29(金) 21:24:58>>685の方法で出来た。
0689名無しさん@お腹いっぱい。
2006/12/29(金) 21:30:16このスレのまとめって無いのかなぁ
ここしばらくの話、めっちゃ勉強になるんですけど
0690名無しさん@お腹いっぱい。
2006/12/29(金) 21:32:30それ以前の問題で外してしまった >>686 はもっと不憫。
0691名無しさん@お腹いっぱい。
2006/12/29(金) 21:36:010692名無しさん@お腹いっぱい。
2006/12/29(金) 22:02:53>>687はエラー出ちゃうんだよ。
どうも最初の/しか置換されなくて._foo/bar/mboxにコピーしようするの。
で原因なんだろうと調べてみてるんだけどわけわからん。
0693名無しさん@お腹いっぱい。
2006/12/29(金) 22:13:46まとめてクレクレ
0694名無しさん@お腹いっぱい。
2006/12/29(金) 22:48:30多分 sed の部分が間違っているんじゃないかな
検証してないけど
0695名無しさん@お腹いっぱい。
2006/12/29(金) 22:49:130696名無しさん@お腹いっぱい。
2006/12/29(金) 23:55:59echo "$(echo " $(echo "`echo "$(ps)"`")")"
ちょい大げさに書きすぎたけど、こんな感じのを見かけた
これはどんな決まりでトークンに切り分けてるのさ!!
0697名無しさん@お腹いっぱい。
2007/01/01(月) 00:02:28今年もよろ69
0698名無しさん@お腹いっぱい。
2007/01/01(月) 01:30:450699名無しさん@お腹いっぱい。
2007/01/01(月) 02:23:40Yellow Mookだろ。
それくらい察してやってくれ。
0700名無しさん@お腹いっぱい。
2007/01/02(火) 11:18:36素で分からんかったorz
0701名無しさん@お腹いっぱい。
2007/01/03(水) 19:21:380702名無しさん@お腹いっぱい。
2007/01/03(水) 19:36:330703名無しさん@お腹いっぱい。
2007/01/09(火) 22:08:180704名無しさん@お腹いっぱい。
2007/01/10(水) 15:53:220705名無しさん@お腹いっぱい。
2007/01/10(水) 15:59:180706名無しさん@お腹いっぱい。
2007/01/11(木) 20:32:03失礼しました
0707名無しさん@お腹いっぱい。
2007/01/11(木) 22:03:310708名無しさん@お腹いっぱい。
2007/01/12(金) 00:58:20sed 's/aaa/bbb/' hoge.dat > tmp.dat
mv tmp.dat hoge.dat
のようにして、一時的なファイルとしてtmp.datというファイルを用意するのが無駄だと
思うのですが、このような一時的なファイルを使わないで
直接、hoge.datをsedで編集する方法はありませんでしょうか?
m(_ _)m
0709名無しさん@お腹いっぱい。
2007/01/12(金) 01:08:30・-i オプションをつかう
・-i オプションがないsedをつかっているなら in-place editing 対応の sed の導入を検討する
・ed をつかう
・perl を使う
・一時ファイルを必要としないファイル命名法を検討する
お好みで
0710名無しさん@お腹いっぱい。
2007/01/12(金) 01:10:26あとinplaceというあらゆるフィルタをin-place editに使うコマンド
もある。(これはぐぐって)
■ このスレッドは過去ログ倉庫に格納されています