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

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

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。2010/02/20(土) 14:10:05
シェルスクリプトの総合スレです。 
スクリプトのお勉強・自慢・腕試しなどにどうぞ。 
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。 

□お約束 
・特記なき場合は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 でトレースしましょう。 

前スレ 
シェルスクリプト総合 その15
http://pc12.2ch.net/test/read.cgi/unix/1246408968/l50
0585名無しさん@お腹いっぱい。2010/08/13(金) 11:23:11
ハードウェア依存の問題を回避するためのworkarroundとしてsleep入れるんじゃないの?
別に問題ないと思うけど。
0586名無しさん@お腹いっぱい。2010/08/13(金) 12:03:28
アンチsleep君の主張はよくわからんな
そもそも非同期処理じゃないし…
0587名無しさん@お腹いっぱい。2010/08/13(金) 12:46:07
SMFやrcngのような同期をとる機構がないのがクソと言いたいのだろう。
0588名無しさん@お腹いっぱい。2010/08/13(金) 13:07:37
この文脈でなぜSMF?
あれはタイマ割り込み使って音源鳴らしてるだけだろ。
0589名無しさん@お腹いっぱい。2010/08/13(金) 13:08:45
この文脈でSMFと言ったら、Service Management Facilityに決ってんだろ。
0590名無しさん@お腹いっぱい。2010/08/13(金) 13:43:34
GNU sleepだと sleep 0.001 とかできるから、
SMF再生するシェルが書けそうだな。
0591名無しさん@お腹いっぱい。2010/08/13(金) 14:17:12
シェルってゆうな。クズ。
0592名無しさん@お腹いっぱい。2010/08/20(金) 19:16:35
Makefileのなかで、tarコマンドを使いたいんですが、うまくいきません
単純に
tar directry/faile.tar tergetdir/
としてみたんですが
0593名無しさん@お腹いっぱい。2010/08/20(金) 19:33:45
>>592
シェルと関係ない話は別スレでやれよ(Makefileとも関係ないし)

まあ、f と -C オプションが落ちてるのが原因だけどな。
0594名無しさん@お腹いっぱい。2010/08/20(金) 20:07:24
なんでこのスレ選んだんだw
0595名無しさん@お腹いっぱい。2010/08/20(金) 20:09:52
directry
faile
terget

英語初心者スレが適当だね
0596名無しさん@お腹いっぱい。2010/08/20(金) 20:37:55
まぁ、ファイル名は別にどうでもいいと思うが
オプションがないね
man tarオススメ
tar cf foo.tar bar
tar cfz foo.tar.gz bar
tar cfj foo.tar.bz2 bar
0597名無しさん@お腹いっぱい。2010/08/20(金) 21:11:10
tar作成じゃなくて、展開じゃないの?
05985922010/08/20(金) 21:29:35
すいません
tar xvfp directry/file.tar tergetdir/
でした
0599名無しさん@お腹いっぱい。2010/08/20(金) 21:36:30
Makefileにターゲットもなくいきなりtarコマンドを書いたと見た。
0600名無しさん@お腹いっぱい。2010/08/20(金) 22:12:32
>>598
だから、>>593 が言うように -C を付けろよ
06015922010/08/20(金) 22:26:50
>>600
やっとわかりました。どうも
0602名無しさん@お腹いっぱい。2010/08/22(日) 09:15:58
shine
0603名無しさん@お腹いっぱい。2010/08/22(日) 09:48:13
シャイン? 輝けって?
0604名無しさん@お腹いっぱい。2010/08/23(月) 22:07:15
OS:FreeBSD
passwd(1)をシェルスクリプトでバッチ的に流すにはどうすればいいのでしょうか。
2回聞かれるところとかが、どう書けばいいのかわかりません。
お願いします。
0605名無しさん@お腹いっぱい。2010/08/23(月) 22:13:46
>>604
標準ツールじゃないけど、expect使ってみるとか。
0606名無しさん@お腹いっぱい。2010/08/23(月) 22:26:36
>>604
chpasswdってBSDには無いの?
0607名無しさん@お腹いっぱい。2010/08/26(木) 14:17:56
pw コマンドで -h 0 とすると標準入力からパスワード読み込むよ。
0608シェルマスター2010/08/28(土) 00:16:37
シェルスクリプトをシステム管理に活かすなら、
お前らならどんなシェルスクリプトを作る?
0609名無しさん@お腹いっぱい。2010/08/28(土) 00:48:13
手作業でやってる作業のうち、繰り返しやるものを折りを見てスクリプト化してくだけ。
0610名無しさん@お腹いっぱい。2010/08/28(土) 03:14:39
起動時に毎回することを自動化
0611名無しさん@お腹いっぱい。2010/08/28(土) 12:19:38
ちょっとした単発のデータまとめとかの下処理用。
ログをcsvに整形してExcelのオートフィルタで分析とか。
0612名無しさん@お腹いっぱい。2010/09/01(水) 09:09:06
以下のようなシェルスクリプトを用いて1つの端末にタブで複数のプログラムを動かすってのをやってます。
ただ、これだとプログラムが終了したりするとタブが閉じちゃうので、終了した後でもまたそこから
コマンドが打てるように改変したいのですがどのようにやれば良いのでしょうか?

