トップページ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
0035名無しさん@お腹いっぱい。2010/02/24(水) 08:20:19
ここ何のスレ?
0036名無しさん@お腹いっぱい。2010/02/24(水) 09:37:59
まとめると
>>19
「今時のUNIX」はLinuxと決定されました。
0037名無しさん@お腹いっぱい。2010/02/24(水) 09:41:33
>>36
LinuxはUNIXじゃないよ。*BSDもUNIXじゃないよ。

「今時のUNIX」は主にSolarisとかのこと。

Solaris10 -> bash標準
OpenSolaris -> bash必須
0038名無しさん@お腹いっぱい。2010/02/24(水) 09:50:50
>>28
> Mac OS Xは全然UNIXとは程遠い。
UNIX認証を得てるので名はUNIX。
ユーザランドはFreeBSDベースに作られたDarwinなので、実も伝統的なu**x

> kernelにFreeBSDが使われてるってだけ。
kernelはMach

>>37
>LinuxはUNIXじゃないよ。
分かった上で言ってるんだと思うよ。
0039名無しさん@お腹いっぱい。2010/02/24(水) 11:29:55
>>37
主にだったら他に何があるの?

主も糞もSolarisのみの話なら、今時のUNIXという
括りは間違ってるんだが
0040名無しさん@お腹いっぱい。2010/02/24(水) 14:37:00
>>37
OpenSolarisもUNIXじゃないよ。
0041名無しさん@お腹いっぱい。2010/02/24(水) 16:01:46
なんとかLinuxを正当化しようと今時のUNIX
なんて書いてみたものの、結局Solarisしかなくて

やっぱり今時のUNIX=Linuxに戻ってしまうという循環
0042名無しさん@お腹いっぱい。2010/02/24(水) 16:03:13
だから、LinuxはUNIXじゃないって、、
0043名無しさん@お腹いっぱい。2010/02/24(水) 18:28:06
>>24
第7版はPDP11です、とセルフつっこみ
0044名無しさん@お腹いっぱい。2010/02/24(水) 21:26:34
>>12 って、bash独自なところは一つもないじゃん。
/bin/shに変更しても「今時のUNIX」ならすべて動く。

それはそうと、>>12 は無駄が多い記述だな、もうちょっと簡単に書ける。
0045名無しさん@お腹いっぱい。2010/02/24(水) 21:40:54
>>44
うちの freebsd (/bin/sh = ash) と debian (/bin/sh = dash) では動きませんでした。
まあ、どっちも今どきの UNIX じゃないけど。
# ksh で拡張された機能が必要
0046名無しさん@お腹いっぱい。2010/02/24(水) 23:06:02
>>45
FreeBSDはUNIXじゃありません。

今、話をしてるのは「UNIX」だけです。
0047名無しさん@お腹いっぱい。2010/02/24(水) 23:33:26
OpenSolarisとか言ってるからUNIXじゃなくてもいいんだろ
0048名無しさん@お腹いっぱい。2010/02/24(水) 23:36:02
>>46
おまえのいう「UNIX」の定義を述べよ。
0049名無しさん@お腹いっぱい。2010/02/24(水) 23:53:32
UNIXかUNIXじゃないかってそんなに大事なことなの?
0050名無しさん@お腹いっぱい。2010/02/25(木) 01:27:11
OS XもUNIXでつ
0051名無しさん@お腹いっぱい。2010/02/25(木) 10:33:42
>>49
今時のUNIXと言い放ったバカと
それを受けとめる人間には重要
0052名無しさん@お腹いっぱい。2010/02/25(木) 10:35:17
なんで重要なんだろう。
0053名無しさん@お腹いっぱい。2010/02/25(木) 11:07:28
そんなに疑問に思うことなの?
0054名無しさん@お腹いっぱい。2010/02/25(木) 11:08:53
うん。
0055名無しさん@お腹いっぱい。2010/02/25(木) 14:58:09
改めて定義を聞かれて慌てているの図
0056名無しさん@お腹いっぱい。2010/02/25(木) 19:35:24
とりあえずわからないから
UNIXの定義は来世紀への課題と致します
0057名無しさん@お腹いっぱい。2010/02/25(木) 20:24:31
以下の結果を出力するスクリプトを,UNIXシェルで書け.
(基本仕様)
・コマンドとして実行できる.(UNIXシェルである.)
・コマンドラインの第1引数で数字を指定する.
・第1引数が数字以外だった場合はエラーメッセージを表示する.
・第1引数の数字以下の自然数のうち,素数をすべて見つけてリスト表示する.
・すべてUNIXシェル内部で処理し,外部コマンドは呼び出さないこと.
(ポイント)
☆UNIXシェルにするには,ファイルの最初に #!/bin/bashというおまじないを書く.
☆コマンドラインの第1引数は,$1に格納されている.
☆四則演算には $(( )) コマンドが使用できる.(ただし,整数しか扱えない.)


