トップページ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/
0270名無しさん@お腹いっぱい。2012/07/15(日) 04:05:13.03
>>269
http://svnweb.freebsd.org/base/head/etc/master.passwd?revision=218047&view=markup
root::0:0::0:0:Charlie &:/root:/bin/csh
0271名無しさん@お腹いっぱい。2012/07/15(日) 07:21:31.45
FreeBSDはなんで今でもcshがデフォルトなの?何か理由あるの?
0272名無しさん@お腹いっぱい。2012/07/15(日) 12:20:29.92
BSD だから,に尽きるんじゃないかな
0273名無しさん@お腹いっぱい。2012/07/15(日) 13:30:12.88
そもそもcsh自体がBSD発祥なんだっけ
0274名無しさん@お腹いっぱい。2012/07/15(日) 17:10:34.35
宗教上の理由でbashが使えないから
0275名無しさん@お腹いっぱい。2012/07/15(日) 20:13:13.73
bashはGNUライセンスだからなんじゃないの?
0276名無しさん@お腹いっぱい。2012/07/15(日) 20:53:59.04
パブリック
0277名無しさん@お腹いっぱい。2012/07/16(月) 02:01:54.23
>>273
Bill Joy先生の作品ですよ。
ジョブコントロール関係のカーネル拡張も。
他にはviとか、page単位の仮想記憶とか。
近代的なUNIXカーネルの創始者の一人。

cshスクリプトの是非については、
csh programming considered harmful.を読めばいい。
0278名無しさん@お腹いっぱい。2012/07/16(月) 16:33:07.10
Linux、bashを使用しています
シェルスクリプトを書いたのですが、
そのスクリプト(***.sh)が入っているディレクトリと入っていないディレクトリで
挙動が変わってしまいます
これはもともとそういう仕様?なのでしょうか
それとも書いたスクリプトに間違いがあってこうなっているのでしょうか
すみませんがアドバイス宜しくお願いします
0279名無しさん@お腹いっぱい。2012/07/16(月) 16:57:50.70
相対パスつこうてるんやろ
0280名無しさん@お腹いっぱい。2012/07/16(月) 17:05:30.38
カレントディレクトリという概念を理解してない。
カレントディレクトリはスクリプトの属性ではなくプロセスの属性。
0281名無しさん@お腹いっぱい。2012/07/16(月) 17:14:22.95
>>279
パスはその都度引数で指定する仕様で
絶対パスで指定しているのでそんなことはない、と思うのですが…
>>280
カレントディレクトリで、なおかつそのスクリプトが入ってるときにしか
動作しない、ということでしょうか…?
すみません、浅学でしてLinuxに関しては学び始めたばかりなのです
0282名無しさん@お腹いっぱい。2012/07/16(月) 17:17:14.41
pastebinか何かにそのスクリプトを晒しなさい
http://pastebin.com/
0283名無しさん@お腹いっぱい。2012/07/16(月) 17:23:10.76
別にLinuxだけの話じゃ無さそうだな
0284名無しさん@お腹いっぱい。2012/07/16(月) 17:24:30.42
>>282
これであってますでしょうか…?
http://pastebin.com/5CHY53XG
0285名無しさん@お腹いっぱい。2012/07/16(月) 17:27:48.35
付け足しですが、こちら「for FILE in _______________」となっていて
inの後ろを穴埋めしろ、という課題なのです
拡張子はtexやdviに限る必要はありません
ただし何かしらの文字列を含まないファイルを
一括で削除するスクリプトを作りましょう、ということなのですが…
0286名無しさん@お腹いっぱい。2012/07/16(月) 17:30:36.51
ls "$DIR"の間違いだろ。
grepのところもegrep -v ".tex$|.dvi$"くらいの意図か?
0287名無しさん@お腹いっぱい。2012/07/16(月) 17:33:28.31
>>286
それも試したんですが削除しますか?と聞かれるファイルがひとつしかないのです>"$DIR"
実際にはもっとたくさんあるんですが…
grepのは特定の文字列を含まないファイルをリストしたいという意図です
".tex$|.dvi$"←これのように「|」を入れないと2つの文字列を除外することはできないのでしょうか?
0288名無しさん@お腹いっぱい。2012/07/16(月) 18:39:06.72
grep -v".txt .dvi" は
何か1文字、t、x、t、スペース、何か1文字、d、v、i
というひとつながりの文字列がある行を除外する。
0289名無しさん@お腹いっぱい。2012/07/16(月) 18:40:30.30
texだたハズカシー