#!bin/sh

gnome-terminal \
--tab --working-directory=`pwd`/hoge/ -e "command" \
--tab --working-directory=`pwd`/foo/ -e "command" \
--tab --working-directory=`pwd`/bar -e "command" \


一応ググってみると

gnome-terminal -x bash -c "command1; command2; exec bash"

こんな表記を使うとその後もコマンドを受け付けるみたいなのですが、
上のスクリプトとの組み合わせ方が上手くいかず、タブが起動しなかったりプログラムが起動しなかったりします。


OSはUbuntuなのでシェルはbashになると思います。お願いします。
0613名無しさん@お腹いっぱい。2010/09/01(水) 09:34:17
>>612

gnome-terminal -e 'bash -c "command1; command2; exec bash"'
0614名無しさん@お腹いっぱい。2010/09/01(水) 17:51:34
複数のプロセスを切るときに、いちいちコマンドでひとつづつ切るのが面倒です。
そこで、シェルで一気にプロセスをきりたいのですが、どのように記述すればいいですか?
0615名無しさん@お腹いっぱい。2010/09/01(水) 18:06:22
zshなら kill -KILL {1..99999} みたいな?
たぶん argument list too long とかいわれるんで、分割いるけど。
0616名無しさん@お腹いっぱい。2010/09/01(水) 18:53:26
pkillとかか?
使えるかは環境によるけど。
0617名無しさん@お腹いっぱい。2010/09/01(水) 19:55:10
説明ぬけててすみません。
そうですpkillです。
であとシェルの種類はbashでやりたいんです。
んで流れ的には612のように、1つの端末にタブで複数のプログラムを動かします。
んで複数のプログラムのプロセスをシェルを実行するだけですべてを切りたいんです。
そのようなシェルを作るにはどうすればよいですか?
ちなみに環境はubuntu10.04です
0618名無しさん@お腹いっぱい。2010/09/01(水) 20:05:56
>>617 おまえ >>612 か?
>>613 には礼なしかよw >>613 はできたんだな?

だったら、pkill -HUP gnome-terminal とかすれば、
その gnome-terminal から派生したプロセスは(普通は)まとめて終了する。
ただし、個々のプロセス側でシグナルを無視してたり、
setsid()とかで別セッションを開始してる場合(デーモン類等)は
終了しないけど、これは仕方ない。
0619名無しさん@お腹いっぱい。2010/09/01(水) 20:30:05
シェル作っちゃう人だし
0620名無しさん@お腹いっぱい。2010/09/01(水) 23:06:53
killすることを「切る」って言うもんなん?
0621名無しさん@お腹いっぱい。2010/09/02(木) 00:01:55
うまい事言うなと思ったが単に変換エラーかもしれんなw
0622名無しさん@お腹いっぱい。2010/09/02(木) 07:31:04
>>619
>シェル作っちゃう人だし

えっ? ここの住人は自分でシェル作れないんですか?
ネットからのコピペ(+改変)専門ですか?
0623名無しさん@お腹いっぱい。2010/09/02(木) 08:46:53
シェルスクリプトスレだからね。
シェルスクリプトは書けるけど、シェル作れる奴なんてここにはいないよ。
0624名無しさん@お腹いっぱい。2010/09/02(木) 08:54:34
>>623
難しく考えずにまずは自分でシェル作ってみたら?
ハローワールドのシェルなんてたった2行で作れるよw
0625名無しさん@お腹いっぱい。2010/09/02(木) 08:55:03
ネタはいいから。
0626名無しさん@お腹いっぱい。2010/09/02(木) 09:56:23
>>624
その2行のソース読ませてくれない?
何万文字で2行なんだ?
0627名無しさん@お腹いっぱい。2010/09/02(木) 09:57:46
2行だとこれで終わりなんだけど。
#include <stdio.h>
#include <stdlib.h>
0628名無しさん@お腹いっぱい。2010/09/02(木) 10:07:46
シェルを書いても「スクリプト」で使うことはないなぁ。
スクリプトにするならperlだし。
シェルはスクリプトにはせずにコマンドとして使う。
0629名無しさん@お腹いっぱい。2010/09/02(木) 10:11:26
>>626
70文字で2行だよw