誰かわかるひとお願いします
0058名無しさん@お腹いっぱい。2010/02/25(木) 20:28:21
オウ、デジャブー
0059名無しさん@お腹いっぱい。2010/02/25(木) 21:37:45
#!/bin/sh
/usr/games/primes 1 "$1"
0060名無しさん@お腹いっぱい。2010/02/25(木) 22:23:21
>>57
『UNIXシェルである』という表現は有効なの?
0061名無しさん@お腹いっぱい。2010/02/25(木) 22:46:26
前スレでマルチしてた人でしょ。
相手しちゃだめだよ。
0062名無しさん@お腹いっぱい。2010/02/26(金) 06:56:02
>>59
>>57
>・すべてUNIXシェル内部で処理し,外部コマンドは呼び出さないこと.
0063名無しさん@お腹いっぱい。2010/02/26(金) 09:20:17
>>57
その頭の悪そうな問題書く人は駆け出しの厨房?
もし師と仰いでるなら、即刻師匠を変えた方が良い
0064名無しさん@お腹いっぱい。2010/02/26(金) 20:51:03
# bashでやる意味のない問題だと思うが。
# 問題自体は難しくないのだが・・・
#!/bin/bash
echo "$1" | grep '^[[:digit:]][[:digit:]]*$' >/dev/null 2>&1
if [[ "$?" -ne 0 || "$1" -lt 2 ]]
then
echo 'Error'
exit 1
fi

for ((i=2;i<="$1";i++)) {
if [ $((i % 2)) -eq 0 ]
then
echo "$i"
fi
}
0065名無しさん@お腹いっぱい。2010/02/26(金) 20:54:41
>>64
偶数を表示してどうするw

>>57
>素数
0066642010/02/26(金) 20:55:01
失礼、書きかけのやつをカキコしちまった。
粗相。
0067名無しさん@お腹いっぱい。2010/02/26(金) 20:57:40
「すべてUNIXシェル内部で処理し,..」だから、
grepも使っちゃ駄目だそうですよ
0068名無しさん@お腹いっぱい。2010/02/26(金) 20:57:53
ってゆうか、微妙に長すぎてカキコめない・・・

早い話、素数かどうかわかれば良いだけなら
判定対象の数値をそれより小さい数値全てで割り算してみればいいだけ。
ようするにループで回せばいいだけ。
0069名無しさん@お腹いっぱい。2010/02/26(金) 21:04:22
肝要部分だけ書くと、
↓だろ。全然長くないよ。