0290名無しさん@お腹いっぱい。2012/07/16(月) 18:52:03.84
>>285
>「for FILE in _______________」となっていて
>inの後ろを穴埋めしろ、という課題なのです

変な課題w

課題関係なしなら
↓で、grep使わずにできる。(lsも使わずに内部コマンドだけで)

cd "$DIR"
for FILE in *
do
case $FILE in
*.tex|*.dvi);;
*) rm -i "$FILE";;
esac
done
0291名無しさん@お腹いっぱい。2012/07/16(月) 19:39:40.80
無理矢理「for FILE in _______________」の中に別のfor文入れちゃえ。
正常に動くよ。

for FILE in `for f in *; do case $f in *.tex|*.dvi)echo "$f";;esac;done`
do
以下略
0292名無しさん@お腹いっぱい。2012/07/16(月) 22:01:42.45
>>288
なるほど…ありがとうございます
検索条件に.○○はダメだったんですね

>>290
正直別なところもいじらせてほしいですorz
スクリプト例もありがとうございます、参考にさせて頂きます

>>291
その手がありましたね…!>for文入れる
有り難うございます、これで行けると思います


長々とどうもすみませんでした
アドバイスしてくれた皆様ありがとうございました
0293名無しさん@お腹いっぱい。2012/07/16(月) 22:05:25.55
あのさぁ…ま いっか
0294名無しさん@お腹いっぱい。2012/07/16(月) 22:27:57.35
ls に絶対パス出力するオプションあるんじゃねーのと思ったらそんなことはなかった
find 使えばいくね?
find "$DIR" -maxdepth 1 -type f

ていうかHOME以下のファイル消すスクリプトとかこえーな
0295名無しさん@お腹いっぱい。2012/07/17(火) 00:37:58.25
>>291 面白w
find -E "$DIR" -type f -regex '.*\.(conf|wrapper)$' -delete
でいいのに

制約があるので>>291よりおふざけ感が低減される
for FILE in `find -E . -type f -regex '.*\.(conf|wrapper)$'`
do
以下略
0296名無しさん@お腹いっぱい。2012/07/17(火) 00:41:30.49
>>295
find -E "$DIR" -type f -regex '.*\.(tex|div)$' -delete
for FILE in `find -E "${DIR}" -type f -regex '.*\.(tex|div)$'`
0297名無しさん@お腹いっぱい。2012/07/17(火) 03:06:32.79
>>292
grep -v -e .tex -e .dvi
egrep -v ".tex|.dvi"

12行目あたりに echo $FILE いれるとか、内容をチェックしてみる癖はつけたほうがいいぞ。
0298名無しさん@お腹いっぱい。2012/07/17(火) 07:26:54.87
>>293
何よ。
0299名無しさん@お腹いっぱい。2012/07/17(火) 15:54:04.83
検索語がまずいのか調べても分からないので、教えてください。

デスクトップ環境(X Window上)のターミナルエミュレータか、
sshログインしたときなどのコンソール上かで、シェルスクリプトの挙動を変えたいのですが、
どのような工夫をすればよいか、何で条件分岐すればよいのか思いつきません。
お願いします。
0300名無しさん@お腹いっぱい。2012/07/17(火) 16:02:19.68
ターミナルエミュレータからsshログインしたときは?
0301名無しさん@お腹いっぱい。2012/07/17(火) 16:03:00.94
>>299
> デスクトップ環境(X Window上)のターミナルエミュレータか、