#!/bin/sh
while echo -n 'myshell> '; read line; do eval "$line"; done
0630名無しさん@お腹いっぱい。2010/09/02(木) 10:22:08
>>629
オマエくらい知能が低く生まれたかったわ
マヌケな2行でご満悦か
毎日幸せだろ?ww
0631名無しさん@お腹いっぱい。2010/09/02(木) 10:30:44
だよな。
whileの後に echoなんて書いても動くわけないし、
doより前に ; なんて書いてるからここでエラーになるはず。
試さなくてもわかる。
0632名無しさん@お腹いっぱい。2010/09/02(木) 10:38:00
見下したつもりの相手よりレベルが低いって……。>>631
0633名無しさん@お腹いっぱい。2010/09/02(木) 11:44:48
>>621

>>617
> すべてを切りたいんです。
とか言ってるから変換ミスではないと思う。
0634名無しさん@お腹いっぱい。2010/09/02(木) 12:09:58
$ cat 2sh.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>

void child(int argc, char **argv);

int main()
{
int argc, n = 0;
int status;
char input[10000], *argv[256], *cp;
const char *delim = " \t\n";

0635名無しさん@お腹いっぱい。2010/09/02(木) 12:11:09
while (1) {
++n;
printf("[%s@2ch]$ ", getenv("USER"));
if (fgets(input, sizeof(input), stdin) == NULL || input == 4) {
exit(0);
}
cp = input;
argc = 0;
while (argc < 256) {
if ((argv[argc] = strtok(cp,delim)) == NULL)
break;
cp = NULL;
argc++;
}
0636名無しさん@お腹いっぱい。2010/09/02(木) 12:12:14
if(strcmp(argv[0], "exit") == 0) {
exit(0);
}
pid_t pid = fork();
if(pid == -1) {
perror("fork");
exit(1);
} else if(pid == 0) {
child(argc, argv);
} else {
wait(&status);
}
}
}

void child(int argc, char **argv) {
execvp(argv[0], argv);
}
0637名無しさん@お腹いっぱい。2010/09/02(木) 17:50:53
おまいらって変なとこで意固地になるよなw
0638名無しさん@お腹いっぱい。2010/09/02(木) 17:54:12
てゆーか、
input == 4 ← inputは char *型なのに
とか、
execvp(argv[0], argv)
の引数が足りないとか、

間違いがあるとネタにもならんな。
0639名無しさん@お腹いっぱい。2010/09/02(木) 18:02:38
シェルぐらい1行で書けよw

int main(){char b[256];while(printf("hoge> "),gets(b)){system(b);}return 0;}

コンパイル、動作確認済み。warning無視
0640名無しさん@お腹いっぱい。2010/09/02(木) 19:07:59
万能ソース

#include </dev/tty>
0641名無しさん@お腹いっぱい。2010/09/02(木) 19:18:51
634涙目w
0642名無しさん@お腹いっぱい。2010/09/02(木) 19:22:23
/bin/sh のラッパーである system() を使って
「シェルできました」と言うのはちょっとなぁ。
0643名無しさん@お腹いっぱい。2010/09/03(金) 08:44:51
ここはシェルスクリプトスレなんで
シェルを書く話はよそでやってください。
0644名無しさん@お腹いっぱい。2010/09/03(金) 14:59:28
>>642
じゃあ、system()なしで書いたよ↓

main(){char b[256];while(printf("hoge> "),gets(b)){fork()?wait(0):_exit(execlp(b,b,0));}}
0645名無しさん@お腹いっぱい。2010/09/03(金) 15:14:23
>>644
とんちやってるんじゃないんだから、exec系も無しだろう。
0646名無しさん@お腹いっぱい。2010/09/03(金) 15:18:17
>>645
えぅ?

おまえ >>644 のプログラムの動作理解してないだろ
0647名無しさん@お腹いっぱい。2010/09/03(金) 19:38:51
>>645 は実際のシェルはexec使わずに実装されてるとでも思ってるのだろうか
0648名無しさん@お腹いっぱい。2010/09/03(金) 20:12:21
printf("hoge> "),gets(b)

