トップページunix
1001コメント289KB

シェルスクリプト総合 その20

■ このスレッドは過去ログ倉庫に格納されています
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/
0764名無しさん@お腹いっぱい。2012/08/31(金) 13:21:45.38
>>762
ああコロンでしたかすいません
前読んだ本にはlsっていうウイルスがカレントディレクトリにあったときに備えて.は置かない方がいいって書いてたけどPATHの後ろに書いとけば大丈夫かと



あとWindowsにもPATH変数はあるけどコントロールパネル->システム->どっかのタブ->環境変数って辿らないと設定するとこまでたどりつけなくてしかも再起動しないと反映されないありさまだったような
0765名無しさん@お腹いっぱい。2012/08/31(金) 14:24:17.00
slっていうウイルスがいるかもよ
0766名無しさん@お腹いっぱい。2012/08/31(金) 15:34:17.51
バッシュと呼ぶのやめようぜ。
かなりカッコ悪い。
0767名無しさん@お腹いっぱい。2012/08/31(金) 15:39:47.48
良く口頭でビーシェルみたいな言い方する人いるけど
あれってbashのことなんだろうか。
0768名無しさん@お腹いっぱい。2012/08/31(金) 16:03:33.42
そういうネタはいいです
0769名無しさん@お腹いっぱい。2012/08/31(金) 23:12:05.50
>>764
大丈夫じゃねーよ、バカ。
0770名無しさん@お腹いっぱい。2012/09/01(土) 02:21:32.43
触るな危険
0771名無しさん@お腹いっぱい。2012/09/01(土) 09:17:52.29
grepして見つかった行の前5行を出力するってできないでしょうか?
0772名無しさん@お腹いっぱい。2012/09/01(土) 09:27:17.81
マッチした行を含めていいなら -B 6 でいいと思う
0773名無しさん@お腹いっぱい。2012/09/01(土) 09:31:57.03
-B 5 だろw
0774名無しさん@お腹いっぱい。2012/09/01(土) 14:01:09.12
ここでの話しはレベルが高いのか低いのかようわからんな
0775名無しさん@お腹いっぱい。2012/09/02(日) 04:13:15.79
ash=エーシェル
bash=バッシュ
csh=シーシェル
d-shell=ディーシェル
sh=ビーシェル
tcsh=ティーシーシェル
zsh=ゼットシェル