DISPLAY環境変数が設定されていれば。

> sshログインしたときなどの

SSH_CLIENT環境変数が設定されていれば。

> コンソール上かで、

ttyコマンド使えばこれも判別できる。
0302名無しさん@お腹いっぱい。2012/07/17(火) 16:13:55.08
すみませんが詳しい方のみ回答をお願いします
0303名無しさん@お腹いっぱい。2012/07/17(火) 16:22:19.33
>>301
ありがとう。DISPLAYはsshログインしたときでもたまに設定するので使えません、
ttyコマンドの出力を使う方法は、仮想コンソールだと区別が付きそうですが、
sshログインした場合は区別が付きませんでした。
SSH_CLIENTを見てみました。
SSH_CLIENT, SSH_TTY, SSH_CONNECTIONはsshログインしたときのみに設定されるようなので、
これを使って条件分岐することにします。
ご教示感謝します。>>300さんもありがとうございました。
0304名無しさん@お腹いっぱい。2012/07/17(火) 16:49:06.86
余談だが、
コンソールってのは本体に物理的に接続されてるキーボード/ディスプレーのことな。
パイプオルガンの鍵盤の付いた演奏台由来の名前。
パイプオルガンの本体はパイプだから。
0305名無しさん@お腹いっぱい。2012/07/17(火) 18:45:11.74
先生!ターミナルとコンソールってどう違うんですか?!
0306名無しさん@お腹いっぱい。2012/07/17(火) 18:51:03.45
コンソールはホスト本体の画面とキーボード。
ターミナルはあくまでも別の機械からのリモートログイン。

xtermなどのことをターミナルと呼んでしまうこともあるが、
正しくはターミナルエミュレータなので、純粋なターミナルとは異なる。
0307名無しさん@お腹いっぱい。2012/07/17(火) 19:32:14.58
>>306
本体に接続されたディスプレイとキーボードを使うのに「ターミナル(遠隔操作端末)エミュレータ」だから直感的に混乱するよね。
0308名無しさん@お腹いっぱい。2012/07/17(火) 23:13:42.44
/dev/pts (/dev/pty), /dev/tty, /dev/console
とかのデバイスによって、コンソール、端末(ターミナル、物理端末、制御端末、広義のコンソール等)、
疑似端末(仮想端末、仮想ターミナル、シュードターミナル等)が分かれる。(はずです。多分。)

カーネルをロードしてinit起動してるやつがコンソール
LinuxとかでAlt+2とかで切り替えられる奴がターミナル
他が疑似端末

でOK。(だと思う。多分。)
コンソールだけちょっと特別で、Ctrl+CとかCtrl+Zみたいな制御ができず、あとデーモン類とか
端末持たないプロセス(ps -efとかで見たとき端末のカラムが?になってるプロセス)が標準出力の代わりに/dev/consoleにメッセージ出してきたりする。

まぁ組み込み系の人以外、端末、ターミナル、コンソールをあまり区別せずに使う場合のが多いし、
大抵はそれであまり実害は出ないのでちゃんと覚えなくても良いと思う。
0309名無しさん@お腹いっぱい。2012/07/18(水) 00:05:24.12
>>308
> コンソールだけちょっと特別で、Ctrl+CとかCtrl+Zみたいな制御ができず

スレ違いな上に出鱈目。最低だ。
0310名無しさん@お腹いっぱい。2012/07/18(水) 09:45:01.28
うん、ムチャクチャにもほどがある。

>大抵はそれであまり実害は出ないのでちゃんと覚えなくても良いと思う。

