トップページ⇒linux
988コメント336KB

シェルスクリプト総合@LINUX Part3

■ このスレッドは過去ログ倉庫に格納されています
0001login:Penguin2007/07/10(火) 23:17:13ID:qGthZdME
UNIX板のスレを見ている方も多数おられるかと思いますが、
まあそれはそれとして、BASHウゼーとか言われる心配なく
平和にLINUX的スクリプト談義しましょうよ。

初めての自作スクリプト、自信ないから見てください。な初心者から
トリッキーな技を駆使した作品を披露したい、蘊蓄を語りたい上級者まで
いろいろな人に参加して頂けると嬉しいです。

perlやらPythonやらの話が混ざっても良いんでない?

【sed】シェルスクリプト総合@LINUX Part2【awk】
http://pc11.2ch.net/test/read.cgi/linux/1154578200/
http://pc8.2ch.net/test/read.cgi/linux/1121994321/

>>2-5あたりに色々と。
0002login:Penguin2007/07/10(火) 23:18:45ID:qGthZdME
関連スレ
おまいら! sed  の使い方教えて下さいm(_ _)m@linux板
http://pc11.2ch.net/test/read.cgi/linux/1067815570/
【Shell】どのシェル使ってる?【Script】@LINUX板
http://pc11.2ch.net/test/read.cgi/linux/1067330754/
シェルスクリプト総合 その8
http://pc11.2ch.net/test/read.cgi/unix/1171517324/
sed@UNIX板
http://pc11.2ch.net/test/read.cgi/unix/1085730992/
2ちゃん画像落としまくりスクリプト@UNIX板
http://pc11.2ch.net/test/read.cgi/unix/1003833552/
連番のH画像/動画を一気にダウンロードする2
http://pc11.2ch.net/test/read.cgi/unix/1135533382/

ログを読みたい人はこちら
http://makimo.to/cgi-bin/search/search.cgi?q=%83V%83F%83%8B%83X%83N%83%8A%83v%83g&;andor=OR&sf=0&H=&view=table&all=on&shw=
0003login:Penguin2007/07/10(火) 23:20:21ID:qGthZdME
参考リンク
bashで始めるシェルスクリプト基礎の基礎 @IT
http://www.atmarkit.co.jp/flinux/rensai/theory08/theory08a.html
シェルスクリプト(Bash)入門 CYBERAM Documents Project
http://cyberam.dip.jp/linux_command/shellscript.html

IBM developerWorks
実例でわかるsed
http://www-06.ibm.com/jp/developerworks/linux/010202/j_l-sed1.html
http://www-06.ibm.com/jp/developerworks/linux/010216/j_l-sed2.html
http://www-06.ibm.com/jp/developerworks/linux/010223/j_l-sed3.html
実例でわかるawk
http://www-06.ibm.com/jp/developerworks/linux/010330/j_l-awk1.html
http://www-06.ibm.com/jp/developerworks/linux/010413/j_l-awk2.html
http://www-06.ibm.com/jp/developerworks/linux/010622/j_l-awk3.html
コマンドラインからのグラフィックス操作
http://www-06.ibm.com/jp/developerworks/linux/031031/j_l-graf.html
洗練されたPerl: MP3とPerlで遊ぶ
http://www-06.ibm.com/jp/developerworks/linux/040319/j_l-cpmp31.html
http://www-06.ibm.com/jp/developerworks/linux/040402/j_l-cpmp32.html
0004login:Penguin2007/07/14(土) 09:56:17ID:42ZxWwqP
EUCで入力された文字列をShiftJISに置き換える方法ってありませんか?
0005login:Penguin2007/07/14(土) 11:17:49ID:29sQfd47
>>4
nkf とか iconv とか。
0006login:Penguin2007/07/14(土) 22:31:28ID:Lb+uQxni
シェルスクリプトの引数にワイルドカードを渡すと、
該当するファイルがファイルシステム上にある場合はそのファイルが変わりに
引数として渡されるみたいですが、ワイルドカード自体を取得したいのです。
何か方法はないでしょうか?
ちなみにダブルクォーテーションをつければ展開されないのは知っていますが、面倒で。。

