シェルスクリプト総合 その20
レス数が900を超えています。1000を超えると表示できなくなるよ。
0001名無しさん@お腹いっぱい。
2012/06/08(金) 00:35:51.19スクリプトのお勉強・自慢・腕試しなどにどうぞ。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
FreeBSDユーザは/bin/shの正体がashなので注意。
v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
http://heirloom.sourceforge.net/sh.html
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
前スレ
シェルスクリプト総合 その19
http://toro.2ch.net/test/read.cgi/unix/1323515200/
0832名無しさん@お腹いっぱい。
2012/09/14(金) 11:04:58.510833名無しさん@お腹いっぱい。
2012/09/14(金) 12:35:38.76っていうか、なんで出来ないの?
Excelのシートに記入するところは苦戦しそうだけど。
0834名無しさん@お腹いっぱい。
2012/09/14(金) 16:45:58.07寧ろUSBメモリ移動が鬼門。
0835名無しさん@お腹いっぱい。
2012/09/15(土) 13:19:37.17egrep "\t" *.txt
だと、tを検索してしまいます。
0836名無しさん@お腹いっぱい。
2012/09/15(土) 13:22:50.87こっちもやり方がよくわかりません。
ついでに教えてください。
0837名無しさん@お腹いっぱい。
2012/09/15(土) 13:32:23.770838名無しさん@お腹いっぱい。
2012/09/15(土) 13:38:45.62対話環境での話ならCTRL-Vあたりがクォート機能に割り当てられている
シェルなら
$ grep '[CTRL-V][TAB]' *.txt
スクリプトの中ならエディタでTABコード書けるだろ。
0839名無しさん@お腹いっぱい。
2012/09/15(土) 13:44:39.15(じゃあMakefileは? というのは無しで)
0840名無しさん@お腹いっぱい。
2012/09/15(土) 15:06:46.92http://linuxjm.sourceforge.jp/html/GNU_bash/man1/bash.1.html#lbAS
grep $'\t' *.txt
0841名無しさん@お腹いっぱい。
2012/09/15(土) 21:55:57.05grepでというのには反則だけど
perl -ne 'print if /\t/'
0842名無しさん@お腹いっぱい。
2012/09/15(土) 21:59:20.76grep -P なら許す
0843名無しさん@お腹いっぱい。
2012/09/15(土) 23:49:50.180844名無しさん@お腹いっぱい。
2012/09/16(日) 09:58:27.49rsync以外で効率のいいやり方を教えて下さい。
diff -rqやfind | sort | diffでは遅すぎるのでもっといいやり方は無いでしょうか。
0845名無しさん@お腹いっぱい。
2012/09/16(日) 10:10:52.16diff <(ls -aR /dir1) <(ls -aR /dir2)
0846名無しさん@お腹いっぱい。
2012/09/16(日) 10:21:29.26ありがとうございます。確かに速いですね。
ただ、lsの出力がファイル名だけなので、diffからファイルのパスが分からないのが困ります。
他にdir1にあってdir2に無いファイルを相対/絶対パスで取得できる方法はありませんか?
情報後出しで済みません。
0847名無しさん@お腹いっぱい。
2012/09/16(日) 10:26:29.46勝手に遅いと思い込んでいました。とりあえずこの方法でやってみます。
回答して下さった方どうもすみませんでした。
0848名無しさん@お腹いっぱい。
2012/09/16(日) 10:56:10.15diff -u <(cd old/ && find . | sort) <(cd new/ && find . | sort) | grep '^\+./'
rsync -naiO --ignore-existing new/ old/ | awk '{print $2}'
diff -rq old/ new/
で、上から順に速いことが分かりました。御参考まで。
0849名無しさん@お腹いっぱい。
2012/09/16(日) 12:14:22.36どちらかのみ含まれるファイルを取り出すのに diff -u して grep ^+ してるけど
commを使うといいかもしれない
0850名無しさん@お腹いっぱい。
2012/09/16(日) 12:24:49.73みなさん、ありがとうございました!
うちにきて弟をファックしてもいいですよ。
0851名無しさん@お腹いっぱい。
2012/09/16(日) 14:49:42.09ありがとうございます。
comm -13 <(cd old/ && find . | sort) <(cd new/ && find . | sort)
と書き換えてスッキリしました。
dircmpのほうは古いUNIXにあったコマンドみたいですね。
自分はLinuxなので使えませんでしたが、参考になりました。
0852名無しさん@お腹いっぱい。
2012/09/16(日) 14:54:15.88結局diffでファイルの中身比較するから遅いよ。
(ファイルの中身は比較しないで欲しいという目的なら)
0853名無しさん@お腹いっぱい。
2012/09/16(日) 18:27:09.74http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/dircmp/dircmp.sh
-dオプションをつければdiffを呼ぶ
そうでない場合でも、ファイルサイズが同じ場合には cmp を呼ぶみたいですね
なるほど、同じファイル名でも違うファイルかどうかを判定する必要があるのかdircmpは
0854名無しさん@お腹いっぱい。
2012/09/18(火) 14:23:13.01例えば echo "test" という 1 行だけのシェルスクリプトを作成して、foo.sh という名前で
保存します。このファイルのパーミッションを 744 にしてコマンドラインで ./foo.sh と叩くと
正常に実行できてしまいました。
シェバング行が無いのに、何故実行できてしまうのでしょう? おそらく基本的なところで
私の理解が不足しているのだと思いますので「ここを読め!」等のポインタで結構ですので、
どなたかご教示いただけないでしょうか。
ちなみに FreeBSD、AIX、CentOS で試してみましたが、いずれも同じ結果でした。
0855名無しさん@お腹いっぱい。
2012/09/18(火) 14:29:46.54ちゃんと調べてないけど。
0856名無しさん@お腹いっぱい。
2012/09/18(火) 14:30:51.050857名無しさん@お腹いっぱい。
2012/09/18(火) 14:31:10.83昔のUNIXではシェバング行なんてなかった。
テキストファイルであっても chmod +xされていればexec()される。
まずはバイナリと仮定してカーネルのexec()を呼び出す。
するとフォーマットが合わないのでエラーで返ってくる。
このあと、コマンドラインのシェルの判断で、
「sh ファイル名」の形に修正して再度カーネルのexec()を呼び直す。
これでシェルスクリプトとして実行される。
シェバング行がある場合は最初からその行に書かれたシェルのスクリプトとして
カーネル側のexec()で直接実行される。
0858名無しさん@お腹いっぱい。
2012/09/18(火) 15:12:12.83最近、ユーザーでも自分のホームフォルダーにソフトをコピーし、
X権限をすることによってソフトが実行できてしまうことが判明しました。
これはOSのセキュリティーボールではないのでしょうか?
ユーザーのフォルダーではたとえX権限がされていても
実行できないようなおすすめのシェルって何ですか?
必要ならカーネルにバッチを当てる方法も、やもうえません。
0859名無しさん@お腹いっぱい。
2012/09/18(火) 15:15:18.02http://toro.2ch.net/test/read.cgi/unix/1000022300/775
0860名無しさん@お腹いっぱい。
2012/09/18(火) 15:19:10.12とりあえず /home以下をnoexecでmountしちゃえば?
0861名無しさん@お腹いっぱい。
2012/09/18(火) 15:27:38.120862名無しさん@お腹いっぱい。
2012/09/18(火) 15:52:29.12> するとフォーマットが合わないのでエラーで返ってくる。
これは先頭の2byteを見ていたのね。
そこから#!を使うことになった。comment(#) + execute(!)
昔の実行形式の先頭2byteがどういう値だったかは、
/usr/share/file/magic/pdpを見るといい。
古典的なUNIXでは/etc/magicにある。
典型的なテキストファイルでは使わないシーケンスになってる。
0863854
2012/09/18(火) 16:18:19.96>>857
> このあと、コマンドラインのシェルの判断で、
> 「sh ファイル名」の形に修正して再度カーネルのexec()を呼び直す。
ありがとうございます。この部分以外は自分の理解とおおむね一致していました。
自分の理解度を再確認できて良かったです。
ただ、「シェルの判断で〜」の部分ってシェルのマニュアルにはちゃんと書かれて
いるのか、それとも「昔からそういうもんだ。ソース読め」のどちらなんでしょう?
手元では tcsh / ksh / bash で同じ挙動だったので「昔からそういうもんだ」
なのかな、という予感です。
0864名無しさん@お腹いっぱい。
2012/09/18(火) 16:23:15.64択一じゃないと思う。
0865名無しさん@お腹いっぱい。
2012/09/18(火) 16:34:37.60bash移行のことじゃないか? それまではexecve(2)におまかせだったはず。
0866名無しさん@お腹いっぱい。
2012/09/18(火) 16:50:35.22GNU bash 4.2.37ではまだexecveしてENOEXECが返されるのを確認してから
そのスクリプトを読み直して処理してるみたい。
0867名無しさん@お腹いっぱい。
2012/09/18(火) 21:16:25.81ログインシェルで解釈されたような気がする。
0868名無しさん@お腹いっぱい。
2012/09/19(水) 11:56:29.71Hello,world!
って書いてもcatが起動しないんだけど、なんで?
0869名無しさん@お腹いっぱい。
2012/09/19(水) 11:59:22.550870名無しさん@お腹いっぱい。
2012/09/19(水) 12:06:17.940871名無しさん@お腹いっぱい。
2012/09/19(水) 12:07:42.490872名無しさん@お腹いっぱい。
2012/09/19(水) 13:51:27.020873名無しさん@お腹いっぱい。
2012/09/19(水) 20:18:30.82みたいなとき、./hogeのエラーを検知してリトライしたいんだけど
どうしたらいいかな
0874名無しさん@お腹いっぱい。
2012/09/19(水) 20:40:36.49A=`while ! ./hoge; do :; done | cat`
ってかんじかなぁ
0875名無しさん@お腹いっぱい。
2012/09/19(水) 20:54:25.77そっかその中でループしちゃえばいいのか
0876名無しさん@お腹いっぱい。
2012/09/22(土) 17:58:27.45望ましいシェルスクリプトの実行方法は実行権付与後に当ファイルを呼び出す方式か、 shコマンドで引数にファイルパスを指定する方法か、 .コマンドで同様にパス指定する方法か、どれになりますでしょうかね
実行時の状況次第で選ぶものだとは思いますが。。
0877名無しさん@お腹いっぱい。
2012/09/23(日) 05:23:02.47明らかに3つとも意図するところは違うだろ。
0878名無しさん@お腹いっぱい。
2012/09/23(日) 23:34:02.910879名無しさん@お腹いっぱい。
2012/09/24(月) 03:46:37.390880名無しさん@お腹いっぱい。
2012/09/24(月) 10:04:32.630881名無しさん@お腹いっぱい。
2012/09/24(月) 10:59:38.290882名無しさん@お腹いっぱい。
2012/09/24(月) 11:08:32.60(2) sh hoge.sh
(3) . hoge.sh
をどう使い分けるか。
0883名無しさん@お腹いっぱい。
2012/09/24(月) 11:08:44.90三種類実行方法がありますが、それぞれどんな特徴ですか?
それはさておき、文法を完全に把握してる人がいないんですね。wikipediaに書いてありました。
0884名無しさん@お腹いっぱい。
2012/09/24(月) 11:19:08.75(1)と(2)はそれほど明確に使い分けてないかもね
パーミッションが立ってることが保証できて、
普通のコマンドと区別する理由がなければ(1)
0885名無しさん@お腹いっぱい。
2012/09/24(月) 11:23:20.30ただ #! とかモードとかちゃんと設定しなければならない。
その辺がめんどうなら (2) で。
(3) は (1)(2) とは動きが違う。
0886名無しさん@お腹いっぱい。
2012/09/24(月) 11:33:50.71(3)が違うというのはなにが違うというのか
0887名無しさん@お腹いっぱい。
2012/09/24(月) 11:35:36.73子プロセスで実行するか現在のプロセスで実行するか。
0888名無しさん@お腹いっぱい。
2012/09/24(月) 11:36:18.770889名無しさん@お腹いっぱい。
2012/09/24(月) 11:36:48.660890名無しさん@お腹いっぱい。
2012/09/24(月) 11:37:32.270891名無しさん@お腹いっぱい。
2012/09/24(月) 12:11:39.880892名無しさん@お腹いっぱい。
2012/09/24(月) 12:42:24.30bash開発時にsh互換にするのに文法で苦労したんだって。
その時の語録みたいよ。
0893892
2012/09/24(月) 12:59:18.55みんな使っている機能なのに。
だから「本当は誰もshの文法がどうなっているのか知らないんだよ。
ソースコードなんて読んだってほとんど役立たねえよ」ってことらしい。
0894名無しさん@お腹いっぱい。
2012/09/24(月) 14:30:47.04伝聞じゃなくてソース出せ
0895名無しさん@お腹いっぱい。
2012/09/24(月) 14:45:31.61コメントってこれのこと?
0896名無しさん@お腹いっぱい。
2012/09/24(月) 14:46:52.91yaccうんぬんはこれか。
0897名無しさん@お腹いっぱい。
2012/09/24(月) 15:59:04.260898名無しさん@お腹いっぱい。
2012/09/24(月) 16:08:48.36コメントの出典。
0899名無しさん@お腹いっぱい。
2012/09/24(月) 16:26:39.69We are Japanese!
0900名無しさん@お腹いっぱい。
2012/09/24(月) 16:54:24.620901名無しさん@お腹いっぱい。
2012/09/24(月) 16:56:23.03>>892は>>896を読んだんだろう。
0902名無しさん@お腹いっぱい。
2012/09/24(月) 17:31:58.970903名無しさん@お腹いっぱい。
2012/09/24(月) 18:05:51.197th Edition なら「|」でいいっぽい。
http://plan9.bell-labs.com/7thEdMan/v7vol2a.pdf
0904名無しさん@お腹いっぱい。
2012/09/24(月) 18:31:49.56んっと、実質いけるかじゃなくて、ドキュメント上の話ね
0905名無しさん@お腹いっぱい。
2012/09/24(月) 18:36:10.23>>903
は、1979のドキュメントか。who|sortがちゃんと例に上がってるね。
who|wcが認められていないっていう出典は何だ?
0906名無しさん@お腹いっぱい。
2012/09/24(月) 19:15:26.74http://tiswww.case.edu/php/chet/bash/article.pdf
出典はこれ。>>903に含まれてるのと同じっぽい。
http://www.alcatel-lucent.com/bstj/vol57-1978/articles/bstj57-6-1971.pdf
でもなんでダメなのかはよくわからん。
0907名無しさん@お腹いっぱい。
2012/09/24(月) 20:02:57.99Chet Rameyの出典ミスのような気がする。
とりあえず、open problemは、初出のTom Duffのrc文献で
> It is remarkable that in the four most recent editions of the UNIX
> system programmer's manual the Bourne shell grammar described in the
> manual page does not admit the command who|wc.
の根拠がわからない点かな。
なのにあちこち引用されてるという……
0908名無しさん@お腹いっぱい。
2012/09/26(水) 20:55:09.390909名無しさん@お腹いっぱい。
2012/09/26(水) 20:58:49.31/⊇∧〈( ゚д゚)
`〈( ゚д゚)ヽ ⊂ニ)
ヽ_と/ ̄ ̄ ̄/ |
 ̄\/___/ ̄ ̄
0910名無しさん@お腹いっぱい。
2012/09/27(木) 13:34:15.65オナニーするんだろ?
本当にキモいよな。
0911名無しさん@お腹いっぱい。
2012/09/27(木) 15:53:41.990912名無しさん@お腹いっぱい。
2012/09/27(木) 16:49:20.71http://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%B9%E3%82%AD%E3%83%BC%E3%82%A2%E3%83%BC%E3%83%88
0913名無しさん@お腹いっぱい。
2012/09/27(木) 22:53:41.050914名無しさん@お腹いっぱい。
2012/09/27(木) 23:37:10.23http://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%B8%E3%83%AC%E3%82%B9
0915名無しさん@お腹いっぱい。
2012/10/03(水) 23:49:51.10以下の@のようにコマンドを変数に代入して、実行したいのですが、どうすればよいですか。
多分、バックスラッシュが正しく認識されていない。。
@コマンドを変数に代入した場合はNG
cmd="find /tmp/ -name \*.tsv"
for f in `${cmd}`; do
echo ${f}
done
Aベタ書きするとOK
for f in `find /tmp/ -name \*.tsv`; do
echo ${f}
done
0916名無しさん@お腹いっぱい。
2012/10/03(水) 23:54:39.82echo $f
done
0917名無しさん@お腹いっぱい。
2012/10/04(木) 08:26:24.94cmdに ' ' で代入すること " " だとバックスラッシュが解釈される。
0918名無しさん@お腹いっぱい。
2012/10/08(月) 21:27:19.47で2行目にproto=WPAを挿入したしてますが、
タブ+proto=WPAを挿入するには、どうしたら出来ますか?
0919名無しさん@お腹いっぱい。
2012/10/08(月) 21:38:16.14sed -e '1a\\tporto=WPA' wpa_supplicant.conf
0920918
2012/10/08(月) 22:10:14.93あ、そうか
ありがとうございます。
0921名無しさん@お腹いっぱい。
2012/10/09(火) 09:23:06.070922名無しさん@お腹いっぱい。
2012/10/09(火) 09:57:32.690923名無しさん@お腹いっぱい。
2012/10/09(火) 10:01:49.880924名無しさん@お腹いっぱい。
2012/10/09(火) 10:22:48.32#!/bin/sh
ls () :
ls
0925名無しさん@お腹いっぱい。
2012/10/09(火) 10:28:51.78↓この人と一緒に考えるといい。
http://toro.2ch.net/test/read.cgi/tech/1348995216/574
0926名無しさん@お腹いっぱい。
2012/10/10(水) 11:22:49.71どうしたらよいでしょうか
0927名無しさん@お腹いっぱい。
2012/10/10(水) 11:26:04.610928名無しさん@お腹いっぱい。
2012/10/10(水) 11:28:20.39grep '[-]--Hoge'
0929名無しさん@お腹いっぱい。
2012/10/10(水) 11:30:08.660930名無しさん@お腹いっぱい。
2012/10/10(水) 15:19:10.02ありがとうございました
0931名無しさん@お腹いっぱい。
2012/10/12(金) 19:22:12.36at コマンドで、日付を指定することはできませんか?
4日後の午前8時に実行したいのです。
at コマンドじゃなくてもかまいません。
FreeBSD 4.7 です。
よろしくお願いします。
0932名無しさん@お腹いっぱい。
2012/10/12(金) 19:35:22.65レス数が900を超えています。1000を超えると表示できなくなるよ。