バッシュだけアホみたい。
0776名無しさん@お腹いっぱい。2012/09/02(日) 09:58:21.31
zshはcshにそろえて読まなきゃ駄目よ
0777名無しさん@お腹いっぱい。2012/09/02(日) 10:08:27.84
>>775
「z」は、
イギリス発音なら「ゼッ『ド』」
アメリカ発音なら「ズィー」
どこにも「ゼット」なんて発音はない。
中学英語からやり直しだなw
0778名無しさん@お腹いっぱい。2012/09/02(日) 15:38:49.68
Zを日本人がゼットって読むのはイギリス英語が基だったのか。勉強になった
0779名無しさん@お腹いっぱい。2012/09/02(日) 16:01:49.22
>>777
俺も z はズィーと習ったけどさ、
zsh をズィーシェルと読むヤツには会った事無い。
0780名無しさん@お腹いっぱい。2012/09/02(日) 17:01:28.91
で、dashは?
0781名無しさん@お腹いっぱい。2012/09/02(日) 17:05:15.94
>>780
鉄腕
0782名無しさん@お腹いっぱい。2012/09/02(日) 17:34:15.94
>>781
ググるとそっちばっかりヒットするよなw
0783名無しさん@お腹いっぱい。2012/09/03(月) 00:53:44.84
ゼットシェルで問題ないよ。
[zed-?el]が[?]に接続して、無声化して[zet-?el]
0784名無しさん@お腹いっぱい。2012/09/03(月) 11:20:15.54
そもそもとしてゼッドもゼットもどちらも正しいけどな
0785名無しさん@お腹いっぱい。2012/09/03(月) 11:35:09.44
zshは「ズシュ」
0786名無しさん@お腹いっぱい。2012/09/05(水) 02:43:38.45
いつもざしゅって読んじゃう。
0787名無しさん@お腹いっぱい。2012/09/05(水) 07:54:36.01
ザシャァッ(車田調
0788名無しさん@お腹いっぱい。2012/09/07(金) 00:21:56.75
雑種
0789名無しさん@お腹いっぱい。2012/09/08(土) 13:09:33.30
ゼットエスエイチとか
ゼットシェル

日本人なんだからZの読み方にこだわる必要なし
0790名無しさん@お腹いっぱい。2012/09/08(土) 15:23:53.34
だな。今後はゼータシェルって言うことにするよ
0791名無しさん@お腹いっぱい。2012/09/09(日) 11:41:33.37
世紀末風に言うとジードシェル
0792名無しさん@お腹いっぱい。2012/09/09(日) 13:14:38.93
もっと捻るかマトモなネタないのかよ
0793名無しさん@お腹いっぱい。2012/09/09(日) 13:22:46.94
仕事で古いパソコンを使っています。OSはUNIX-OSです。
このマシンにbashを入れたいのですが、UNIX-OS用のbashバイナリが
入手できるところをご存知の方いらっしゃいましたら、入手先を教えて下さい。

ソースからコンパイルするのは、私があまりUNIX-OSに詳しくないので、あまり気が
進まないのですが、もしもコンパイルするしかないのでしたら、ソース入手先を
教えて頂けないでしょうか。
また、コンパイルしか手段が無いとしたら、UNIX-OSでは、bashのバージョンいくつまで
対応可能でしょうか。
0794名無しさん@お腹いっぱい。2012/09/09(日) 13:35:34.28
ネタにしてはつまらなすぎる。マジな質問ならば今のキミの知識では無理としか答えようがない。
0795名無しさん@お腹いっぱい。2012/09/09(日) 14:25:33.64
2台セットの激安PCを買ったんですが、テレビが付いてなくて、、
ケーブル買ってやっと居間のテレビにつないだんですけど、
電源を入れるとオペラシステム、ナンバーTが見つかった、
みたいなシェル画面が出て先に進みません。2台ともそうです。
この後どういうシェルコマンドを打てばいいのでしょうか?
0796名無しさん@お腹いっぱい。2012/09/09(日) 17:39:59.21
よくわかんないけどシェルの事ならシェルに聞いてみるのが一番いいよ。
http://www.shell.co.jp/
0797名無しさん@お腹いっぱい。2012/09/09(日) 18:20:22.56
ありがとうございました。今環境がないので今度客先で試してみます。
0798名無しさん@お腹いっぱい。2012/09/09(日) 18:42:25.39
いいクオリティしてますね
0799名無しさん@お腹いっぱい。2012/09/11(火) 12:23:14.32
マスコミは特亜系エセ左翼・カルト宗教団体が行っている組織的な嫌がらせ、集団ストーキング、電磁波悪用、「ガスライティング」を報道しろ
0800名無しさん@お腹いっぱい。2012/09/13(木) 01:14:45.24
全くシェルスクリプトを触ったことない素人なのですが、cdを変更して
あるファイルをmakeするのが面倒なので自動化させたいです。
させたい処理はcd変更→makeの2点だけです。
ですが、うまくいきません。(シェルが一瞬立ち上がってそのまま終了します)
シェルにどういう引数を与えて起動させればいいでしょうか。
0801名無しさん@お腹いっぱい。2012/09/13(木) 01:23:56.91
make -C directory
0802名無しさん@お腹いっぱい。2012/09/13(木) 01:31:25.80
>>801
どういうことでしょうか?
bash make -C directoryでしょうか?
えーと、makeは-fオプションで行いたいので、bash make -f directoryですか?
0803名無しさん@お腹いっぱい。2012/09/13(木) 01:35:05.89
>>801
あ、いや、つまり-Cでcd変更を兼ねるわけですね。理解しました
それで、その前にシェルを起動させなければいけないのですが、シェル起動→make -C directoryまでを
一連の動作として行うにはどうすればいいでしょう亜k?
0804名無しさん@お腹いっぱい。2012/09/13(木) 02:03:13.41
んっと、自分の考えた「手段」に固執して
シェル起動とかいう独自用語使ってるとアドバイス来ないよ。
「何をしたら何が起きてほしい」と「目的」が重要。
0805名無しさん@お腹いっぱい。2012/09/13(木) 02:32:36.62
リンクか何かをクリックしたらbashが起動してmakefileしたいです。
0806名無しさん@お腹いっぱい。2012/09/13(木) 02:35:29.22
しかしシェルスクリプトを直接起動するのはNGで、必ずbashに引数を与えて起動させなければならないとします
0807名無しさん@お腹いっぱい。2012/09/13(木) 02:40:38.93
そして最も求めている手段がshにオプション引数としてシェルスクリプトを与えて起動し、makefileする方法です
0808名無しさん@お腹いっぱい。2012/09/13(木) 06:26:57.77
はい、次の方どうぞ
0809名無しさん@お腹いっぱい。2012/09/13(木) 06:38:48.75
先生、ぼくも同じ物を探しています
0810名無しさん@お腹いっぱい。2012/09/13(木) 07:40:19.71
「cd変更」って何だ。
0811名無しさん@お腹いっぱい。2012/09/13(木) 07:52:00.73
マウントしなおすんだと思ってたw
0812名無しさん@お腹いっぱい。2012/09/13(木) 08:36:35.52
しきりに「シェルを起動」って言ってるのは、
端末エミュレータ起動のことだろうとエスパー。
あるいはcygwin環境なのかも試練。

が、そういう低レベルの質問はお断りなので、
次の方どうぞ
0813名無しさん@お腹いっぱい。2012/09/13(木) 08:40:27.04
>>805-807
デスクトップと端末エミュレータとshとbashとシェルスクリプトとオプション引数とmakeとmakefileとcdとカレントディレクトリと手段と目的がごっちゃになってる。
整理して出直せ。
0814名無しさん@お腹いっぱい。2012/09/13(木) 10:11:28.58
端末エミュレーターxtermはUNIX系のほとんどのOSに対応してるって聞いたんですが、
xtermでFreeBSDのコマンドが実行できません。FreeBSDは対応してないんでしょうか?
関係あるかどうかわかりませんが、ホストOSはLinuxです。
0815名無しさん@お腹いっぱい。2012/09/13(木) 10:21:58.22
お薬出しておきますね

次の方どうぞ
0816名無しさん@お腹いっぱい。2012/09/13(木) 21:30:04.47
>>814
FreeBSDもLinuxもUNIXじゃありません。
0817名無しさん@お腹いっぱい。2012/09/13(木) 21:34:21.69
>>816
この板にfreeBSDスレ立ってますがイタチと言われません
→freeBSDはUNIX

UNIX系OS用ソフトの大半はLinuxで動きますしディレクトリ構造が同じです
→LinuxはUNIXライク
0818名無しさん@お腹いっぱい。2012/09/13(木) 21:51:52.27
>>817
freeBSDなんていうあなたが発明したシステムが
UNIXかどうかは、ほかの人にはわかりません。
0819名無しさん@お腹いっぱい。2012/09/13(木) 22:11:31.87
出されたお薬はちゃんと飲んでください
0820名無しさん@お腹いっぱい。2012/09/13(木) 22:18:29.90
ハイ、わかりますた。
でも飲んだか飲んでないか、すぐ忘れちゃうんです。
0821名無しさん@お腹いっぱい。2012/09/13(木) 23:02:26.98
飲んだかどうか記録するシェルスクリプト作るといいです
0822名無しさん@お腹いっぱい。2012/09/13(木) 23:28:44.84
そのスクリプトを起動する事を忘れちゃうんです

っつーかある意味、マジな話、一日一度、cronやatを使えず、どうしても手動で
動かさなければならない手順を、結構いつも忘れてしまう…
0823名無しさん@お腹いっぱい。2012/09/13(木) 23:29:59.39
$ while true; do sleep 86400; ./hoge; done
0824名無しさん@お腹いっぱい。2012/09/13(木) 23:40:27.06
まぁ、1日1回動かしゃいいって訳じゃなくて、例えば商用マシンからログ類を集計して、
USBメモリにコピって、テストマシンにアップロードして、集計して、そんで最終的に
得られたデータを所定のExcelのシートに記入して、その結果出てきた情報を
ログに書き込んでスクリプトを実行する、みたいな作業だ

昔は派遣の人にお願いしてたんだが、コストカットで人が減っちまった

自動化できるんならしたいわマジ
0825名無しさん@お腹いっぱい。2012/09/13(木) 23:41:01.52
trueの代わりに : で、とか
むしろ、sleep 86400 を条件にすりゃいんじゃねとかの、誘い水かね?
0826名無しさん@お腹いっぱい。2012/09/13(木) 23:44:38.84
>>825
それだとkillall sleepされたときに一緒に終了されちゃうじゃん。
0827名無しさん@お腹いっぱい。2012/09/13(木) 23:48:41.09
なんでsleep名指しで殺すんだよ
0828名無しさん@お腹いっぱい。2012/09/13(木) 23:53:12.25
>>825
while sleep 86400; do ./hoge; done
だと、最初の実行まで24時間待たされる。

敢えてsleepを条件に入れたいなら、
while ./hoge; sleep 86400; do :; done
だな。

でもこれだと結局 :コマンドが要るから、素直に
while :; do sleep 86400; ./hoge; done
かな。
0829名無しさん@お腹いっぱい。2012/09/13(木) 23:55:28.62
処理に10秒かかるスクリプトだと、毎日毎日10秒ずつ起動時刻が遅くなっていくんだな
0830名無しさん@お腹いっぱい。2012/09/14(金) 10:42:32.57
f(){ ./hoge; sleep 86400; f;}; f
0831名無しさん@お腹いっぱい。2012/09/14(金) 11:03:37.39
そして再帰が深くなりすぎて落ちる、と。
0832名無しさん@お腹いっぱい。2012/09/14(金) 11:04:58.51
末尾最適化するようにbash改造すれば大丈夫
0833名無しさん@お腹いっぱい。2012/09/14(金) 12:35:38.76
>>824
っていうか、なんで出来ないの?
Excelのシートに記入するところは苦戦しそうだけど。
0834名無しさん@お腹いっぱい。2012/09/14(金) 16:45:58.07
windows使っていいなら簡単でしょ。板違いなだけで。
寧ろUSBメモリ移動が鬼門。
0835名無しさん@お腹いっぱい。2012/09/15(土) 13:19:37.17
grepでタブを検索したいんですがどうしたらいいでしょうか

egrep "\t" *.txt
だと、tを検索してしまいます。
0836名無しさん@お腹いっぱい。2012/09/15(土) 13:22:50.87
あと、STX(アスキーコード0x02)も検索したいのですが
こっちもやり方がよくわかりません。
ついでに教えてください。
0837名無しさん@お腹いっぱい。2012/09/15(土) 13:32:23.77
8進printfしてコマンド置換かな
0838名無しさん@お腹いっぱい。2012/09/15(土) 13:38:45.62
>>835

対話環境での話ならCTRL-Vあたりがクォート機能に割り当てられている
シェルなら

$ grep '[CTRL-V][TAB]' *.txt

スクリプトの中ならエディタでTABコード書けるだろ。
0839名無しさん@お腹いっぱい。2012/09/15(土) 13:44:39.15
スクリプトは expand -8 とかで清書する場合もあるし、意味を持ったTABをじかに書くべきじゃないな

(じゃあMakefileは? というのは無しで)
0840名無しさん@お腹いっぱい。2012/09/15(土) 15:06:46.92
>>835
http://linuxjm.sourceforge.jp/html/GNU_bash/man1/bash.1.html#lbAS
grep $'\t' *.txt
0841名無しさん@お腹いっぱい。2012/09/15(土) 21:55:57.05
>>835
grepでというのには反則だけど
perl -ne 'print if /\t/'
0842名無しさん@お腹いっぱい。2012/09/15(土) 21:59:20.76
perl使うのはこのスレでは禁止
grep -P なら許す
0843名無しさん@お腹いっぱい。2012/09/15(土) 23:49:50.18
grep -e "$(printf '\t')"
0844名無しさん@お腹いっぱい。2012/09/16(日) 09:58:27.49
巨大なディレクトリツリーの差分(ファイルの有無だけでいい)を取りたいんですが、
rsync以外で効率のいいやり方を教えて下さい。
diff -rqやfind | sort | diffでは遅すぎるのでもっといいやり方は無いでしょうか。
0845名無しさん@お腹いっぱい。2012/09/16(日) 10:10:52.16
>>844
diff <(ls -aR /dir1) <(ls -aR /dir2)
0846名無しさん@お腹いっぱい。2012/09/16(日) 10:21:29.26
>>845
ありがとうございます。確かに速いですね。
ただ、lsの出力がファイル名だけなので、diffからファイルのパスが分からないのが困ります。
他にdir1にあってdir2に無いファイルを相対/絶対パスで取得できる方法はありませんか?
情報後出しで済みません。
0847名無しさん@お腹いっぱい。2012/09/16(日) 10:26:29.46
ごめんなさい、今確認したところfind | sort | diffでもそれなりに速いことが分かりました。
勝手に遅いと思い込んでいました。とりあえずこの方法でやってみます。
回答して下さった方どうもすみませんでした。
0848名無しさん@お腹いっぱい。2012/09/16(日) 10:56:10.15
ちなみに自分が試したのは

diff -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
ディレクトリの比較は dircmp が使えるなら、dircmp を使うといいかもしれない

どちらかのみ含まれるファイルを取り出すのに diff -u して grep ^+ してるけど
commを使うといいかもしれない
0850名無しさん@お腹いっぱい。2012/09/16(日) 12:24:49.73
>>838-843
みなさん、ありがとうございました!
うちにきて弟をファックしてもいいですよ。
0851名無しさん@お腹いっぱい。2012/09/16(日) 14:49:42.09
>>849
ありがとうございます。

comm -13 <(cd old/ && find . | sort) <(cd new/ && find . | sort)

と書き換えてスッキリしました。
dircmpのほうは古いUNIXにあったコマンドみたいですね。
自分はLinuxなので使えませんでしたが、参考になりました。
0852名無しさん@お腹いっぱい。2012/09/16(日) 14:54:15.88
dircmpってSolarisに付いてるけど、
結局diffでファイルの中身比較するから遅いよ。
(ファイルの中身は比較しないで欲しいという目的なら)
0853名無しさん@お腹いっぱい。2012/09/16(日) 18:27:09.74
>>852
http://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
ないときは /bin/sh でも呼ぶようになってんじゃないの。
ちゃんと調べてないけど。
0856名無しさん@お腹いっぱい。2012/09/18(火) 14:30:51.05
カーネルソースを読め。
0857名無しさん@お腹いっぱい。2012/09/18(火) 14:31:10.83
>>854
昔の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.02
コピペ改変
http://toro.2ch.net/test/read.cgi/unix/1000022300/775
0860名無しさん@お腹いっぱい。2012/09/18(火) 15:19:10.12
>>858
とりあえず /home以下をnoexecでmountしちゃえば?
0861名無しさん@お腹いっぱい。2012/09/18(火) 15:27:38.12
つまらんネタにかまうな。
0862名無しさん@お腹いっぱい。2012/09/18(火) 15:52:29.12
>>857
> するとフォーマットが合わないのでエラーで返ってくる。

これは先頭の2byteを見ていたのね。
そこから#!を使うことになった。comment(#) + execute(!)

昔の実行形式の先頭2byteがどういう値だったかは、
/usr/share/file/magic/pdpを見るといい。
古典的なUNIXでは/etc/magicにある。
典型的なテキストファイルでは使わないシーケンスになってる。
08638542012/09/18(火) 16:18:19.96
おまいら早いですねw (褒めてます)

>>857
> このあと、コマンドラインのシェルの判断で、
> 「sh ファイル名」の形に修正して再度カーネルのexec()を呼び直す。

ありがとうございます。この部分以外は自分の理解とおおむね一致していました。
自分の理解度を再確認できて良かったです。

ただ、「シェルの判断で〜」の部分ってシェルのマニュアルにはちゃんと書かれて
いるのか、それとも「昔からそういうもんだ。ソース読め」のどちらなんでしょう?

手元では tcsh / ksh / bash で同じ挙動だったので「昔からそういうもんだ」
なのかな、という予感です。
0864名無しさん@お腹いっぱい。2012/09/18(火) 16:23:15.64
マニュアルに書いてあるかどうかと昔からそういうもんかどうかって
択一じゃないと思う。
■ このスレッドは過去ログ倉庫に格納されています