(例)
$ test.sh *.txt
$ echo $1
とするとカレントにあるXXX.txtを表示するのではなく
「*.txt」を表示したいのです。
0007login:Penguin2007/07/14(土) 22:53:16ID:29sQfd47
>>6
呼ばれるスクリプトの側でなんとかしたいってことなら
無理だよ。
0008login:Penguin2007/07/14(土) 23:13:50ID:Lb+uQxni
>>7
そんな気はしていましたが、そうですか。。
残念です。
0009login:Penguin2007/07/14(土) 23:26:42ID:29sQfd47
呼ぶシェル側でなんとかするなら
$ set -o noglob
$ test.sh *.txt
とか。
0010login:Penguin2007/07/15(日) 05:00:56ID:OzInTFfn
>>6
test.sh '*.txt'
(シングルコーテーションならてんかいされないはず)
0011login:Penguin2007/07/15(日) 11:22:44ID:oGW94xFn
>2
おまけの関連スレ

シェルスクリプト相談室
http://pc11.2ch.net/test/read.cgi/tech/1112553783/
awkについて語るスレ $2
http://pc11.2ch.net/test/read.cgi/tech/1172242542/
0012login:Penguin2007/07/15(日) 12:37:56ID:llPpP8sT
>>8
よく仕様がわからんが、スクリプトの多段階呼び出しで展開されたくないんだったら、
$ test.sh @.txt
みたいに、擬似ワイルドカード指定指定しておいて
使ううときに、
fs=`eco $1 | sed 's/@/*/'`
echo $fs
0013login:Penguin2007/07/15(日) 22:24:45ID:ZpXAubZ6
>>6
complete とかで、補完のルールを作れるんじゃないか?

bashで補完スレ [UNIX板]
http://pc11.2ch.net/test/read.cgi/unix/1013019416/
0014login:Penguin2007/07/16(月) 12:28:16ID:MK2VLXxK
すみませんちょっとヘルぽ

/homeの中にある複数のファイル・ディレクトリーをrm -rf したいのですが
/home/hogeとlost+found だけは消したくないので

何とかそれ以外を消す方法をご教示頂きたいのですが
おしえてたもれ
0015login:Penguin2007/07/16(月) 13:05:49ID:fC+1yCpQ
>14
shell script関係ないが、lsでリストとって、リストから削除したくないファイル・ディレクトリを削除し、
その後 rm -rf `cat 〜` なんかするのが間違いなくて確実だとおもー。
0016login:Penguin2007/07/16(月) 13:13:37ID:hTbLQxc+
>>14
bashだったら、GLOBIGNORE="hoge:lost+found" に賭けてみたまえ
0017login:Penguin2007/07/16(月) 13:32:26ID:xW/HZyHj
/home/hogeとlost+foundに書き込み禁止属性をつけてから一気に rm -rf
その後戻せばいいのでわ
0018login:Penguin2007/07/16(月) 21:41:14ID:J/qZmNrt
>>14?!(xxx|yyy)
0019login:Penguin2007/07/17(火) 03:37:44ID:I2w4SVYd
awk の出力をコマンドとして実行したいでつ。
どうやればいいでつか?
0020login:Penguin2007/07/17(火) 10:02:57ID:ZxaQD0ZF
awk ... | sh
0021login:Penguin2007/07/18(水) 08:18:48ID:Dw+iZryL
>>5
遅くなりましたが、ありがとうございます。
試してみたいと思います。
0022login:Penguin2007/07/18(水) 16:34:40ID:cvC9pUm6
>>20
ありがとう。
できまちた。
0023login:Penguin2007/07/19(木) 07:38:39ID:gg1Is+TJ
>>16 >>17 >>18 
�dクス