#!/bin/bash
for ((i = 2; i <= $1; i++)) {
for ((j = 2; j < i; j++)) {
if ((i % j == 0)); then
continue 2
fi
}
echo $i
}
0070名無しさん@お腹いっぱい。2010/02/26(金) 21:18:53
以下の結果を出力するスクリプトを,UNIXシェルで書け.
(基本仕様)
・コマンドとして実行できる.(UNIXシェルである.)
・コマンドラインの第1引数で人間の手番(○側か×側か)を指定する.
・人間とコンピュータが対戦するようにする.
・3x3マスのマルバツゲームのボードを作成する.
・○側と×側が交互に2次元座標上の位置を入力する.
・入力後、毎回ボードを表示する.
・たて、よこ、斜めのいずれかに○か×が3つ並んだ時点でプログラムを終了する.
・すべてUNIXシェル内部で処理し,外部コマンドは呼び出さないこと.
(ポイント)
☆UNIXシェルにするには,ファイルの最初に #!/bin/bashというおまじないを書く.
☆コマンドラインの第1引数は,$1に格納されている.
☆四則演算には $(( )) コマンドが使用できる.(ただし,整数しか扱えない.)


誰かわかるひとお願いします
0071名無しさん@お腹いっぱい。2010/02/26(金) 21:19:32
すっかり糞スレになったな
0072名無しさん@お腹いっぱい。2010/02/26(金) 22:48:25
以下の結果を出力するスクリプトを,UNIXシェルで書け.
(基本仕様)
・コマンドとして実行できる.(UNIXシェルである.)
・主人公、妹1名、両親、自分の友人数名(うち最低1名は女性、半数以上は男性とする)、妹の友人(女性)数名が登場する.
・主人公、妹、自分の友人、妹の友人はいずれも生徒もしくは学生とする.
・両親のうち、父は総合商社勤務のサラリーマン、母は専業主婦とする.
・主人公の言動やイベントの発生にともない、各キャラのパラメータを変化させる.
・病弱な妹を思いやる兄と妹の交流を中心に、他の登場人物との友情や恋愛を描写する.
・エンディングは妹、もしくは妹の友人のいずれかと深い恋愛関係になるか、誰とも親密になれないバッドエンディングになるようにする.
・妹と恋愛関係が深まる場合、病弱な妹への思いやりが徐々に、自然に恋愛感情へ変化するように描写する.
・ゲームの操作方法はコマンド選択式またはコマンド入力式とする.
・すべてUNIXシェル内部で処理し,外部コマンドは呼び出さないこと.
(ポイント)
☆UNIXシェルにするには,ファイルの最初に #!/bin/bashというおまじないを書く.
☆コマンド選択方式のゲームにする場合、select文を使用できる。
☆四則演算には $(( )) コマンドが使用できる.(ただし,整数しか扱えない.)


誰かわかるひとお願いします
0073名無しさん@お腹いっぱい。2010/02/26(金) 22:48:28
なったっていうか元から
0074名無しさん@お腹いっぱい。2010/02/26(金) 22:55:02
>>73
おにいちゃん、寂しいこと言わないで・・・

好感度 :-2
ストレス:+5
0075名無しさん@お腹いっぱい。2010/02/26(金) 23:10:47
くだらねえからもっとネタとしておもしろいお題提供してくれ
0076名無しさん@お腹いっぱい。2010/02/28(日) 00:22:12
コマンドとかBシェルはいろいろ使っていましたし、使いこなせますって言ったら
うちはKだしなって言われました。
個人的にはコマンドとか多少は違っていてもBシェル知っていたら、
それなりにKシェルとかでも対応できるじゃんと思っていますが


いまいち違いがわからないのですが
具体的にBシェル、Cシェル、Kシェルの決定的な違いってあるのでしょうか?
たとえばこれがあるからこれを採用しているとか
0077名無しさん@お腹いっぱい。2010/02/28(日) 00:35:37
あなたのいうBシェルがBourne Shell (/bin/sh) のことなら、
相手の言うKシェル(Korn Shell)はそれのスーパーセットなので、
機能が増えていると思えばいい。商用のUNIXだとkshがふつーに入っている。

あなたのいうBシェルがGNUのBourne-Again Shell(bash)のことなら、
同じようにBourne Shellのスーパーセットではあるが、kshとは系列が異なる。