自分がちゃんと覚えていないなら、それをわきまえて黙ってろ。
0311名無しさん@お腹いっぱい。2012/07/18(水) 10:01:19.01
端末のことを英語でターミナルって言うのも知らないんだろな。
端末とターミナルを別物のように説明してるしw
0312名無しさん@お腹いっぱい。2012/07/18(水) 11:07:30.77
>>308がフルボッコにされてるから読んでみたけど
たしかにこれはひどいな
0313名無しさん@お腹いっぱい。2012/07/18(水) 11:13:48.49
>>309
古典/bin/shなrootログインでしかコンソールを触ったことがなかった爺と思われ。
SunOS辺りか?
0314名無しさん@お腹いっぱい。2012/07/18(水) 13:07:04.12
cp file1 /mnt/file2 &
みたいにやっておいて、
mv file2 file3
した場合、最初のコピーにmvが追いついた時ってどうなるの?
0315名無しさん@お腹いっぱい。2012/07/18(水) 13:13:20.91
>>314
この場合のmvは同一ファイルシステムだから、
実際にはrename(2)が呼ばれるだけで、
cpでコピー途中かどうかに関係なくファイル名だけがリネームされる。
また、リネーム後もcpはオープン済みのファイル記述子でコピーを続けるので
コピーも無事file3に対して行なわれる。
よって無問題。
0316名無しさん@お腹いっぱい。2012/07/18(水) 13:18:37.48
>>315
あ、ごめんなさい、
mv /mnt/file2 file3
でした。この場合も問題なしですか?
0317名無しさん@お腹いっぱい。2012/07/18(水) 13:24:13.19
>>316
異なるファイルシステムの場合は
mvが追い付いてしまったらそこでEOFとみなされるので
file3は後半が切れた短いファイルになる。

mvによるコピー後、mvはfile2をunlink(2)する。
cpはファイル記述子でコピー中なので、unlink(2)に気づかずにfile2にコピーするが、
file2はそのまま消滅する。

よって問題あり。
0318名無しさん@お腹いっぱい。2012/07/18(水) 13:33:12.07
>>317
ありがとうございます!
0319名無しさん@お腹いっぱい。2012/07/18(水) 15:15:13.34
最近はこういう自演が流行ってんの?
0320名無しさん@お腹いっぱい。2012/07/18(水) 15:16:56.45
自演じゃないよ。
0321名無しさん@お腹いっぱい。2012/07/18(水) 22:31:50.13
unlink相当の事をした時にどうなるかは、使ってるファイルシステムに依るんじゃないかなぁ
0322名無しさん@お腹いっぱい。2012/07/19(木) 00:40:03.43
UNIX由来のファイルシステムで判例ある?
0323名無しさん@お腹いっぱい。2012/07/19(木) 08:23:00.94
>>321
いや。

OSがUNIXなら、たとえFATファイルシステムであっても
unlinkの挙動は同じになってるよ。
(unlink後もfile descriptorで書き込み等可能、プロセス終了で実体削除)
0324名無しさん@お腹いっぱい。2012/07/19(木) 09:34:12.27
ふーん、どうやってるんだろう。UNIXのファイルシステムと違ってunlink
して(ディレクトリエントリから削除)実体を解放しない(FATには残ってい
る)状態は、ファイルシステムとして壊れた状態なんだけど。
0325名無しさん@お腹いっぱい。2012/07/19(木) 10:50:31.77
どうやってるんだろうとか言ってないで自分で試せよ。
0326名無しさん@お腹いっぱい。2012/07/19(木) 11:54:23.00
>>323
NFSだと違うくね?
0327名無しさん@お腹いっぱい。2012/07/19(木) 11:55:45.52
>>324
全員closeするまでunlinkされないよ
0328名無しさん@お腹いっぱい。2012/07/19(木) 12:10:15.79
>>327
ディレクトリからunlinkはされるけど
closeするまで実体は隠れたところに残ってる、が正しい
0329名無しさん@お腹いっぱい。2012/07/19(木) 12:13:46.17
それunlinkじゃなくてrenameじゃね?
0330名無しさん@お腹いっぱい。2012/07/19(木) 12:14:14.27
ねぇ、この照れ隠しっていつまで続くの?
0331名無しさん@お腹いっぱい。2012/07/19(木) 12:24:14.27
>>329
いや、renameじゃなくてunlink。ディレクトリ上にはどこにも存在しない。
0332名無しさん@お腹いっぱい。2012/07/19(木) 13:47:29.51
>>326
NFSだとサーバ実装にもよるんだけど、
オープンされてるファイルをunlinkすると.nfsXXXというパス名にして、
ls -aなら見えるタイプの実装があるね。
本家のSunOSがそうだった。
今時の商用NASは見えないのが多い。
0333名無しさん@お腹いっぱい。2012/07/19(木) 17:24:45.23
>>324
ファイルシステムとして壊れた状態かどうかはOS側の解釈に過ぎない。
unlinkして実体を解放しないまま何らかの原因で強制ummountされたら、
fsck_msdosfs(FreeBSD)またはfsck.msdos(Linux)で修復できる。