とりあえず、試験機でゴリゴリしてみます
0024login:Penguin2007/07/19(木) 07:41:44ID:gg1Is+TJ
あ、>>15 も�dクスです
その方法でやってみたいと思います
0025login:Penguin2007/07/20(金) 01:54:45ID:bZea7ZdA
スクリプトに実行時間制限を設けたいんですが、いい方法はないですか?
厳密さは求めていません。暴走防止程度です。
(因みにLinux初心者のプログラマです、あまり複雑な概念は未だ理解できていないと思います。

今は大体こんな感じでやろうとしています、
(sleep 10; kill $$)&
時間制限を設けたいコマンド

これだと、時間内に終了しなかったとき、スクリプトのみ終了し、実際に終了させたいコマンドは生き残ります。
時間内に終了したときにkillさせないために最後に kill `jobs -p` すると「(sleep 10; kill $$)&」は終了しますが、sleepだけが残ります(自然消滅はする
だからといって kill 0 とするとこのスクリプトの呼び出し元まで死んでしまいます。

プロセスを kill するときに、その子も殺せればいいんですが如何でしょうか。
0026login:Penguin2007/07/20(金) 02:25:54ID:zucTG+iZ
>>25
ps --ppid とか pstree -p とかで
子の pid を調べれば
kill できると思う。
0027login:Penguin2007/07/20(金) 07:34:06ID:0zbWXhyq
ulimit -tはだめ?
CPU使った時間になっちゃうけど。
0028login:Penguin2007/07/20(金) 13:11:40ID:VbE5NJtk
killのman見ればprocess groupを殺す方法書いてあるだろうに。
0029login:Penguin2007/07/22(日) 01:17:56ID:MkzMxIYh
>>26
pstree -p からpidだけ取り出す方法が分かりません。
ps --ppid の再起で殺すようにしてみましたが思い通り動いてくれません。
間違えている可能性は大いにありますが。

>>27
CPU時間でも構いません。寧ろその方が良いかもしれません。
ありがとうございます。調べてみます。

>>28
でしょうね。
0030login:Penguin2007/07/24(火) 02:36:44ID:TdZoIfh3
>>29

% pstree -p 親PID
親cmd(親PID)-+-子cmd(子PID)

と表示されるんだから、

% pstree -p 親PID | perl -nle '/親PID\)[^\(]+\((\d+)\)/ && print $1'
子PID

とならないかな?awkでもsplitを使えば同じようにできると思う。
そもそもperl使うならpstreeもkillも内部で呼び出せば済むけど。
それ以前にプロセスをアレコレする関数かmodがあるんだろうな...
0031login:Penguin2007/08/04(土) 23:01:23ID:prsNz29A
awkの区切り文字に'|'を指定するにはどうすればいいですか
awk -F'|'
ではパイプとみなされてしまいます
0032login:Penguin2007/08/04(土) 23:37:42ID:dhi36EzE
やってみた。
% echo 'a|b|c' | gawk -F'|' '{print $2}'
b
0033login:Penguin2007/08/05(日) 03:46:06ID:a+1tcmkL
>>31

-F'[|]' とか
0034login:Penguin2007/08/05(日) 23:10:51ID:ftJrAaPL

非rootのアカウントからシェルを実行して
規定のHDDをマウントしたいと思っています。
問題は非rootなのでmountの実行権が無い点です。

sudo は設定方法がよく分からないので、
もちょっと簡単なやり方ないかと探しているのですが
何かよい方法ないもんでしょうか?

スクリプトの中でrootでログインして、そのまま
実行してほしい。(passwd入力はOK)

ちなみにSuSE 10.2を使ってます。
0035login:Penguin2007/08/05(日) 23:39:27ID:YQ3bjemY
>>34
sudo の設定くらいわかれ。
そんなに難しくないよ。
0036login:Penguin2007/08/06(月) 01:50:25ID:xhWrZGpQ
sudo -u USER /dev/hd ...

いかん、だるい。
0037login:Penguin2007/08/06(月) 02:18:34ID:AKmvozj+
>>34
/etc/fstabの規定のHDDのエントリ内に user というオプションを書いておけば、
そこは一般ユーザでもmount/unmountできるようになる。
もちろんこの場合、mountコマンド自体のxビットは、一般ユーザが実行できるように
設定する必要がある。
0038login:Penguin2007/08/06(月) 22:17:00ID:LTHEPNn8
テキストファイルが2つあると仮定して、(a.log、b.txt)
a.logはソフトのログファイル。
b.txtはerror、badなどの複数行の文字列が入っています。

で、a.logに対して、b.txtの中を一行ずつgrepさせたいときはどうすればいいの?

↓のようにしたい。b.txtは50行程度の行数があるとする。
grep -i error a.log
grep -i bad a.log
grep -i ...... a.log
などをしたい。

0039login:Penguin2007/08/06(月) 22:32:01ID:kQOiX48t
$ cat b.txt | while read keyword; do grep -i "$keyword" a.log; done

bshしか知らね。
0040login:Penguin2007/08/06(月) 22:50:29ID:q2/C5Z+3
grep -f b.txt a.log
0041login:Penguin2007/08/09(木) 03:57:05ID:q+NJZ5PJ
スクリプトの中から、
スクリプト自身のパスを知るにはどうすればいいですか?
0042login:Penguin2007/08/09(木) 06:28:33ID:EHaDR+6/
echo $0
0043login:Penguin2007/08/09(木) 08:01:28ID:NwjhxE+f
>>42
http://www.nurs.or.jp/~asada/FAQ/UNIX/section4.4.html
0044login:Penguin2007/08/09(木) 11:34:05ID:EHaDR+6/
>>43
俺? $0で十分だと思うけど?
0045login:Penguin2007/08/09(木) 21:51:00ID:8UsjPRp6
うわ。あさたくの文章、久しぶりに見た。
0046login:Penguin2007/08/10(金) 18:42:50ID:hRezB52r
こんなの作った。

#!/bin/sh

for i in "$@"
do
a="$(echo $i | nkf -w)"
mv $i $a
done

convmv は元の文字コードを指定しなきゃならないのが面倒なので。
良かったらどぞ。
0047462007/08/10(金) 18:44:30ID:hRezB52r
書き忘れたので一応。
./myconvmv.sh *
とかで使える。
0048382007/08/11(土) 02:02:30ID:h4twNLWe
>>39
>>40
できました。神様ありがとう。
0049login:Penguin2007/08/15(水) 18:16:19ID:oxw3opBU
・ファイルを指定フォルダ内へコピー
・同名ファイルが存在する場合は、
既に存在するファイル名を「ファイル名.1」へ変更し、
既にファイル名.1が存在しているのであれば、それをさらにファイル名.2へ変更し、、、(繰り返し)

というコピーシェルスクリプトがほしいんですが、
簡単な記述方法などがあったらおながいします。
0050login:Penguin2007/08/15(水) 18:22:48ID:vI6OWTR9
>>49
自分ではどこまでできたの?
0051492007/08/15(水) 18:30:05ID:oxw3opBU
シェルスクリプト自体ほとんど作成経験がないので、
mv とかのオプションでそんな機能ないかな〜と
調べている程度の状態です。
--------------------------------------------------
・同名ファイルが存在する場合は、
既に存在するファイル名を「ファイル名.1」へ変更し、
既にファイル名.1が存在しているのであれば、それをさらにファイル名.2へ変更し、、、(繰り返し)
--------------------------------------------------
この部分を数行で教えていただけるとありがたいでつ。
ループ処理が必要になるのはなんとなく予想がつくのですが、、、
0052login:Penguin2007/08/15(水) 18:34:51ID:vI6OWTR9
>>51
ファイルが何番まであるかを先にチェックして
番号大きい方から順に mv してくのが楽かな。
[ とか expr 使え。
0053login:Penguin2007/08/15(水) 23:30:14ID:BP+0zqca
番号をrotateすることに大した意味がないことに気付き、--backupオプションとかで安易に済ます。
そんな自堕落な道を私は選びました。
0054login:Penguin2007/08/16(木) 07:16:56ID:D/eLf54Q
ディレクトリにあるすべての*.cファイルを
全部*.cppにするにはどういう風に書いたらよいのでしょうか?
mv *.c *.cpp
としてみましたがだめでした
どなたかお知恵を...
0055login:Penguin2007/08/16(木) 07:57:42ID:Uoi1O64b
rename コマンドで出来そうな気がする。
0056login:Penguin2007/08/16(木) 10:10:37ID:MWEjh3WB
まあそうだけど。シェルスクリプトスレであることだし
for f in *.c; do mv "$f" "${f}pp"; done
0057login:Penguin2007/08/16(木) 13:33:29ID:D/eLf54Q
>>56
Thx,できますた!
0058login:Penguin2007/08/23(木) 16:17:17ID:n9QZBMiJ
flashの動画をダウンロードできる
シェルスクリプトある?
0059login:Penguin2007/08/23(木) 16:36:59ID:lPn22JjI
kurekure厨
0060login:Penguin2007/08/23(木) 16:53:47ID:C+I5hIDu
>>58
普通にwgetでダウンロードすればいいだけでは?
youtubeから簡単に落としたいとかであればyoutube-dlとかが便利。
0061login:Penguin2007/08/24(金) 19:56:13ID:k2Yrnokn
すごく基本的なことなんだろうけど、
いくつかのディレクトリの中にあるファイルのそれぞれの名前を変数に入れたいんだけど、

files=ls dir* | sort

for i in files
do

done

みたいなことは出来ませんか?
要するに標準出力する内容を変数に入れたいだけなんだけど。
0062login:Penguin2007/08/24(金) 20:25:50ID:iKvrTLai
>>61
「コマンド置換」でぐぐってみ
0063login:Penguin2007/08/24(金) 20:43:22ID:k2Yrnokn
>>62
理解できました。どうもありがとりんこです。
0064login:Penguin2007/08/26(日) 16:36:55ID:sDCP6Pah
ファイル一覧だと長大になって溢れるので

 ls ... | sort | while read i; do echo $i; done

とかも定番。
0065login:Penguin2007/08/27(月) 08:44:07ID:mTK43/6/
for i in dir*
do

done

sortを挟むのは良くわからんが、単純にこんなんで済む話じゃね?
0066login:Penguin2007/08/27(月) 18:32:24ID:Vup2OsE3
>>64
それだとlsの時点ですでに溢れる
0067login:Penguin2007/08/27(月) 20:04:00ID:5Y4ThyNx
find DIR -exec (ここで好きなことやれ) \;
0068login:Penguin2007/08/28(火) 00:17:04ID:Gt/lw90m
/home/200708/1200・・・1300・・・1400/と100刻み1800までディレクトリーがあるとして
A.PDFとかファイルが格納されてて

0KB〜150MBなら 「ne-yo」
500〜600MBなら 「OK」 とfile.txtを出力したいのでつが・・・・・
if,thenの繰り返ししかないでしょうかね?
0069login:Penguin2007/08/28(火) 00:58:46ID:is4Tjxw4
なんのバイト数? そのディレクトリ内ファイルの総和?
0070login:Penguin2007/08/28(火) 08:13:17ID:k11zEdxe
こんな感じ?

 $ du -s * | awk '{ print $2," ", ($1 > 10000 ? "ne-yo" : "OK") }'

条件文のところは自分で書き換えてくれ。
0071login:Penguin2007/08/28(火) 09:07:28ID:LHhLJxDo
なるほどdu か。。。。と、>68とはちがう漏れ様が感心しますたーw
0072login:Penguin2007/08/28(火) 14:07:23ID:LHPFC9xp
du 以外だと例えば何が?
■ このスレッドは過去ログ倉庫に格納されています