トップページ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
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が落ちたわけではないんだと言ってるんだけど。
0136名無しさん@お腹いっぱい。2010/03/18(木) 08:23:16
シェルって言ってるクズを相手にすんなよ。
0137名無しさん@お腹いっぱい。2010/03/18(木) 08:24:35
tr とか dos2unix(笑)とかの外部コマンドを使うより、

IFS= の中に ^M を入れておくと readの際に自動的に CR を落してくれる。
これが最適解。
0138名無しさん@お腹いっぱい。2010/03/18(木) 17:02:54
デフォルトのIFSって何だっけ?
0139名無しさん@お腹いっぱい。2010/03/18(木) 17:08:36
スペース・タブ・LF
0140名無しさん@お腹いっぱい。2010/03/18(木) 17:32:38
IFSって?
0141名無しさん@お腹いっぱい。2010/03/18(木) 17:45:17
International FreeBSD School
0142名無しさん@お腹いっぱい。2010/03/18(木) 17:51:24
OK, 願書もらってくる!

bakanisareta... orz
0143名無しさん@お腹いっぱい。2010/03/21(日) 14:17:59
>>76
BシェルもKシェルも大して変わらんよ
0144名無しさん@お腹いっぱい。2010/03/21(日) 18:14:29
というか、Kシェルはclassic Bシェルの拡張の一つ
ただ、Bashとは違う
0145名無しさん@お腹いっぱい。2010/03/22(月) 23:29:11
質問させてください。

関数に渡す引数の中に、5C問題を起こすコードとスペースが混じっている可能性があるとき、どうやって渡せばいいんでしょう?

Fanc '${hoge}'
だと${hoge}が文字列になってしまうし、

Fanc "${hoge}"
だと5C含みの文字がエスケープされて文字化ける
01461452010/03/22(月) 23:31:14
変なところで改行してしまいました。申し訳ないです。

上手く変数を展開しつつ、さらにエスケープを抑止する方法はないでしょうか?

よろしくお願いします。
0147名無しさん@お腹いっぱい。2010/03/23(火) 12:49:02
>>143
いや ksh は bourne sh とぜんぜん違うでしょ。
機能的には bash の方がよほど近い。