/bin/sh の機能の範囲では大差ない。商用だとkshが、フリーだと
bashがそれの上位シェルとして使われていると思えばよい。

Linux だと /bin/sh だと思っても実体が bash だったりして知らない
うちに固有の機能に依存していることがあるので気をつける。

Cシェルのことは忘れていい。
0078名無しさん@お腹いっぱい。2010/02/28(日) 00:39:50
>>76
http://www.nurs.or.jp/~asada/FAQ/UNIX/UNIX.FAQ.5.html
0079名無しさん@お腹いっぱい。2010/02/28(日) 01:11:10
シェルスクリプトとVBA、どちらが簡単ですか?
0080名無しさん@お腹いっぱい。2010/02/28(日) 01:16:28
シェルスクリプト
0081名無しさん@お腹いっぱい。2010/02/28(日) 01:43:14
>>80
シェルスクリプトと比較して、VBAはどこがどんな風に難しいのでしょうか?
0082名無しさん@お腹いっぱい。2010/02/28(日) 10:29:39
処理系の入手が有償なとこ
0083名無しさん@お腹いっぱい。2010/02/28(日) 12:33:50
>>50
今時でつまつ調はキモい
0084名無しさん@お腹いっぱい。2010/02/28(日) 13:17:02
3日も前の事を今時って…
0085名無しさん@お腹いっぱい。2010/02/28(日) 17:10:20
bashの '-ne' は '=' ですか?
0086名無しさん@お腹いっぱい。2010/02/28(日) 17:21:11
bashじゃなくても -ne と = は違います。
0087名無しさん@お腹いっぱい。2010/02/28(日) 17:38:23
bashで '-eq' は '==' ですよね。
'=' はどう書くんでしょう?
0088名無しさん@お腹いっぱい。2010/02/28(日) 17:45:24
何を意味する = だ?
0089名無しさん@お腹いっぱい。2010/02/28(日) 17:49:33
bashじゃなくても -eq と = は違います

ついでに、-ne と != も違います
0090名無しさん@お腹いっぱい。2010/02/28(日) 17:51:42
bashでは比較の '=' と '==' は同じ。
しかし、'='または'==' と -eq は違う。
0091名無しさん@お腹いっぱい。2010/02/28(日) 17:58:53
今時の「UNIX」はbashじゃなくても'=='が使えるから無問題
0092名無しさん@お腹いっぱい。2010/02/28(日) 18:25:42
で、今時の「UNIX」の定義にループ
0093名無しさん@お腹いっぱい。2010/02/28(日) 18:27:07
ったく…今時の若いモンは…ブツブツ
009485,872010/02/28(日) 18:30:09
混乱中...
0095名無しさん@お腹いっぱい。2010/02/28(日) 18:40:42
その混乱してる行をコピペしてみろよ
0096名無しさん@お腹いっぱい。2010/02/28(日) 19:45:24
rpmの.specの中で

%preun
if [ "$1" -eq "0" ]; then
0097名無しさん@お腹いっぱい。2010/02/28(日) 19:48:38
>>96
"$1"が 0 でも 00 でも 000 でも一致するのが -eq
0098名無しさん@お腹いっぱい。2010/02/28(日) 20:00:19
if [ "$1" = "0" ]; then

こうすれば0のみの一致になる?
0099名無しさん@お腹いっぱい。2010/02/28(日) 20:06:40
if [ x"$1" = x0 ] ; then
と、xをつけたくなってしまうバッドノウハウ
0100名無しさん@お腹いっぱい。2010/02/28(日) 20:10:19
>>90
kwsk
0101名無しさん@お腹いっぱい。2010/02/28(日) 20:14:10
>>99
その xを付けるバッドノウハウが必要になるような "$1"の例が、
今時のUNIXシェルには存在しないんだな。