カンマ区切りの実行順は確定だっけ?
0649名無しさん@お腹いっぱい。2010/09/03(金) 20:41:07
カンマ演算子は左が先。
関数引数のカンマで区切られた各項の評価順序は不定。

「副作用完了点」でぐぐろう。
0650名無しさん@お腹いっぱい。2010/09/05(日) 19:15:10
そんなに上げ足とらなくても、シェルスクリプトとシェルの誤用くらい文脈でわかるだろ。
SQL ServerをSQLって呼ぶのに比べりゃ大したことない。
0651名無しさん@お腹いっぱい。2010/09/05(日) 19:44:10
じゃあPC98をさして一太郎といってもいいんですか?
0652名無しさん@お腹いっぱい。2010/09/05(日) 19:51:18
そもそも誤用でもないし
0653名無しさん@お腹いっぱい。2010/09/05(日) 20:53:42
>>650
揚げ足ってどのレスのことだよ
0654名無しさん@お腹いっぱい。2010/09/05(日) 21:11:54
>>653
>>617に対する>>619から始まったシェルを作るって話のこと。
0655名無しさん@お腹いっぱい。2010/09/06(月) 00:34:26
俺は50ccATミッション車を総合的に「ラッタッタ」と呼ぶ。
異論は認めない
0656名無しさん@お腹いっぱい。2010/09/06(月) 08:56:24
俺は JIS規格のステープラのことを総合的にホッチキスと呼ぶ
異論は認めるw
0657名無しさん@お腹いっぱい。2010/09/06(月) 16:07:08
俺は、白い綿シャツを「ホワイトシャツ」と呼ぶ、ネイティブな
発音は認めない
0658名無しさん@お腹いっぱい。2010/09/06(月) 16:14:46
もういいです。
0659名無しさん@お腹いっぱい。2010/09/06(月) 16:21:04
俺はPCなどのコンピュータハードウェアのことをミシンと呼ぶ(サーバーミシン等)
縫製機械のことを連想してしまうやつは認めない。
0660名無しさん@お腹いっぱい。2010/09/06(月) 18:58:16
うちのおかんはゲームコンソールは全てファミコンという
0661名無しさん@お腹いっぱい。2010/09/06(月) 20:06:12
for file in *
do
mv "$file" "${file/hoge/piyo}"
done
0662名無しさん@お腹いっぱい。2010/09/06(月) 20:48:12
同時に8スレッド走るCPUで大量のシェルスクリプトを実行したくてxargsつかっているのですが、
うまく動かなくて困っています。分かる人教えてください。

やりたいことは、数値計算の実効シェルスクリプト(300個くらいある)を同時に最大8個走らせ、
一つ終了したら次が始まるようにしたい。

args.listファイルにシェルスクリプトの絶対パスを1行ずつ書き並べて
xargs --arg-file=args.list --max-procs=8 -L 1
としましたが、topコマンドで確認しても全く動いている気配がありません。

クラスター用のjobマネージャは使わず、あくまでlinuxで一般的に使えるコマンドで済ませたいです。
0663名無しさん@お腹いっぱい。2010/09/06(月) 20:57:54
犬板に(・∀・)カエレ!!
0664名無しさん@お腹いっぱい。2010/09/06(月) 21:32:30
>>662
--arg-file はあくまで「引数」リストだから。
実行するシェルスクリプトを書き並べても引数になるだけで実行されない。

実行するには xargsのコマンドとしてシェルを書かないと。

xargs --arg-file=args.list --max-procs=8 -L 1 sh
0665名無しさん@お腹いっぱい。2010/09/06(月) 23:46:45
そんなに時間が惜しいなら、最低限LLでやるべきだろ。
06666622010/09/07(火) 01:41:39
おお、できました!
自分も引数リストであることは引っかかっていたのですが、どう解決すればいいか分かりませんでした。
ありがとうございました。


>>665
これは私に対するレスですか?LLというのはAWKとかParlとかのことですか?
『LLを使うと時間短縮になる』というイメージが湧かないのですが、具体的にどんな方法があるんでしょうか?
0667名無しさん@お腹いっぱい。2010/09/07(火) 01:43:34
実際Perlとかで書いてみて時間計って、
シェルスクリプトと比べてみるといいよ。
0668名無しさん@お腹いっぱい。2010/09/07(火) 06:33:27
>>664
> シェルを書かないと。

