トップページunix
987コメント278KB

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

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。2012/11/15(木) 18:57:33.11
シェルスクリプトの総合スレです。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。
 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でそれらしい単語による簡単な検索もできます。
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)
・シェルスクリプトのことをシェルってゆーな
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 awkまたはperlの方が適した処理にはそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
□回答者への注意事項:
・シェルスクリプトでの処理方法を質問しているのに、よくわからずに
 「そういうのはperl使いましょう」と回答するのはやめましょう。
 安易にperlに逃げずにシェルスクリプトで処理するのが頭のいいやり方。
前スレ
シェルスクリプト総合 その20
http://toro.2ch.net/test/read.cgi/unix/1339083351/
0660名無しさん@お腹いっぱい。2013/05/21(火) 21:27:11.56
>>659
それはスクリプト「実行後」じゃなくて「実行中」の別シェルだねw
ハイやり直し
0661名無しさん@お腹いっぱい。2013/05/21(火) 22:08:40.79
>>660
俺にとっても正解ではないが、
質問者にとってはこれで充分かもしれず。
0662名無しさん@お腹いっぱい。2013/05/22(水) 01:05:07.75
不十分だろう。
0663名無しさん@お腹いっぱい。2013/05/22(水) 10:31:50.02
. ドットコマンドについて、誰か
0664名無しさん@お腹いっぱい。2013/05/22(水) 10:34:02.64
ドットコマンドの話じゃないよ。普通の実行スクリプトで親シェルをcdする方法の話。
0665名無しさん@お腹いっぱい。2013/05/22(水) 11:10:54.23
もし、親プロセスのカレントディレクトリを変更できる仕組みがあったら
子プロセスを起動するプログラムはガクブルだな。
0666名無しさん@お腹いっぱい。2013/05/22(水) 12:04:13.10
>>665
だから、fork2(FORK_SHARECWD) で作成されたプロセスのみ可能なので安心して。
0667名無しさん@お腹いっぱい。2013/05/22(水) 13:53:26.90
>>663
help .
0668名無しさん@お腹いっぱい。2013/05/25(土) 18:42:48.92!
自分がスクリプトを書く環境で grep に -x オプションがないことが判明したのですが、
grep -x -F -f patlist に相当する処理をしたい場合はどうしたらいいですかね?

とりあえず -F をやめて patlist の各行を ^ と $ で囲む前処理をする? と思ったら、patlist
に含まれうる "." 等をメタ文字として解釈されてはまずいのでした。
grep を入れ直す、perl 等別のスクリプト言語を使う (sed/awk は OK。「言語」かどうかは
ともかく)、キレる等以外でお願いできますでしょうか。
0669名無しさん@お腹いっぱい。2013/05/25(土) 19:33:33.74
>>668
> 自分がスクリプトを書く環境
もしかして Solaris とかだったりする?
0670名無しさん@お腹いっぱい。2013/05/25(土) 19:46:11.01
効率を考えないのであれば
$ comm -12 <(sort patlist) <(sort hoge.txt)
で行けそうな気がする
0671名無しさん@お腹いっぱい。2013/05/25(土) 19:59:14.50
Solarisは grep -x あるぞ。というか、SunOS4の時代からある。
-xないってどこのOSだ?
0672名無しさん@お腹いっぱい。2013/05/25(土) 20:01:59.13
エスパーすると busyboxの grepとか
0673名無しさん@お腹いっぱい。2013/05/25(土) 20:10:20.17
bosyboxの shは、>>670 の named pipeは使えないな
06746682013/05/25(土) 20:56:40.98!
>>669
SUSで-xは規定されてるみたいですし...

>>670
comm もないのです

>>672
正解w


前処理として sed で patlist 内のメタ文字をエスケープすることもちょっと思ったのですが。
s/\([エスケープしたメタ文字リスト]\)/\\\1/g みたいな。ところでメタ文字のリストって?
06756682013/05/25(土) 22:01:26.16!
>>674
おっとっと、文字クラスの中ではエスケープは不要か。

実験してみると [ と ] を指定したいときに [[]]と書くと動かないけど[][]と書くと動くような。
ふむー
0676名無しさん@お腹いっぱい。2013/05/26(日) 05:51:54.34
>>674
-xが使えなくても -wで十分だったりするケースが多いんだけど。
あと、ウチのbusyboxではcommは使えるぞ。<(コマンド)の文法は使えないけど。
06776682013/05/26(日) 09:26:18.70!
>>676
それは元のデータが一行に一個しか単語を含まないとかそういう感じですか?
自分の場合そうではないので...