通常のUNIXのファイルシステムのfsckの場合ととくに変わらない。
0334名無しさん@お腹いっぱい。2012/07/19(木) 18:18:26.99
>>332
最近のLinuxのNFSサーバも同じ挙動をする
NFSv3かv4の仕様なんだと思ってた
0335名無しさん@お腹いっぱい。2012/07/19(木) 18:28:40.79
いや.nfsXXXは仕様じゃない。(NFS3以降はRFCになっているので仕様が読める)
NFSは仕様上、ファイルサーバがクラッシュした後、再起動すれば、
クライアントがオープンしていたファイルについて問題なく処理を続行できる必要がある。
そのため、回収されてしまわないようピン止めしているだけ。
商用NASでは.nfsXXXではなく不揮発メモリ上の内部DBに格納して保存している。
0336名無しさん@お腹いっぱい。2012/07/19(木) 20:42:29.05
>>331
ディレクトリから消えるだけっしょ
0337名無しさん@お腹いっぱい。2012/07/19(木) 20:57:26.28
>>336
お前は何を言ってるんだ?
0338名無しさん@お腹いっぱい。2012/07/19(木) 21:11:53.31
以上、知ったかの >>324 君の照れ隠し&自爆をお送りしました。
十分お楽しみいただけましたか?

それでは次の方どうぞ
0339名無しさん@お腹いっぱい。2012/07/19(木) 21:46:23.95
↑リフレクト!
0340名無しさん@お腹いっぱい。2012/07/20(金) 23:28:32.13
cat file1 file2 ってやると file1 のあとに file2 がつながり以下の様になりますが
a
b
c
1
2
3
下のようになるコマンドってありますか
a1
b2
c3
0341名無しさん@お腹いっぱい。2012/07/20(金) 23:31:16.63
>>340
paste
0342名無しさん@お腹いっぱい。2012/07/20(金) 23:31:53.26
つ join
0343名無しさん@お腹いっぱい。2012/07/21(土) 08:02:00.38
>>341 の正解の後で 間違いを書き込む >>342
しかも「つ」とか恥ずかしい文字使ってwww
0344名無しさん@お腹いっぱい。2012/07/21(土) 08:09:55.50
>>340
補足すると、デリミタを空文字にするようにオプション付けてね。

paste -d '' file1 file2
0345名無しさん@お腹いっぱい。2012/07/21(土) 15:59:34.92
>>341>>344
ありがとうございました、望み通りのものです
0346名無しさん@お腹いっぱい。2012/07/21(土) 16:48:21.35
cpuの使用量を確認するのにtop/psを利用しているのですが、
ppid指定で子プロセスの累積値を出すオプション等ありますか?

軽いプロセスをループで呼び続けてるものがcpu%でソートした場合
浮かんで来ないというのを解決するのが目的です