↑シェルを書いちゃう回答者現るw
0669名無しさん@お腹いっぱい。2010/09/07(火) 08:15:01
shってシェルじゃないの?
0670名無しさん@お腹いっぱい。2010/09/07(火) 08:15:29
そこはシェルでおけ
0671名無しさん@お腹いっぱい。2010/09/07(火) 09:37:54
>>669
一般的な呼び方だと、ボーンシェル、Bシェル(ビーシェル)と
呼ぶんで、シェルとは呼ばない。
0672名無しさん@お腹いっぱい。2010/09/07(火) 09:47:45
指定したシェルスクリプトを実行するシェルなんだからいいじゃんか
そのうちshと想定して回答しただけだろ
字面で反応した恥ずかしいミスを指摘されてキョドるなよ
0673名無しさん@お腹いっぱい。2010/09/07(火) 09:59:19
>>672
スクリプトの前にアンカー覚えろよ
0674名無しさん@お腹いっぱい。2010/09/07(火) 12:29:12
> 数値計算の実効シェルスクリプト(300個くらいある)
これって「数値計算」をシェルスクリプトでやってるのかなあ?
06756662010/09/07(火) 12:30:37
>>667
科学計算についてどの程度知った上でのレスでしょうか?

300個ある実行シェルスクリプトは全て、中でFortranのプログラムを呼び出しているだけです。
シェルスクリプトは初期値や環境変数の設定に使うだけであって、それで数値計算しているわけではないです。

『Perlで書いてみて』というのは、具体的にどの部分を言っているのですか?
06766662010/09/07(火) 12:32:32
レスがかぶった。
0677名無しさん@お腹いっぱい。2010/09/07(火) 12:55:12
さー
情報後出し祭りに突入してきましたよ
0678名無しさん@お腹いっぱい。2010/09/07(火) 12:59:10
情報後出しじゃないだろ

>>662 の質問は >>664 で解決してる。解決報告は >>666

質問の解決後に >>667 の Perl厨が余計なことを言い出した。
それに対する反論として >>675 が書かれただけ。

Perl厨はきっと今ごろ赤面w
0679名無しさん@お腹いっぱい。2010/09/07(火) 14:21:26
>>678
そうか?
別に深く追求しないで
「単純に時間を計って比べてみな」ってだけなんだから

「現状が速いです」で済む話なんだが?


0680名無しさん@お腹いっぱい。2010/09/07(火) 15:07:59
>300個ある実行シェルスクリプトは全て、中でFortranのプログラムを呼び出しているだけです。
なんで、ここもプログラムにしないの?
普通は、函数化はしてあるだろうから、それを呼び出すようにするだけじゃん。
わざわざシェル経由して、xargsでこねくり回す意味がわからんわ。

完全に情報後出しの下手ないい訳だなw
0681名無しさん@お腹いっぱい。2010/09/07(火) 15:13:56
>>680
よくよめ

xargs使うのは、-max-procs=8 を指定したいから。
同時に動くプロセスを常に8個に保った状態で回したい。
これはFortranだけではできない。

-max-procs=8については最初の質問の >>664 に書かれている。

全く持って「後出しではない」
0682名無しさん@お腹いっぱい。2010/09/07(火) 15:17:44
>>680
>普通は、函数化はしてあるだろうから、それを呼び出すようにするだけじゃん。


それを呼び出すようにするだけだとシングルスレッドにしかならないよ。
8スレッド使いたいという質問だったのでは?
0683名無しさん@お腹いっぱい。2010/09/07(火) 15:43:23
だから、並列化の部分のところを含めてプログラムにすれば?
と、言ってると思うんだが?
>>これはFortranだけではできない。
数値計算の並列化なんて、Fortranの最も得意とするところじゃん。
0684名無しさん@お腹いっぱい。2010/09/07(火) 15:44:00
>>680
特定のパラーメータ振ったデータを生成して、fortranの解析プログラムを起動する
スクリプトなんだろ。そもそもそういう解析プログラムはコマーシャルソフトや別
部門が作ったソフトの場合が多く、それを呼び出すようになど出来ない場合が多い。
他にも、解析プログラムに、汎用でない特定の用途のパラメータ振りを組み込む事
は嬉しくないから、スクリプトで対応する可能性もある。

>>662を読んでその程度を推測できないアマチュアはネチネチと絡むんじゃねーよ。
■ このスレッドは過去ログ倉庫に格納されています