% echo foo bar | grep -x foo
% echo foo bar | grep -w foo
foo bar
0678名無しさん@お腹いっぱい。2013/05/26(日) 17:26:43.01
メタ文字をエスケープしたパターンを^$でくくればいい。
0679名無しさん@お腹いっぱい。2013/05/26(日) 17:38:36.63
>>678
だから、メタ文字をエスケープすることが難しいって話だろ。
0680名無しさん@お腹いっぱい。2013/05/26(日) 17:48:23.97
sedやawkでやればいい
06816682013/05/27(月) 18:41:29.35!
個々のメタ文字をエスケープしようかな、というのは前の方にに書いたんですが。
ただ正規表現もいろいろあったりするし、その方法はなんか嫌な感じがw
busybox の grep が -x をサポートしない時点で正規表現の方にも一抹の不安がw

まあ仕方ない、grep が扱いそうな正規表現ということで、
sed 's/[][^.$*\]/\\&/g' でいいですかねえ。
でそこに s/^.*$/^&$/ を付けて処理すれば文全体にマッチするパターンになると。
0682名無しさん@お腹いっぱい。2013/05/27(月) 19:11:46.88
awk 'BEGIN{while(getline<"patlist")a[$0]=1}{if($0 in a)print}'
0683名無しさん@お腹いっぱい。2013/05/27(月) 21:50:54.04
結局、環境はbusyboxなの?
0684名無しさん@お腹いっぱい。2013/05/27(月) 23:06:54.89
>>683 節穴
06856682013/05/28(火) 01:03:20.06!
>>682
おおー素晴らしい。そっか連想配列がありましたよね...
元の grep -v の話に合わせるなら !($0 in a) とすると。
0686名無しさん@お腹いっぱい。2013/06/20(木) 10:38:54.93
圧縮されたファイルをハードディスクに展開せずに
読み込ませるシェルスクリプトを書けないでしょうか

今までmkfifoでパイプを利用して
mkfifo input
xz -dc input.xz > input &
fortran.out < input
として必要なinput.xzの個数分コマンドラインで実行をしていました

inputファイルが増えてきたのでシェルスクリプトを使おうとしたのですが
バックグラウンドでパイプへ展開しながら
実行ファイルに読み込ませる方法が分かりません
0687名無しさん@お腹いっぱい。2013/06/20(木) 11:26:02.34
>>686
結局 fortran.out も stdinから読んでるんだから、

xz -dc input.xz | fortran.out &amp;

でいいんじゃないの? mkfifoする必要なし。

for で回すなら、

