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

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

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

□前スレや過去スレ:
シェルスクリプト総合 その1
http://pc8.2ch.net/test/read.cgi/unix/1101820646/
☆シェルスクリプトを勉強するにあたって☆
http://pc5.2ch.net/test/read.cgi/unix/989659936/
便利なシェルスクリプト見せろ
http://pc5.2ch.net/test/read.cgi/unix/996949546/
【貝】第1回シェル講座【殻】
http://fun.kz/test/read.cgi/unix/1016372780/

□関連スレ:
sed
http://pc8.2ch.net/test/read.cgi/unix/1085730992/
おまえら! shell は何を使っているんですか?
http://pc5.2ch.net/test/read.cgi/unix/1012330865/
Eshell の使い方とか設定とか【Emacs Shell、Lisp】
http://pc8.2ch.net/test/read.cgi/unix/1102921590/

□他板の関連スレ:
Macでシェルスクリプト総合 Part 1
http://pc7.2ch.net/test/read.cgi/mac/1105074933/
【Shell】どのシェル使ってる?【Script】
http://pc8.2ch.net/test/read.cgi/linux/1067330754/
0542名無しさん@お腹いっぱい。2005/07/09(土) 20:07:19
>>541
djbってじじいなの?
0543名無しさん@お腹いっぱい。2005/07/09(土) 20:09:18
         ,.. -――‐- 、
       ,. '":::::::::::::::::::::::::::::::ヽ    
      /:::::::::::::::::::::::::;:::ノi、:::::::ヽ 
     .,':::::::::::::::::::::;-ニ'/  ヽ:i::::::::ヽ
     i:::n::;;:'::;;:-',,='"´    ヽi、::::::::l 
     !:::l.}、/          、!:::::l 
    .l:::;;じ'   ''''''   ''''''    ヽ;;!
     、:;;!  (●),   、(●)、.:::::il 
     l::、!     ,,ノ(、_, )ヽ、,, .:::::/ヽ 
    .l;'^ヽ.     -=ニ=- ' .::::::〈,' ! 
    l::、 ゝ.、    `ニニ´ .:::::::;"ノ  
    !::::`ー-.、       .::::/:l:::l 
    .l:::::::;;;;;;i::;;l` - 、   ,..;;';;;l;;:::i::::l  
    i:::::::;;;;;;;':::;;l;;;;;;;;l ` ´l;;;;;;;;;l::::'::::i 
0544名無しさん@お腹いっぱい。2005/07/09(土) 20:32:07
美人が出てきたところで、フレームも終わりだな。
0545名無しさん@お腹いっぱい。2005/07/09(土) 21:10:24
これはフレームが収まるAA?
0546名無しさん@お腹いっぱい。2005/07/09(土) 21:17:46
#!/bin/sh

echo hoge


~$ ./hoge.sh
: bad interpreter:No such file or directory

hogeと表示したいだけなのにやってくれません!(><)
such fileって何のことですか?(><)
0547名無しさん@お腹いっぱい。2005/07/09(土) 21:19:16
サッチというファイル
0548名無しさん@お腹いっぱい。2005/07/09(土) 21:22:22
>>546
Winでエディットしただろ。
#!/bin/sh の後ろに ^M が付いていて、
/bin/sh^M なんてコマンドは知らんと言ってる。
0549名無しさん@お腹いっぱい。2005/07/09(土) 21:38:08
改行コードをlfにしたらできました!(><)
ありがとうございましたm(><)m
0550名無しさん@お腹いっぱい。2005/07/09(土) 22:33:48
(゚Д゚)ハァ?
0551名無しさん@お腹いっぱい。2005/07/09(土) 23:04:18
見えない ^M が見える漢がこのスレに居ると言われている。
0552名無しさん@お腹いっぱい。2005/07/09(土) 23:08:43
^M能力者
0553名無しさん@お腹いっぱい。2005/07/09(土) 23:14:27
^M 能力者、映画化決定
0554名無しさん@お腹いっぱい。2005/07/09(土) 23:23:16
エスパーは本当にいたんだ!
0555名無しさん@お腹いっぱい。2005/07/09(土) 23:24:41
っ[potion of see invisible]
0556名無しさん@お腹いっぱい。2005/07/09(土) 23:26:24
Linuxのbash ja_JP-UTF8環境で、先頭を#!/bin/saofeaoijfeaoiとしたら、
bash: ./jfoeiajosh: /bin/saofeaoijfeaoi: bad interpreter: そのようなファイルやディレクトリはありません
と言われたが、#!/bin/saofeaoijfeaoi^Mにしたら、
: bad interpreter: そのようなファイルやディレクトリはありません
になったので、エスパーではないと思われるが、よくすぐに分かったな。

0557名無しさん@お腹いっぱい。2005/07/09(土) 23:42:15
しかし、こうなってくると >>547 が可哀相だな。
エスパー出現じゃ仕方が無いか。
0558名無しさん@お腹いっぱい。2005/07/10(日) 00:11:27
まあFAQですね。
0559名無しさん@お腹いっぱい。2005/07/10(日) 00:26:01
一瞬天国かと思った、この流れ
0560名無しさん@お腹いっぱい。2005/07/10(日) 02:32:18
>>551-557
プ。FAQだよ、騒ぐな馬鹿ども。
0561名無しさん@お腹いっぱい。2005/07/10(日) 02:34:05
空気読めない馬鹿が一匹
0562名無しさん@お腹いっぱい。2005/07/10(日) 02:42:33
行末の^Mも見えないのに空気が見えるわけがない
0563名無しさん@お腹いっぱい。2005/07/10(日) 04:28:38
つ [ざぶとん]
0564名無しさん@お腹いっぱい。2005/07/10(日) 12:08:06
windowsのcygwinでbashなのですが

dir=(`pwd`);
if [ ! -d "$dir" ];then
  echo "$dirは存在しないかディレクトリではありません";
  exit 1;
fi

というスクリプトで今いるデレクトリが
"C:\Documents and Settings\user\My Documents"というように空白を含む
デレクトリだとうまくいきません. どうすればいいでしょうか?
0565名無しさん@お腹いっぱい。2005/07/10(日) 12:24:26
dir=`pwd` にすれば?
0566名無しさん@お腹いっぱい。2005/07/10(日) 12:27:59
dir="`pwd`"じゃないのか?
05675642005/07/10(日) 12:38:52
できました. ありがとうございます.
0568名無しさん@お腹いっぱい。2005/07/10(日) 12:41:27
bash ならば何もしなくても $PWD にカレントディレクトリが入ってるはず。
0569名無しさん@お腹いっぱい。2005/07/10(日) 16:07:32
`pwd`を直接代入する場合は" "を付けなくていい。
dir=`pwd`で、スペースもちゃんと保存される。
もちろん、値を使う時は"$dir"で" "が要る。

dir=(`pwd`)の場合は、配列への代入になってしまうので、
配列の要素解釈の際にスペースが解釈されてしまうため、
dir=("`pwd`")とする必要がある。
でも、>>564 は配列とは知らずに=( )を使ったのだろうから、
この書き方は忘れた方がいい。

なお、bashが$PWDをセットするからといって、
こういうのに頼ってはいけない。
0570名無しさん@お腹いっぱい。2005/07/10(日) 16:17:54
>>569
> なお、bashが$PWDをセットするからといって、
> こういうのに頼ってはいけない。

と老害が申しております。。。。
0571名無しさん@お腹いっぱい。2005/07/10(日) 16:18:47
と、知能の発達の遅れた方が申しております。
0572名無しさん@お腹いっぱい。2005/07/10(日) 18:43:22
互換性を考えるなら使わん方がいいけどね。
cygwin なんて互換性を無視していい環境の最たるものだと思うが。
0573名無しさん@お腹いっぱい。2005/07/10(日) 18:51:00
またこいつか。
05741232005/07/12(火) 02:22:06
誰かリムーバブルディスク(USBストレージ)を自動マウントするスクリプト教えてくれませんか?
0575名無しさん@お腹いっぱい。2005/07/12(火) 02:25:54
OSによって違うだろ。
ここじゃなくて自分が使ってるOSのスレで聞くべし。
0576名無しさん@お腹いっぱい。2005/07/12(火) 02:42:56
#/bin/sh
#自動マウントスクリプト
while true
mount usbストレージ
done
05771232005/07/12(火) 04:03:07
なんとつかいにくいsolarisです。
大学なんでsuもrootの権限もないんですよね・・・

あのそこのusbストレージ
と二音後で書いてあるところはどうすれば・・・・
0578名無しさん@お腹いっぱい。2005/07/12(火) 04:33:19
素直にそこの管理者にすがるのが吉
0579名無しさん@お腹いっぱい。2005/07/12(火) 07:03:04
>>577
二音語って、
‐・・・ ・‐ ‐・‐ ・‐
みたいに「・」と「‐」の二音で会話する言語のことですか?
0580名無しさん@お腹いっぱい。2005/07/12(火) 07:43:32
>>576
whileループでマウントするのは重杉で非効率。
やむを得ずそれでやるとしても、ループ中に
sleep 1 とか入れれ。

Solarisならvoldとかautomountとかでやるのが
正攻法だろな。いずれにしても、その設定をするために
root権限は要る。設定完了後はrootじゃなくても
自動的にマウントできるようになる。
0581名無しさん@お腹いっぱい。2005/07/12(火) 14:28:26
何かと話題のzshみたいですが、
以前、zshのmanを見ていた時、zshにsocketの機能があるのに
ビックラこきました。
shellでsocketって、何に使うねん。と思ったのですが、
shellでsocketって、メジャーなんでしょうか?
0582名無しさん@お腹いっぱい。2005/07/12(火) 14:34:31
>>581
zftp
0583名無しさん@お腹いっぱい。2005/07/12(火) 19:13:06
zshは使わないけど、netcatはたまに使うな。
0584名無しさん@お腹いっぱい。2005/07/13(水) 14:01:50
俺だったらこう書くぞ!とかあったらお願いします。

***********************************
#!/bin/sh

old_name=$1
num=1
new_name=$old_name$num
while [ -e $new_name ]
do
num=`expr $num + 1`
new_name=$old_name$num
done
****************************
num=
new_name=
を2回も書いてる所とかが気にくわないんですが、どうにかできるものですか?
0585名無しさん@お腹いっぱい。2005/07/13(水) 14:12:22
num=1
while [ -e $1$num ]
do
num=`expr $num + 1`
done
new_name=$1$num
0586名無しさん@お腹いっぱい。2005/07/13(水) 14:16:15
>>584

#!/bin/sh

old_name=$1
num=1
while [ -f "$old_name$num" ]
do
num=`expr $num + 1`
done
new_name=$old_name$num

だな。
new_nameの代入をループ外に出して1行減らした。
Solarisではtest -eが使えないので
test -fに変えた。
あと、引数として使う時は" "で囲む。(直接代入なら囲まなくていい)
0587名無しさん@お腹いっぱい。2005/07/13(水) 14:19:36
linux人でbashですって書き忘れてたーと思ったらもう返信が
>585,586
ありがとうございます。
むー。なんか俺、無駄な事しまくってますね。
0588名無しさん@お腹いっぱい。2005/07/13(水) 14:33:23
bashなら、

old_name=$1
for ((num=1; ; num++)) {
[ ! -e "$old_name$num" ] && break
}
new_name=$old_name$num

と書ける。
0589名無しさん@お腹いっぱい。2005/07/13(水) 14:57:22
>588
++ってシェルスクリプトでも使えるんですね。
やってみたいお年ごろなので一行にまとめてみました。

for ((num=1; ; num++)) { [ ! -e "$1$num" ] && { new_name=$1$num ; break ;} }
0590名無しさん@お腹いっぱい。2005/07/13(水) 15:04:18
妙な書き方認めてるbashうぜぇー
0591名無しさん@お腹いっぱい。2005/07/13(水) 20:28:52
bash だから余所へ逝けとはいわんが,せめて >>2 の □お約束 くらいは読もうぜ
0592名無しさん@お腹いっぱい。2005/07/13(水) 20:33:06
今時Posix shellじゃなくてbourne shell互換スクリプトを書く意味って
何なんだろうか
0593名無しさん@お腹いっぱい。2005/07/13(水) 20:41:53
posixってなんですか。
0594名無しさん@お腹いっぱい。2005/07/13(水) 21:01:55
>>593
ちったぁぐぐったうえで聞けや、この腐れぼんくら
ttp://www.google.com/search?hl=ja&q=posix&btnG=Google+検索&lr=lang_ja
0595名無しさん@お腹いっぱい。2005/07/13(水) 21:04:23
>>594
posixってどこで読めの?
0596名無しさん@お腹いっぱい。2005/07/13(水) 21:22:25
>>592
dejure standard ではなく defact standard を使うのは当然でしょ。
ちゃんと象牙の塔に引き篭もっててください。
0597名無しさん@お腹いっぱい。2005/07/13(水) 21:24:31
Posixなんて机上の空論。
現存の環境で動かなきゃ意味がない。
となると、必然的にBourne互換スクリプトになる。
0598名無しさん@お腹いっぱい。2005/07/13(水) 21:31:07
今時CだってK&Rスタイルじゃ書かねえだろうがよ……
いや、書くか?
それとも、ansi2knr.c?
0599名無しさん@お腹いっぱい。2005/07/13(水) 21:32:16
>>596
dejure standardはなんですか
0600名無しさん@お腹いっぱい。2005/07/13(水) 21:34:19
で、可搬性重視でbourneシェル互換スクリプト書くヤツはecho()とかいう関数を
毎回定義するんだな?
0601名無しさん@お腹いっぱい。2005/07/13(水) 21:37:10
>>600
またお前か。引っ込んでろ。
0602名無しさん@お腹いっぱい。2005/07/13(水) 21:37:12
>>600
何回も書くほど面白いネタじゃないぞ。
0603名無しさん@お腹いっぱい。2005/07/13(水) 21:42:22
>>597
>Posixなんて机上の空論。

ええ?そうなんですか?
少なくともHP-UXの/bin/shはPOSIX準拠だと謳っているから
そう信じてたんですが私は騙されてたんでしょうか?
0604名無しさん@お腹いっぱい。2005/07/13(水) 21:54:41
>>603
今だと/bin/sh-->/usr/bin/sh(shell-posix)なのかな?
昔はそうじゃなかった気がする

http://www.bookshelf.jp/texi/autoconf/autoconf-ja_10.html
あたりが答えなのかねえ
0605名無しさん@お腹いっぱい。2005/07/13(水) 21:57:22
solarisはkshをposix準拠シェルとして扱ってるな。
06066032005/07/13(水) 22:10:28
>>604
>今だと/bin/sh-->/usr/bin/sh(shell-posix)なのかな?

今、現物を確認できませんが、
たしか/bin/shと/usr/bin/shは両方実体ファイルで、
中身はdiffで比べると同一だったと思います。
それと/sbin/shは違うシェルだったような・・・
0607名無しさん@お腹いっぱい。2005/07/13(水) 22:13:13
ls -l /bin
lrwxrwxrwx 1 root root 9 Aug 23 2004 /bin -> ./usr/bin
06086032005/07/13(水) 22:22:36
>>607
それはHP-UXの話ですか?
だとしたら盲点ですた・・・
じゃあやっぱりHP-UXの/bin/shはPOSIX準拠なのだと信じて
生きていきます・・・
0609名無しさん@お腹いっぱい。2005/07/13(水) 22:29:17
>>608
いや、Solarisです。
ちなみに、/sbin/sh はスタティックリンク
06106032005/07/13(水) 22:39:02
>>609
あら。失礼しますた。
やっぱ明日自分で確認してみよう・・・
0611名無しさん@お腹いっぱい。2005/07/13(水) 22:41:11
HP-UXのsh-posixて、行エディットできるからterminfo見てるよな
そういうシェルを/binに置くのって、どうなのよ
0612名無しさん@お腹いっぱい。2005/07/13(水) 22:41:55
>>609
10では/sbin/sh --> /bin/sh
0613名無しさん@お腹いっぱい。2005/07/13(水) 22:45:41
ちょっと話は変わりますが、
Solarisには、/usr/bin/cdとか/usr/bin/umaskとか、
外部コマンド版が存在しますが、
これって意味あるんですか?
実際、実行しても当然期待通り動作しませんが・・
0614名無しさん@お腹いっぱい。2005/07/13(水) 22:46:16
要するに、シェルをパスで指定しないといけないのが悪いんだYO!!
ってことでOK?
/bin/shが何者だかわかりゃしねえ
0615名無しさん@お腹いっぱい。2005/07/13(水) 22:47:44
>>611
rootは/sbin/shを使うから問題ない。んじゃね?
0616名無しさん@お腹いっぱい。2005/07/13(水) 22:52:10
>>612
そこまでいくと、もう…
0617名無しさん@お腹いっぱい。2005/07/13(水) 22:54:49
ttp://www.in-ulm.de/~mascheck/various/shells/
に色々なシステム環境の説明があるな

1)HP-UXでも/bin-->/usr/bin
2)/sbin/shは/usr/bin/sh(sh-posix)のstatic link版
3)昔あったbourne互換シェルは消えた

ってことだ

>>615
てことだから、/sbin/shもterminfo見てるんじゃないかな
0618名無しさん@お腹いっぱい。2005/07/13(水) 23:01:56
>>612
10では、/bin は /usr/bin とは別物なの?
0619名無しさん@お腹いっぱい。2005/07/14(木) 16:55:32
FreeBSDの/bin/shで、コマンドの標準エラー出力を
変数に取り込もうと、

err_message=`hoge 2>&1`

とすると、メッセージが変数に取り込めずに直接表示されてしまいます。
仕方なく、

err_message=`hoge 2>&1 | cat`

と、catをかますとうまくいきます。
これってknown Bugですか?

なお、hoge自体がファイル記述子2に出力していることは確認済みです。
0620名無しさん@お腹いっぱい。2005/07/14(木) 18:03:44
>>619
-current だと以下のように期待通りの動作をしていますけど,
バージョンは?
$ msg=`ls -z 2>&1`
$ echo $msg
ls: illegal option -- z usage: ls [-ABCFGHLPRSTWZabcdfghiklmnopqrstuwx1] [file ...]
$
0621名無しさん@お腹いっぱい。2005/07/14(木) 18:33:50
kshellなんだけど

hoge='ENV_HOGE'

の状態で
環境変数ENV_HOGEにアクセスしたいんだけど
${$hoge} では怒られるんだけど、どう書けばいいのかな、
それともこういうポインタ的なのは_?
0622名無しさん@お腹いっぱい。2005/07/14(木) 18:37:31
>>621
eval でがんばれ。
0623名無しさん@お腹いっぱい。2005/07/14(木) 19:34:29
>>620
$ uname -sr
FreeBSD 5.4-RELEASE
$ err_message=`umask 999 2>&1`
umask: Illegal number: 999$
$ echo "$err_message"

$ err_message=`umask 999 2>&1 | cat`
$ echo "$err_message"
umask: Illegal number: 999
$


つーことで、5.4でもバグってます。
currentでは直ってるんですね?
0624名無しさん@お腹いっぱい。2005/07/14(木) 19:38:29
>>621
eval echo \$$hoge
06256202005/07/14(木) 22:00:34
>>623
commitlog 漁ってみたけど, それらしき patch はあたっていない.
cvs diff -r RELENG_5_4_0_RELEASE やってみたけど, それらしき差分は見当たらない.
なんで, そんな現象になるんだろ?
0626名無しさん@お腹いっぱい。2005/07/15(金) 00:28:32
umaskがビルトイン関数だからじゃないの?
外部コマンドでそうなる例はある?
0627名無しさん@お腹いっぱい。2005/07/15(金) 00:49:01
つくづくFreeBSDはダメだな。
超致命的バグが発見できないとは。
0628名無しさん@お腹いっぱい。2005/07/15(金) 01:17:53
>>626
いくつか試したところ
ok: cd eval alias
ng: umask pwd dot set
ちなみに"AAA=`(umask 999) 2>&1`"は大丈夫だ
06296212005/07/15(金) 01:35:08
>622、624氏
どうもっす。
evalでいいのかな``で囲むやつでがんばってみた。
`env $hoge` でなんとかうまくいきますた。
でもなんつか、ちと格好悪いね。
${${hoge}} の方がポインタちっくでいい感じだと
思うんだけど… (´・ω・`)
0630名無しさん@お腹いっぱい。2005/07/15(金) 01:37:51
>>628
(umaskの場合) ashはsubstitution commandがbuiltinだとsubshellをforkせずに
済ませようとするようです。
bashとpdkshは普通にforkし、ksh93はforkしませんがbash/pdkshと同じ結果を返します。
最適化しようとしてenbugしたっぽいですね。
06316282005/07/15(金) 01:41:09
>>628 cdもevalもサブシェルで実行してたみたいだ。
0632名無しさん@お腹いっぱい。2005/07/15(金) 01:47:11
>>629
要するにPerlのシンボリックリファレンスみたいな機能が欲しかった、と
0633名無しさん@お腹いっぱい。2005/07/15(金) 09:38:24
>>629
> ${${hoge}} の方がポインタちっくでいい感じだと
それって \$$hoge じゃん。
0634名無しさん@お腹いっぱい。2005/07/15(金) 12:04:21
>>629
そう書きたきゃ、
eval echo \${${hoge}}
でできるよ。

あと、 `env $hoge` じゃなくて、
echo `printenv $hoge`
だよね。
0635名無しさん@お腹いっぱい。2005/07/15(金) 12:21:15
>>629
シェルスクリプトにかっこよさを期待されてもな。
0636名無しさん@お腹いっぱい。2005/07/15(金) 13:13:53
ファイルサーバのファイルの世代バックアップのシェルを作らなければならなくて困ってます。

(1)バックアップ作成、ログ取得
# cd /backup   (←作ったDIR)
# tar cvfz backup`date +%Y%m%d`.tar.gz --atime-preserve /home >bulog`date +%Y%m%d`.txt

(2)現在のファイルを取得
# ls -1 | grep backup[0-9][0-9][0-9][0-9][0-1][0-9][0-3][0-9] > now_data.txt

(3)7世代までのファイルを取得
# tail -7 now_data.txt >days_data.txt

(4)2つのファイルを比較、削除ファイル抽出
# diff now_data.txt days_data.txt > differ_data.txt

(5)差分を消す        ←今ここ
# ??? differ_data.txt

な感じで考えてみましたが、行き詰ってます。
diffで差分を拾ってきた結果↓から
-----
[root@xxxxx backup]# cat differ_data.txt
1d0
< backup20050709.tar.gz
-----
1d0 とか < とかを省いて「backup????????.tar.gz」の部分だけを拾ってきたリストを作って、
「rm -f < differ_data.txt」みたいに一発で消せる様に出来ないものなのでしょうか。

#もっとスマートな方法が有ったら教えてくだちぃ…。
0637名無しさん@お腹いっぱい。2005/07/15(金) 13:30:01
>>636
そもそもdump(8)を避けた理由は何かあるんでしょうか?

dumpなら普通に世代バックアップできるし。
dump先を普通のファイルにしておけば、そこからrestore -iで取り出す
手間もtarと大差ないし。
06386372005/07/15(金) 13:31:54
>>637 dump先を普通のファイルにしておけば
これはちょっと勝手に話の先を読みすぎたかも。
関係なかったら無視して。
0639名無しさん@お腹いっぱい。2005/07/15(金) 13:36:26
>>637
早速のレス有り難う御座います。
dumpを避けた理由は…dumpというコマンドを知りませんでした。
手元の「RedHatLinux コマンドリファレンス」に載っていない様で…(汗

とりあえず一旦
man dump
してみます、有り難う御座いましたー!
0640名無しさん@お腹いっぱい。2005/07/15(金) 13:37:44
×コマンドリファレンス
○ポケットリファレンス
(技術評論社)
0641名無しさん@お腹いっぱい。2005/07/15(金) 13:46:58
>>636
diffじゃなくてcommを使う。

rm -f `comm -23 now_data.txt days_data.txt`

で、一発で消せる。

ただし、now_data.txtとかはsort済みのこと。
■ このスレッドは過去ログ倉庫に格納されています