bsh は ${hoge%fuga} とか ${#hoge} とか $((1+1)) とかどれも使えない。
~ がホームディレクトリに展開されないぐらいだし。
0148名無しさん@お腹いっぱい。2010/03/23(火) 13:05:31
>>147
今現在 B-shと言ったら、*BSDの ash または debianの dash相当のシェルを指す。
で、その B-shでは、${hoge%fuga} とか ${#hoge} とか $((1+1)) とか
すべて使える。

ちなみに、OpenSolarisからはBourne-shが消えて、
/bin/shは kshへのsymlinkになってる。
0149名無しさん@お腹いっぱい。2010/03/23(火) 13:23:37
bash > ksh > {d,}ash
0150名無しさん@お腹いっぱい。2010/03/23(火) 13:30:22
「Bourne Shellの文法の範囲内でのみ記述すること」の主張の
最大の根拠がSolarisに現存していたBourne Shellだったわけだが、
SolarisのBourne Shellがなくなったことで、
Bourne Shell互換で記述する意味がなくなってしまったな。。
0151名無しさん@お腹いっぱい。2010/03/23(火) 13:33:30
>>145
0152名無しさん@お腹いっぱい。2010/03/23(火) 15:11:32
>>150
OpenSolaris にも bourne sh はあるよ。
パスが /usr/has/bin/sh に変わったけど。

>>148
>今現在 B-shと言ったら、*BSDの ash または debianの dash相当のシェルを指す。

これ、ふつー posix shell といわない?
>>144 は classic Bシェルという言葉を出してるわけだし、
昔からの bourne sh の方を言ってると考えるのが妥当じゃないかと。
0153名無しさん@お腹いっぱい。2010/03/23(火) 15:22:19
シェル雑談はいいから
0154名無しさん@お腹いっぱい。2010/03/23(火) 15:53:36
>>152
ashやdashぱ posix shellじゃないよ。

たとえば、[[ ]] とかが使えないし、、
0155名無しさん@お腹いっぱい。2010/03/23(火) 15:56:03
つーか、あれが使えないとか、コレが欠陥なんて
かんけーねーだろ。
自分が求める仕事が完結すれば、シェルは何だって良い。

酸いも甘いも理解して使えばいいんだよ
0156名無しさん@お腹いっぱい。2010/03/23(火) 15:57:41
>>152
/usr/has/bin/sh は歴史的遺物として置いてあるのであって、
実際のスクリプトで使われていないし、使ってはいけない。
0157名無しさん@お腹いっぱい。2010/03/23(火) 16:03:34
言えてる。別システムで使う予定も無いくせにな
アホくせ
0158名無しさん@お腹いっぱい。2010/03/23(火) 16:06:38
一昔前ならいざ知らず、未だにこんな事言ってる化石がいるから衰退すんだよ。
0159名無しさん@お腹いっぱい。2010/03/23(火) 16:48:01
さーて
夕飯までにcshでちょろっと組むかな
0160名無しさん@お腹いっぱい。2010/03/23(火) 23:18:15
[[ ]] はPOSIX shellの仕様に無いと思ったが
0161名無しさん@お腹いっぱい。2010/03/24(水) 00:22:06
こまけぇことはいいんだよ
0162名無しさん@お腹いっぱい。2010/03/24(水) 01:17:36
ごもっとも。
0163名無しさん@お腹いっぱい。2010/03/24(水) 01:51:48
このスレからこまけぇことを取ったら何が残るんだよ
0164名無しさん@お腹いっぱい。2010/03/24(水) 01:56:59
>>163
はいいんだよ
0165名無しさん@お腹いっぱい。2010/03/24(水) 02:04:55
敗因…
0166名無しさん@お腹いっぱい。2010/03/24(水) 02:07:00
イーンダヨ!
0167名無しさん@お腹いっぱい。2010/03/24(水) 05:51:17
グリーンだよ
0168名無しさん@お腹いっぱい。2010/03/24(水) 06:46:53
ashみたいに、posixシェルでもBourneシェルでもないBシェルを
総称して何と呼べばいいの?
0169名無しさん@お腹いっぱい。2010/03/24(水) 08:25:51
糞シェル
0170名無しさん@お腹いっぱい。2010/03/24(水) 15:41:51
ラルク・アン・シェル
0171名無しさん@お腹いっぱい。2010/03/24(水) 16:29:35
クミコ・タケダ・オン・シェル
0172名無しさん@お腹いっぱい。2010/03/24(水) 16:42:41
シェル・ファントムハイヴ
0173名無しさん@お腹いっぱい。2010/03/24(水) 16:49:49
★お待たせしました★ユーズド&B級ユーズド販売復活!

http://www.ioplaza.jp/shop/genre/genre.aspx?genre=09outtop&affiliate=TP100323B1#useditem
ユーズドアイテム公開日: 3月24日 (水) 19:30〜

http://www.ioplaza.jp/shop/genre/genre.aspx?genre=09outtop&affiliate=TP100323B1#reusememory
B級ユーズドアイテム公開日: 3月24日 (水) 20:15〜

I-O OUTLET はアイオープラザ会員様限定の特別販売コーナーです。
アイオー製品のワケあり掘り出し物がタイムセールスで大放出。是非ご来店をお待ちしております。

※なお、ご利用には会員登録が必要です(登録無料)。
0174名無しさん@お腹いっぱい。2010/03/24(水) 16:50:39
エコール・デュ・シェル
0175名無しさん@お腹いっぱい。2010/03/24(水) 16:53:50
マイヨ・アルカンシェル
0176名無しさん@お腹いっぱい。2010/03/24(水) 16:54:51
銀と真紅のアルカンシェル
0177名無しさん@お腹いっぱい。2010/03/25(木) 00:58:36
>>160
あるよ。
if [[ ${1} = AAA]] ;then
とか可能
0178名無しさん@お腹いっぱい。2010/03/25(木) 01:18:04
>>177
http://www.opengroup.org/onlinepubs/009695399/utilities/test.html
The KornShell-derived conditional command (double bracket [[]]) was removed
from the shell command language description in an early proposal.
0179名無しさん@お腹いっぱい。2010/03/25(木) 07:39:10
ashには、$(( )) はあっても、(( )) がないな。
letコマンドの動作も変だし。
0180名無しさん@お腹いっぱい。2010/03/26(金) 01:06:03
仕事の時は細かいことはどーでもいーが、
それ以外なら細かい話もよしではある。
0181名無しさん@お腹いっぱい。2010/03/26(金) 06:53:42
(( )) はPOSIX shellの仕様に無いと思ったが
0182名無しさん@お腹いっぱい。2010/03/26(金) 07:08:17
こまけぇことはいいんだよ
0183名無しさん@お腹いっぱい。2010/03/27(土) 21:42:06
教えていただきたい
例えば以下のようなテキストファイル、file.hoge1があるとします。

AAA111ZZZZ
BBB222ZZZZ
CCC333ZZZZ
DDD444ZZZZ

これに対して、先頭CCCで始まるレコードの4カラム目から3カラム
つまり「333」を「XXX」にしたい。
AAA111ZZZZ
BBB222ZZZZ
CCCXXXZZZZ
DDD444ZZZZ

しかし「333」の位置には半角3バイトではあるが必ずしも「333」が入っている訳ではなく
何が入ってるかは一定でない。

これの解をお願いします。
0184名無しさん@お腹いっぱい。2010/03/27(土) 21:49:03
sedでいいんじゃね?
01851832010/03/27(土) 22:01:24
333が固定なら

sed "s/^CCC333/CCCXXX/" file.hoge1

でいけると思ったのですが。。。

solarisのsh,kshです
0186名無しさん@お腹いっぱい。2010/03/27(土) 22:03:32
s/^CCC.../CCCXXX/
ならCのあと何でも3文字いけるお
01871832010/03/27(土) 22:08:50
その記述だ!
ありがとう!
0188名無しさん@お腹いっぱい。2010/03/28(日) 12:50:53
POSIX?shellとBourneShellって同じものでしょうか?
0189名無しさん@お腹いっぱい。2010/03/28(日) 12:52:00
全然違います
0190名無しさん@お腹いっぱい。2010/03/28(日) 12:58:36
>>189
返信thx!

POSIXシェル、Cシェル、キーシェル、コーンシェル
のどれかを今日中にある程度使えるようになりたいんだけど
何か良い方法ないですかねw

参考サイトや本と、実行環境が整えば・・・
0191名無しさん@お腹いっぱい。2010/03/28(日) 13:13:36
環境なんてどこにでもあるし
サイトなんてぐぐればたくさん出てくる。
0192名無しさん@お腹いっぱい。2010/03/28(日) 13:15:21
キーシェルってなんだろう。昭和シェルなら知ってる
0193名無しさん@お腹いっぱい。2010/03/28(日) 14:36:10
>>191
そうなのですか
家のfedoraでコーンシェルが動かないっぽくて絶望してました
探してみます

>>192
keysh?らしいです
何かはよくわかりません><
0194名無しさん@お腹いっぱい。2010/03/28(日) 15:10:10
>>193
ftp://ftp.kddilabs.jp/Linux/distributions/fedora/releases/12/Everything/i386/os/Packages/ksh-20090630-1.fc12.i686.rpm
0195名無しさん@お腹いっぱい。2010/03/28(日) 15:20:17
>>194
有難うございます!
超助かりました。
0196名無しさん@お腹いっぱい。2010/03/28(日) 17:12:56
シェル童貞から質問です
2010年にもなってダイアルアップuucp環境を構築しようとしています('A`)
cronで一定時間毎にuucpキューをチェックして、1つでも中身があればuucicoで
ダイアルアップ接続・・・という事をしたいのですが正直構文がわかりません

uustat -q|wc -lでキューの中身をカウントし、0じゃなければuucicoを実行したいのですが・・・

#!/bin/sh
uustat -q|wc -l
val=$?
if test ${val} -ne 0
then
/usr/sbin/uucico -s uucp-domain
else
echo "no mail in uucp queue."
fi
exit 0

考えたら"wc -l"は行数を表示するコマンドで戻り値は成功すれば0なので
$?も0だから上記の記述じゃ条件が常に偽になりますわな ○<\_
戻り値じゃなくてwc -lの表示結果の数値を変数に格納する方法を教えて下さい
0197名無しさん@お腹いっぱい。2010/03/28(日) 17:22:33
status=`uustat -q|wc -l`
01981962010/03/28(日) 17:53:58
>>197
できました!
本気でありがとう
0199名無しさん@お腹いっぱい。2010/03/30(火) 07:03:23
スクリプト初心者にアドバイスをお願いします。

CSVファイルをシェル配列に格納していろいろ加工しようと思っています。

が、CSVに空の項目がある場合に上手く格納できず、空項目を無視してしまいます。

------------ソース-------------
cat ${file} | while read line

eval ARRAY="(`cat ${line} | awk {'print $1,$2,$3'}`)"
→以降ARRAYを加工
----------ソースここまで---------

これを実行すると
AAA,BBB,CCC →ARRAY[0] =AAA,ARRAY[1] =BBB,ARRAY[2] =CCC
⇒ 想定通り
,BBB,CCC →ARRAY[0] =BBB,ARRAY[1] =CCC
⇒ ARRAY[0]=””,ARRAY[1] =BBB,ARRAY[2] =CCCにしたい

何か工夫が必要なんでしょうか?
02001992010/03/30(火) 07:28:56
間違えました…

× awk {'print $1,$2,$3'}
○ awk -F , {'print $1,$2,$3'}
0201名無しさん@お腹いっぱい。2010/03/30(火) 08:29:01
やっつけ
#!/bin/bash
file=hoge.csv
cat ${file} | while IFS=, read ARRAY[0] ARRAY[1] ARRAY[2]; do
echo 0: ${ARRAY[0]}
echo 1: ${ARRAY[1]}
echo 2: ${ARRAY[2]}
done
0202名無しさん@お腹いっぱい。2010/03/30(火) 21:39:41
>>201
IFSって上書きした時の影響範囲ってスクリプト内だけなんですね…全体だと思ってました。
教えていただいたソースで実現できました。
ありがとうございます。

が、もう一度処理を見直した結果、ARRAYの加工と同時に元の${line}も使用するので、
一度lineに格納してから改めてARRAYに分割・格納する必要があることが分かりました。

条件が後出しになってしまって申し訳ありませんが、何か方法はないでしょうか?
0203名無しさん@お腹いっぱい。2010/03/31(水) 01:35:39
set - $line
0204名無しさん@お腹いっぱい。2010/04/01(木) 06:57:16
>>203
setを使ってみましたが上手くいかず…

ARRAY=`set - ${line}`
でいけるんですか?
0205名無しさん@お腹いっぱい。2010/04/01(木) 09:17:38
>>204
set は $1 $2 $3 ... に値をセットする。
0206名無しさん@お腹いっぱい。2010/04/01(木) 11:45:07
あぁ、釣りか。

つられちゃったw てへっ?☆
0207名無しさん@お腹いっぱい。2010/04/01(木) 19:42:04
>>202

line=',aaa,bbb'
IFS=,
ARRAY=($line)
0208名無しさん@お腹いっぱい。2010/04/08(木) 06:05:00
シェルスクリプトで2つのジョブを同時に実行した後、両方が終了するのを待つにはどうのようにしたらよいのでしょうか?

./a &
./b
これだと、2つめのジョブの終了は待ちますが、1つめはまだバックグランドで実行されている可能性が出てしまいます
0209名無しさん@お腹いっぱい。2010/04/08(木) 06:19:10
./a &
./b
wait
0210名無しさん@お腹いっぱい。2010/04/08(木) 06:41:22
または
./a &
./b &
wait
0211名無しさん@お腹いっぱい。2010/04/08(木) 09:57:16
>>210
まじ?
0212名無しさん@お腹いっぱい。2010/04/08(木) 10:03:25
まじ。
■ このスレッドは過去ログ倉庫に格納されています