for file in .....
do
xz -dc "$file".xz | fortran.out &amp;
done
0688名無しさん@お腹いっぱい。2013/06/20(木) 11:30:04.73
それで行けるならこんな質問しないだろうな。
たぶん質問のしかたが悪い。
0689名無しさん@お腹いっぱい。2013/06/20(木) 11:33:07.90
mkfifo使うにしても、質問で input の文字列のところを $hoge 変数にして
ループ回すだけだし、それで行けるならこんな質問しないのか?
0690名無しさん@お腹いっぱい。2013/06/20(木) 11:39:30.71
お前らよくこんな質問にレスを付けようと思うな。
文体は丁寧だが、目的語などを省略して、相手に理解させる配慮が一切ない、
自分しか理解できない文章で質問する奴はスルーでいいだろ。
0691名無しさん@お腹いっぱい。2013/06/20(木) 11:41:17.87
いいじゃん答えても。
スルーでいいと思う人はスルーしてればいいじゃない。
0692名無しさん@お腹いっぱい。2013/06/20(木) 11:50:41.37
>>686
普通に「&」でバックグランドジョブにしてもダメなのかな。
0693名無しさん@お腹いっぱい。2013/06/20(木) 12:35:01.18
>>690
お前少し黙ってろよ
06946862013/06/20(木) 12:49:13.79
>>688
>>690
すいませんでした。
考え直します。
0695名無しさん@お腹いっぱい。2013/06/20(木) 13:11:52.63
>>694
んで結局解決した?
0696名無しさん@お腹いっぱい。2013/06/20(木) 14:22:58.18
>>690 アレ、お前以外は質問を理解出来てるんじゃね?あっ(察し
0697名無しさん@お腹いっぱい。2013/06/20(木) 14:41:16.75
>>686 の質問は「バックグラウンドでパイプへ展開しながら
実行ファイルに読み込ませる方法が分かりません」だろ?

シェルスクリプトでもバックグランド「&」は使えるから、
お前が書いている内容をスクリプトにコピペして実行してみろ。
0698名無しさん@お腹いっぱい。2013/06/20(木) 14:50:30.70
>>697
それだと、inputというファイル名(FIFO)が衝突して正常動作しない。

>>686 が言うバックグラウンドでの実行というのは、
同じスクリプトを複数同時に(バックグラウンド)で起動するという意味を含んでいる
と解釈できる。

まあ、その件は >>689 が回答済みだけどね。
0699名無しさん@お腹いっぱい。2013/06/20(木) 17:27:55.78
これhurdの機能でできるんじゃね
0700名無しさん@お腹いっぱい。2013/06/20(木) 17:31:36.03
つか質問しといて、「考え直します」とか言って引っ込むのはどうよ?って思うな。
0701名無しさん@お腹いっぱい。2013/06/20(木) 17:43:13.21
同じPCでも、使うシェルによってPCの耐久寿命が変わるそうですね。
BASHは、電解コンデンサがライトアップしやすいって聞きましたけど、
ユーザーの多いシェルなのに何故ですか?
0702名無しさん@お腹いっぱい。2013/06/20(木) 17:54:54.11
質問です。
シェルが・・・
考えなおします。
0703名無しさん@お腹いっぱい。2013/06/23(日) 17:52:58.66
>>701
dry upじゃないの? ケミコンをライトアップしてどうすんだよw スカイツリーかよww
0704名無しさん@お腹いっぱい。2013/06/24(月) 12:35:58.41
というかbashが動作してるときだけコンデンサが劣化するとか
どんなテクノロジーなの?
0705名無しさん@お腹いっぱい。2013/06/24(月) 12:43:45.59
対話画面に降りると、CPUのidleを発行しなくなる環境が多かったから、
あながち間違いでもない。
0706名無しさん@お腹いっぱい。2013/06/24(月) 13:42:31.38
コピペ改変に釣られんなよ。
0707名無しさん@お腹いっぱい。2013/06/24(月) 14:37:12.05
>>705
そんなこともあったのか
奥が深いな
0708名無しさん@お腹いっぱい。2013/06/24(月) 14:59:38.89
bashは利用者がキーボードに触れるかどうか、気を感じているから。
0709名無しさん@お腹いっぱい。2013/06/24(月) 19:12:51.68
bashはあなたを監視している
過去のコマンド実行履歴もこっそり覚えてる
0710名無しさん@お腹いっぱい。2013/06/24(月) 23:56:06.32
おはようからおやすみまで
くらしをみつめる bash
0711名無しさん@お腹いっぱい。2013/06/25(火) 09:37:13.20
>>709
$ echo $HISTFILESIZE
0
何か?
0712名無しさん@お腹いっぱい。2013/06/25(火) 09:42:59.41
$ cat /etc/profile
readonly HISTFILESIZE=1000000
0713名無しさん@お腹いっぱい。2013/06/25(火) 10:14:06.90
Bourne-Again Shell is watching you.
0714名無しさん@お腹いっぱい。2013/06/25(火) 17:24:02.91
ご教授頂きたいのですが、

#!/bin/sh

awk '/Summit48si/ { print "snmpget -v 2c -c hbl-snmp "$1" SNMPv2-SMI::enterprises.1916.1.1.1.16.0 " ; print "echo "$1"" }' list | sh

を実行すると、

SNMPv2-SMI::enterprises.1916.1.1.1.16.0 = STRING: "シリアル番号"
IPアドレス

という風に出力されます。

これを、

IPアドレス シリアル番号

という風に出力させたいのですが、どのように記述すれば良いのでしょうか?
どなたか、お知恵を貸して頂けないでしょうか。
0715名無しさん@お腹いっぱい。2013/06/25(火) 17:39:37.87
ご教授ってネタなの?
0716名無しさん@お腹いっぱい。2013/06/25(火) 17:42:01.74
>>715
別にネタじゃ無いだろ
懇切丁寧に教えろって意味だ
0717名無しさん@お腹いっぱい。2013/06/25(火) 17:44:59.43
素で間違えてる人多いよ。
0718名無しさん@お腹いっぱい。2013/06/25(火) 17:47:52.88
素で間違えました。女教授ください。
0719名無しさん@お腹いっぱい。2013/06/25(火) 17:57:32.66
>>714
list はファイルでIPアドレスと型番的な情報(ex. Summit48si)が一行に一つ入ってるのでしょうか?

IPアドレスが後から出ているのが気に入らないなら
print "echo "$1"" を print "snmpget -v ..."の前に持ってくる。
でもってIPアドレスの後で改行が入るのがいやなら echo -n

SNMPv2-SMI::enterprises.1916.1.1.1.16.0 = STRING: が出力されるのがいやなら
これはsnmpgetが出力しているものでしょうか?それならsnmpgetで出力しないようにできるかどうか調べて
出力を抑制できないなら sed とかで削除すればいいんじゃないでしょうか。

教授はできないので教示させていただきました。
0720名無しさん@お腹いっぱい。2013/06/25(火) 18:02:46.48
>>715
・学問や技芸、専門知識を教え授けること
・児童・学生に知識・技能を授け、心意作用の発達を助けること
0721名無しさん@お腹いっぱい。2013/06/25(火) 18:03:21.06
わざわざ書かんでも知ってるでしょ。
0722名無しさん@お腹いっぱい。2013/06/25(火) 18:07:43.68
>>717
間違いじゃないw
他には「ご教授賜りたい」という用法もある。
0723名無しさん@お腹いっぱい。2013/06/25(火) 18:11:53.02
>>721
素で間違えてると思い込んでる人多いよ。
0724名無しさん@お腹いっぱい。2013/06/25(火) 18:16:22.41
この話おわり。
0725名無しさん@お腹いっぱい。2013/06/25(火) 18:22:55.40
女教師ください。
0726名無しさん@お腹いっぱい。2013/06/25(火) 18:38:55.10
>>722
「ご教示賜りたい」は聞いたことがあるが、
「ご教授賜りたい」なんて聞いたことがないw
0727名無しさん@お腹いっぱい。2013/06/25(火) 18:46:10.14
>>726
俺は聞いたことあるよ

この話おわり。
0728名無しさん@お腹いっぱい。2013/06/25(火) 19:01:50.38
ご教授も間違ってないけど、
見ず知らずの人に使うには図々しい感じがするわ。

とはいえ、時間が経てば、違いなんか無くなるだろうし
突っ込んだら負けだと思ってる。
0729名無しさん@お腹いっぱい。2013/06/25(火) 19:03:14.36
もうその話おわったよ。
0730名無しさん@お腹いっぱい。2013/06/25(火) 19:12:41.15
女享受ください。
0731名無しさん@お腹いっぱい。2013/06/25(火) 19:25:51.38
間違い方としては、役不足ににてるのだけどな。

>>714
awkって、-F'[ :]'とか区切り文字に正規表現つかなかった?
0732名無しさん@お腹いっぱい。2013/06/25(火) 19:32:38.31
この誤用は昔からあるね。
文末の定型だと勘違いしてる人が多い感じ
で「ご教授ください」「あなたのような弟子を取った覚えはありません」が繰り返されるという
0733名無しさん@お腹いっぱい。2013/06/25(火) 19:37:22.59
見飽きた話だ。
0734名無しさん@お腹いっぱい。2013/06/25(火) 19:39:57.27
「女教授股触りたい」
0735名無しさん@お腹いっぱい。2013/06/25(火) 19:46:02.01
>>728
図々しいやつだ、という批判なら尤もだし正しい指摘だよ
0736名無しさん@お腹いっぱい。2013/06/25(火) 20:16:32.09
教員をしてるわけではないけど専門知識のある知人に
ものを尋ねる時、「これ教えてくださいよ、先生!」みたいに比喩で
言うことは普通にある。それと一緒。問題なし。
0737名無しさん@お腹いっぱい。2013/06/25(火) 20:26:37.92
>>734
いいよ。今から研究室においで。
0738名無しさん@お腹いっぱい。2013/06/25(火) 20:33:48.36
↓738先生、持ち時間を使い切りましたので1手30秒以内でお願いします。
0739名無しさん@お腹いっぱい。2013/06/25(火) 21:14:54.32
738には失望した
0740名無しさん@お腹いっぱい。2013/06/25(火) 21:29:23.24
詳しいHP教えてください

ヒューレットパッカードがどうしたのですか?
0741名無しさん@お腹いっぱい。2013/06/25(火) 21:31:50.15
プラスチック容器なのに「レンジOK」って書いてあるよ
0742名無しさん@お腹いっぱい。2013/06/25(火) 22:19:29.93
>>726
アホだから
07437142013/06/26(水) 08:50:35.25
>>719
ありがとうございました。

大変助かりました。
0744名無しさん@お腹いっぱい。2013/06/26(水) 14:42:05.63
>>741
オチがわかりません
0745名無しさん@お腹いっぱい。2013/07/11(木) NY:AN:NY.AN
並列処理みたいなことをしたいです
*マークをつけた次の行です
ただこのままだと、配列に結果が代入されません
当然バックグウランドにしないと処理速度が落ちます

バックグラウンドにして、かつ結果を得る方法はありますか?

func_test ()
{
# 実際はこの関数の処理に時間がかかる、結果をメイン処理に渡したい
echo "${1}"
}

array=()
for i in `seq 1 5`
do
# この関数の処理を並列化したい *
array[${i}]=`func_test ${i}` &
done

wait

for i in ${array[@]}
do
echo ${i}
done
0746名無しさん@お腹いっぱい。2013/07/11(木) NY:AN:NY.AN
ファイルに結果を出力しておいて後で読み込むのが無難じゃないかな
直前に生成した子プロセスのPIDは$!でとれたはず。
配列にPID保管→PIDに対応するファイルから結果取得みたいな
0747名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
あとfunc_testはシェルスクリプトとして独立させてバックグラウンド実行
0748名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
すみませんが詳しい方のみ回答をお願いします
0749名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
>>748
自閉症
http://autism.flop.jp/characteristic/not_tired.html
07507452013/07/12(金) NY:AN:NY.AN
みなさんありがとうございます。

>>746
例ではループを「seq 1 5」としていますが、実際は数千あります。
(数千をいっきにバックグラウンドで走らせる訳ではなく分割する予定です)
数千のファイルを作って消すことはhddの寿命に対して大丈夫なものですか?
関数の出力は1行なので、数千でも容量はとらないのでメモリ上に一時ファイルを作る方法があれば助かりますが。

>>747
初心者なもので、関数と別のシェルスクリプトとして独立させることの違いが
あまりわからないので、もう少し詳しく教えていただけますか?
0751名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
>>750
>>747 は知ったかの誤回答。
関数を別のシェルスクリプトにしてもバックグラウンドの出力は
そのまま取り込めないから解決にならない。
0752名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
Cかpopen系が使える他のスクリプト言語で書いた方がいいんじゃないか?
0753名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
>>745
func_test() の出力行数が決まってるなら
その行の頭にでもindexの識別子を付けて
全部標準出力に出して、数字でソートすればいいよ

func_test ()
{
echo "${1} : ${1}の出力"
}

for i in `seq 1 5`
do
func_test ${i} &amp;
done | sort -n
0754名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
>>750
> 数千のファイルを作って消すことはhddの寿命に対して大丈夫なものですか?

HDDの寿命的には問題にならない。
SSDでも最近のはウェアレベリングしてるはずなので、
1行程度のファイルを数千個作ったところで影響なし。

どうしても気になるなら、直列に動かす複数のプロセスで1個のファイルを共有したら?
0755名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
>>751
名前付きパイプを作って、それに通すのは?
0756名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
シェルスクリプトの方で出力先も切り替えればいいだけの話。

#! /bin/sh
echo "${1} : ${1}の出力" > "${DIR}/file${1}.out"

そしてwaitで全てのシェルスクリプトが終了するまで待つ。
0757名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
処理中に何か不具合が出て、プロセスがいつまでも終わらなかったらどうすんの?
0758名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
それはどうやっても同じでは?
0759名無しさん@お腹いっぱい。2013/07/12(金) NY:AN:NY.AN
>>756 >>755
それはシェル関数を使ってできる。
わざわざ「別シェルスクリプト」に分ける意味がない。
■ このスレッドは過去ログ倉庫に格納されています