psを利用してppid指定で自前っていうのをやってみようかと思いましたが
それだと、目的の物がpsに出てくる間隔で呼び続ける必要になりそうなので
「軽いプロセスを呼び続ける」ものを監視したいっていう目的に反してるなと・・
0347名無しさん@お腹いっぱい。2012/07/21(土) 21:03:14.45
>>346
Linuxなら、psに S オプションを付けると子プロセスのCPU時間が親に加算されるけど。
0348名無しさん@お腹いっぱい。2012/07/21(土) 21:28:04.70
xinitを打つと左上に白のシェルが出てプロンプトは実行できるようですが、
マウスが反応しません。あ、マウス自体は動いてるんですがクリックしても
何もなりません。タスクバーとかはどうやって出すんですか?
0349名無しさん@お腹いっぱい。2012/07/21(土) 21:36:58.32
xinitじゃなくてstartxでどうよ?
というかシェルスクリプトか?
0350名無しさん@お腹いっぱい。2012/07/21(土) 23:15:22.59
dwm入ってる?
0351名無しさん@お腹いっぱい。2012/07/22(日) 03:02:09.25
>>348
gnomeとかcdeとかのウインドウマネージャやデスクトップ環境を起動しないと使えないよ。
0352名無しさん@お腹いっぱい。2012/07/23(月) 21:56:01.86
すみませんが詳しい方のみ解答をお願いします。
0353名無しさん@お腹いっぱい。2012/07/23(月) 22:11:18.53
スレちがいの戯言は放置するスルーカを習得しよう。
0354名無しさん@お腹いっぱい。2012/07/23(月) 22:21:56.21
http://blogimg.goo.ne.jp/user_image/4e/fe/fff5e143159a2acaa462eb8ce1fa1977.jpg
0355名無しさん@お腹いっぱい。2012/07/24(火) 00:34:24.03
もしかして:ヤリイカ
0356名無しさん@お腹いっぱい。2012/07/24(火) 00:36:18.47
いや、モンゴウイカじゃね?
0357名無しさん@お腹いっぱい。2012/07/24(火) 23:56:17.62
>>353
xinitrcを書きたい。それってシェルスクリプトみたいなもんだろ?
ってのがいいたいんじゃないの?352は。
ちがうのかなあ。
0358名無しさん@お腹いっぱい。2012/07/25(水) 03:21:11.56
>>357
352 はよく有るコピペだろ。
「質問者のくせに偉そうに!」を引き出す為の、第三者によるあおりだからスルー推奨。
0359名無しさん@お腹いっぱい。2012/07/25(水) 21:35:30.31
>>358
おう、そうか。スルーしよう。ありがとう。
0360名無しさん@お腹いっぱい。2012/07/27(金) 20:48:33.81
標準出力はそのままに、標準エラー出力だけgrepかけたいとか
思うんだけど、どうしたらいいでしょか
0361名無しさん@お腹いっぱい。2012/07/27(金) 20:52:17.05
>>360
((コマンド 2>&1 1>&3) | grep hoge) 3>&1
0362名無しさん@お腹いっぱい。2012/07/28(土) 03:58:28.71
>>361
なるほど
いろいろできるもんだな
0363名無しさん@お腹いっぱい。2012/07/28(土) 07:49:40.42
興味本位で聞いただけかよ。無礼な奴だ。
0364名無しさん@お腹いっぱい。2012/07/28(土) 07:56:32.30
アスペさんちっす
0365名無しさん@お腹いっぱい。2012/07/28(土) 09:41:50.79
>>361
サブシェルが1個無駄です。

(コマンド 2>&1 1>&3 | grep hoge) 3>&1

---
サブシェルなしにもできます。

exec 3>&1
コマンド 2>&1 1>&3 | grep hoge
0366名無しさん@お腹いっぱい。2012/07/28(土) 10:07:31.29
>>365
なるほど
いろいろできるもんだな
0367名無しさん@お腹いっぱい。2012/07/28(土) 10:11:09.01
>>366
若ハゲチッス
0368名無しさん@お腹いっぱい。2012/07/28(土) 11:36:30.41
すみませんが詳しい方のみ解答をお願いします。
0369名無しさん@お腹いっぱい。2012/07/28(土) 11:45:46.68
>>366
興味本位で聞いただけかよ。無礼な奴だ。
■ このスレッドは過去ログ倉庫に格納されています