よってxを付けるバッドノウハウは不要。
0102名無しさん@お腹いっぱい。2010/02/28(日) 21:04:27
ash(またはdash)だと、$1 が ! のとき、[ "$1" = 0 ] でコケる。

bash/ksh/zsh だとコケない。確かにUNIXシェルならコケないな。
0103名無しさん@お腹いっぱい。2010/03/09(火) 04:37:55
>>100
文字として比較するか、数値として比較するか
0104名無しさん@お腹いっぱい。2010/03/09(火) 04:39:31
UNIXシェルと言っているが、HP-UXなんかはPOSIXだお
bashに似ているが、微妙に違う罠
0105名無しさん@お腹いっぱい。2010/03/11(木) 23:38:01
ファイルから1レコード読み込んでそのバイト数を取得したいのですが、レコードの最後にスペースがあると上手く行きません。

echo $record | wc -c
で取得できると思ったのですが、echoが末尾のスペースをカットしてしまい、上手く行かず…

どんな工夫で解決できるでしょうか?
0106名無しさん@お腹いっぱい。2010/03/11(木) 23:46:46
$record に格納する時点でスペースが落ちてるんじゃないの。
$record にはどうやってデータ格納してるの?
0107名無しさん@お腹いっぱい。2010/03/12(金) 06:46:57
>>106
まだテスト段階で、本格的なコーディングはしていないのですが、

record=`head -1 ファイルパス`
echo "${record}@" …ここではスペースが入っているのを確認
echo ${#record} …スペース込みの文字数が出力されるのを確認
echo $record | wc -c …バイト数が足りず

ということで、パイプする前のechoでスペースが落ちてるんじゃないかと…
0108名無しさん@お腹いっぱい。2010/03/12(金) 06:59:52
なんで " を使ったり使わなかったりするのかに興味あるわ
0109名無しさん@お腹いっぱい。2010/03/12(金) 18:33:15
で、今度は

echo "$record" | wc -c …バイト数が1個多い、、

、、と言うと予想。
0110名無しさん@お腹いっぱい。2010/03/12(金) 21:01:22
>>107
sh-3.2$ bar="space "
sh-3.2$ /bin/echo -n ${bar} | wc -c
5
sh-3.2$ /bin/echo -n "${bar}" | wc -c
6
0111名無しさん@お腹いっぱい。2010/03/12(金) 21:07:44
>>110
$ bar="space "
$ /bin/echo -n "${bar}" | wc -c
10

???
0112名無しさん@お腹いっぱい。2010/03/12(金) 21:21:03
>>>111
-n オプション(出力後改行しない)を持たないecho実装だとそうなる。
- n 空白 s p a c e 空白 改行
0113名無しさん@お腹いっぱい。2010/03/12(金) 21:30:41
>>112
知ってるよ。だから >>110 じゃ不完全だって指摘してるんだろ。
0114名無しさん@お腹いっぱい。2010/03/12(金) 21:35:42
そういうのってストレートに性格が出るよな。
0115名無しさん@お腹いっぱい。2010/03/12(金) 21:42:52
$ bar="-n"
$ /bin/echo -n "$bar" | wc -c
0
0116名無しさん@お腹いっぱい。2010/03/13(土) 10:29:32
>>105 >>107
echo ${#record} で目的の結果が得られているのに、
なぜ echo -n "$record" | wc -c とかわざわざ外部コマンドでやろうとするの?

(ダブルクォートと -n は付けておいたよ)
0117名無しさん@お腹いっぱい。2010/03/13(土) 14:53:17
まず service httpd configtest して syntax OK が出た場合のみ
service httpd graceful を実行する

という処理を一行で可能でしょうか?
0118名無しさん@お腹いっぱい。2010/03/13(土) 15:02:21
一行で可能です
0119名無しさん@お腹いっぱい。2010/03/13(土) 16:09:53
わかってくださいよ
0120名無しさん@お腹いっぱい。2010/03/13(土) 16:22:25
わかりました。
0121名無しさん@お腹いっぱい。2010/03/13(土) 16:26:00
ありがとうございます。
今環境がないので、今度客先に行った時に試してみます。
0122名無しさん@お腹いっぱい。2010/03/15(月) 01:02:16
環境変数に配列の宣言文を入れておいて、子シェルで配列を使いたいんですけど、上手くいきません。

export HOGE="(A B C D)"
hoge=${HOGE}

export HOGE=(A B C D)
hoge=${HOGE}

の両方試してみたのですが、どちらもhogeには文字列ががが

要素が10個近くあるので、それぞれ別の変数に入れて渡すとごちゃごちゃしそうで…
なにか良い方法はないですかね?
0123名無しさん@お腹いっぱい。2010/03/15(月) 02:39:42
>>122

bash なら
hoge=("${HOGE[@]}")

これでどうでしょうか。
0124名無しさん@お腹いっぱい。2010/03/15(月) 04:23:21
ががが
0125名無しさん@お腹いっぱい。2010/03/15(月) 07:03:40
>>122
export HOGE="(A B C D)"
(子プロセスで)
eval hoge=${HOGE}


>>123
同じシェルだとうまく行くが、
配列はexportできないので、
それでは駄目。
0126名無しさん@お腹いっぱい。2010/03/15(月) 17:36:54
function grepall(){
find . -name "*" -exec grep $1 {} /dev/null \;
}
findとexecを毎回打つのがめんどいんで
こんなのを書いたんですが

grepall "int main"とかやると
"int main"を含む行じゃなくて
intかmainを含む行が出力されてしまうんですが
そうならないようにできたりしますか?
0127名無しさん@お腹いっぱい。2010/03/15(月) 17:41:53
>>126
function grepall(){ find . -exec grep "$1" {} /dev/null \;;}
か?

つーか GNU grep の -r 使えばいいんじゃね。
0128名無しさん@お腹いっぱい。2010/03/15(月) 17:48:22
おお、どちらでもいけますた!ありがとう
0129名無しさん@お腹いっぱい。2010/03/17(水) 22:16:20
cat ${file} |while read line
do
echo "${line},1"
done

でファイルの中身をグルグル回すシェルを作りたいのですが、ファイルの改行コードが落ちてしまうのはどうにかならないでしょうか?

読み込むファイルがCRLFなので、LEだけ落ちてCRだけ残るというなんとも半端なことに…
どうせならCRもまとめてなくなるか、CRLFのまま残るかして欲しいんですが…
0130名無しさん@お腹いっぱい。2010/03/17(水) 22:36:30
>>129

echo "${line},1"
ってやってるなら、行末に ",1" が付くわけだけど、
${line}に ^M が含まれてるなら、"...^M,1" ってなるわな。

それ、LFが落ちてるわけじゃないよ。
0131名無しさん@お腹いっぱい。2010/03/17(水) 22:37:25
cat file | tr -d '\r' | while
0132名無しさん@お腹いっぱい。2010/03/18(木) 01:33:45
dos2unixコマンド使えば?
0133名無しさん@お腹いっぱい。2010/03/18(木) 07:19:29
そんな、baseにない非標準コマンド使われてもねぇ
0134名無しさん@お腹いっぱい。2010/03/18(木) 07:38:43
>>130
しかし、Windowsに持ってきてエディタで開いたり、バイナリエディタで見てもCRだけ残っているのですが…

>>131
やはりそういう形になりますかね…試してみます。
0135名無しさん@お腹いっぱい。2010/03/18(木) 08:21:57
>>134
おまえ、>>130 の言ってる意味わかってないな。

CR+LFのLFが落ちてCRだけ残ったのではなく、
もともとCRが普通の文字とみなされて、
その後に「,1」が追加されただけのことで、
LFが落ちたわけではないんだと言ってるんだけど。
■ このスレッドは過去ログ倉庫に格納されています