シェルスクリプト総合 その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
0143名無しさん@お腹いっぱい。
2010/03/21(日) 14:17:59BシェルもKシェルも大して変わらんよ
0144名無しさん@お腹いっぱい。
2010/03/21(日) 18:14:29ただ、Bashとは違う
0145名無しさん@お腹いっぱい。
2010/03/22(月) 23:29:11関数に渡す引数の中に、5C問題を起こすコードとスペースが混じっている可能性があるとき、どうやって渡せばいいんでしょう?
Fanc '${hoge}'
だと${hoge}が文字列になってしまうし、
Fanc "${hoge}"
だと5C含みの文字がエスケープされて文字化ける
0146145
2010/03/22(月) 23:31:14上手く変数を展開しつつ、さらにエスケープを抑止する方法はないでしょうか?
よろしくお願いします。
0147名無しさん@お腹いっぱい。
2010/03/23(火) 12:49:02いや ksh は bourne sh とぜんぜん違うでしょ。
機能的には bash の方がよほど近い。
bsh は ${hoge%fuga} とか ${#hoge} とか $((1+1)) とかどれも使えない。
~ がホームディレクトリに展開されないぐらいだし。
0148名無しさん@お腹いっぱい。
2010/03/23(火) 13:05:31今現在 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:370150名無しさん@お腹いっぱい。
2010/03/23(火) 13:30:22最大の根拠がSolarisに現存していたBourne Shellだったわけだが、
SolarisのBourne Shellがなくなったことで、
Bourne Shell互換で記述する意味がなくなってしまったな。。
0151名無しさん@お腹いっぱい。
2010/03/23(火) 13:33:300152名無しさん@お腹いっぱい。
2010/03/23(火) 15:11:32OpenSolaris にも 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:190154名無しさん@お腹いっぱい。
2010/03/23(火) 15:53:36ashやdashぱ posix shellじゃないよ。
たとえば、[[ ]] とかが使えないし、、
0155名無しさん@お腹いっぱい。
2010/03/23(火) 15:56:03かんけーねーだろ。
自分が求める仕事が完結すれば、シェルは何だって良い。
酸いも甘いも理解して使えばいいんだよ
0156名無しさん@お腹いっぱい。
2010/03/23(火) 15:57:41/usr/has/bin/sh は歴史的遺物として置いてあるのであって、
実際のスクリプトで使われていないし、使ってはいけない。
0157名無しさん@お腹いっぱい。
2010/03/23(火) 16:03:34アホくせ
0158名無しさん@お腹いっぱい。
2010/03/23(火) 16:06:380159名無しさん@お腹いっぱい。
2010/03/23(火) 16:48:01夕飯までにcshでちょろっと組むかな
0160名無しさん@お腹いっぱい。
2010/03/23(火) 23:18:150161名無しさん@お腹いっぱい。
2010/03/24(水) 00:22:060162名無しさん@お腹いっぱい。
2010/03/24(水) 01:17:360163名無しさん@お腹いっぱい。
2010/03/24(水) 01:51:480164名無しさん@お腹いっぱい。
2010/03/24(水) 01:56:59はいいんだよ
0165名無しさん@お腹いっぱい。
2010/03/24(水) 02:04:550166名無しさん@お腹いっぱい。
2010/03/24(水) 02:07:000167名無しさん@お腹いっぱい。
2010/03/24(水) 05:51:170168名無しさん@お腹いっぱい。
2010/03/24(水) 06:46:53総称して何と呼べばいいの?
0169名無しさん@お腹いっぱい。
2010/03/24(水) 08:25:510170名無しさん@お腹いっぱい。
2010/03/24(水) 15:41:510171名無しさん@お腹いっぱい。
2010/03/24(水) 16:29:350172名無しさん@お腹いっぱい。
2010/03/24(水) 16:42:410173名無しさん@お腹いっぱい。
2010/03/24(水) 16:49:49http://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:390175名無しさん@お腹いっぱい。
2010/03/24(水) 16:53:500176名無しさん@お腹いっぱい。
2010/03/24(水) 16:54:510177名無しさん@お腹いっぱい。
2010/03/25(木) 00:58:36あるよ。
if [[ ${1} = AAA]] ;then
とか可能
0178名無しさん@お腹いっぱい。
2010/03/25(木) 01:18:04http://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:10letコマンドの動作も変だし。
0180名無しさん@お腹いっぱい。
2010/03/26(金) 01:06:03それ以外なら細かい話もよしではある。
0181名無しさん@お腹いっぱい。
2010/03/26(金) 06:53:420182名無しさん@お腹いっぱい。
2010/03/26(金) 07:08:170183名無しさん@お腹いっぱい。
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:030185183
2010/03/27(土) 22:01:24sed "s/^CCC333/CCCXXX/" file.hoge1
でいけると思ったのですが。。。
solarisのsh,kshです
0186名無しさん@お腹いっぱい。
2010/03/27(土) 22:03:32ならCのあと何でも3文字いけるお
0187183
2010/03/27(土) 22:08:50ありがとう!
0188名無しさん@お腹いっぱい。
2010/03/28(日) 12:50:530189名無しさん@お腹いっぱい。
2010/03/28(日) 12:52:000190名無しさん@お腹いっぱい。
2010/03/28(日) 12:58:36返信thx!
POSIXシェル、Cシェル、キーシェル、コーンシェル
のどれかを今日中にある程度使えるようになりたいんだけど
何か良い方法ないですかねw
参考サイトや本と、実行環境が整えば・・・
0191名無しさん@お腹いっぱい。
2010/03/28(日) 13:13:36サイトなんてぐぐればたくさん出てくる。
0192名無しさん@お腹いっぱい。
2010/03/28(日) 13:15:210193名無しさん@お腹いっぱい。
2010/03/28(日) 14:36:10そうなのですか
家のfedoraでコーンシェルが動かないっぽくて絶望してました
探してみます
>>192
keysh?らしいです
何かはよくわかりません><
0194名無しさん@お腹いっぱい。
2010/03/28(日) 15:10:10ftp://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有難うございます!
超助かりました。
0196名無しさん@お腹いっぱい。
2010/03/28(日) 17:12:562010年にもなってダイアルアップ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:330199名無しさん@お腹いっぱい。
2010/03/30(火) 07:03:23CSVファイルをシェル配列に格納していろいろ加工しようと思っています。
が、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にしたい
何か工夫が必要なんでしょうか?
0200199
2010/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:41IFSって上書きした時の影響範囲ってスクリプト内だけなんですね…全体だと思ってました。
教えていただいたソースで実現できました。
ありがとうございます。
が、もう一度処理を見直した結果、ARRAYの加工と同時に元の${line}も使用するので、
一度lineに格納してから改めてARRAYに分割・格納する必要があることが分かりました。
条件が後出しになってしまって申し訳ありませんが、何か方法はないでしょうか?
0203名無しさん@お腹いっぱい。
2010/03/31(水) 01:35:390204名無しさん@お腹いっぱい。
2010/04/01(木) 06:57:16setを使ってみましたが上手くいかず…
ARRAY=`set - ${line}`
でいけるんですか?
0205名無しさん@お腹いっぱい。
2010/04/01(木) 09:17:38set は $1 $2 $3 ... に値をセットする。
0206名無しさん@お腹いっぱい。
2010/04/01(木) 11:45:07つられちゃったw てへっ?☆
0207名無しさん@お腹いっぱい。
2010/04/01(木) 19:42:04line=',aaa,bbb'
IFS=,
ARRAY=($line)
0208名無しさん@お腹いっぱい。
2010/04/08(木) 06:05:00./a &
./b
これだと、2つめのジョブの終了は待ちますが、1つめはまだバックグランドで実行されている可能性が出てしまいます
0209名無しさん@お腹いっぱい。
2010/04/08(木) 06:19:10./b
wait
0210名無しさん@お腹いっぱい。
2010/04/08(木) 06:41:22./a &
./b &
wait
0211名無しさん@お腹いっぱい。
2010/04/08(木) 09:57:16まじ?
0212名無しさん@お腹いっぱい。
2010/04/08(木) 10:03:250213名無しさん@お腹いっぱい。
2010/04/08(木) 22:52:39前スレか前々スレに確かそんな話題があった
0214名無しさん@お腹いっぱい。
2010/04/28(水) 14:12:30シェルスクリプト(bash)内で、非同期で他のシェルを呼び出したり、
javaコマンドを実行したりしたいのですが、どのように書けばよいのでしょうか。
(戻り値は必要無いです。)
0215名無しさん@お腹いっぱい。
2010/04/28(水) 14:12:540216名無しさん@お腹いっぱい。
2010/04/28(水) 14:29:50bashのmanpageみたら確認できました。
(非同期、で検索してたので見落としてました。)
ありがとうございます。
0217名無しさん@お腹いっぱい。
2010/05/05(水) 04:29:57if文で以下、括弧の違いを教えてくれませんか?
ぐぐっても分からなかった・・・
2重も1重も同じとおもってよいのでしょうか?
if [[ xxxx ]];then
if [ xxxx ];then
0218名無しさん@お腹いっぱい。
2010/05/05(水) 05:17:13シェルスクリプトの中で、
ls /honya/* >> list.txt をしたファイル名使いたいのですが、
Directory や Filenameにメタキャラやらスペースがいっぱい
あります。そんなの作るなって言えれば、いいのですが、ユーザ
さんは、Windowsだし。見てるとそれなりに規則性があって
運用してるんだなってわかります。
話がそれましたが、シェルの中での処理を教えて下さい。
よろしくお願いします。
0219名無しさん@お腹いっぱい。
2010/05/05(水) 07:05:17[[ hoge -a boke ]] は文法エラー
[[ hoge && boke ]] と書く
[ hoge && boke ] は文法エラー
[ hoge -a boke ] と書く
-o と || についても同様。
[[ hoge = h* ]] は真
[ hoge = h* ] は偽(ただしカレントディレクトリにhogeというファイルがあると真)
0220名無しさん@お腹いっぱい。
2010/05/05(水) 07:15:24ファイル名に改行コードが含まれていないなら、
ls /honya/* >> list.txt
while IFS= read -r hoge
do
echo "$hoge"
done < list.txt
の形で処理できる(メタキャラやらスペースもOK)
変数を参照する時には "$hoge" のように必ず " " を付けること。
0221名無しさん@お腹いっぱい。
2010/05/05(水) 08:25:45ありがとうございます。さすがです。
読み込んだファイルを sed か tr 一つづつ 変換して書き出すしか
ないかなぁって思ってました。
こんな方法があるのですね。勉強させていただきました。
0222名無しさん@お腹いっぱい。
2010/05/05(水) 09:29:01>>220のようにlsの結果を使うのは素人。↓こういう仮定を勝手に設定してはいけない。
> ファイル名に改行コードが含まれていないなら、
for fname in /honya/*;do echo "$fname";done
が正しい。
0223名無しさん@お腹いっぱい。
2010/05/05(水) 09:38:47おまえ、もっとアホ
それではファイル名のスペースがもろに分離されてしまって
全く動作しない。
まあ、釣りだろうけど
0224名無しさん@お腹いっぱい。
2010/05/05(水) 09:41:43質問自体が、
「lsの結果のファイルがすでにあって、それを処理するスクリプトが欲しい」
ということなのだから、lsの結果を使うことまでは「前提条件」かと。
0225名無しさん@お腹いっぱい。
2010/05/05(水) 10:55:07分離されねーよ。
恥をかきにのこのこ出てきて… これほどのバカはめったにいない。
>>224
ダメな前提の質問なのだから、正しく処理するスクリプトを作成する事は不可能。が正解。
0226名無しさん@お腹いっぱい。
2010/05/05(水) 11:39:49笑殺させられたくないから、もうひとつ先に言っといてやる。
「ARG_MAX超えたら動作しない」とか言い出すなよ。
確実に5人は笑い死にするぞ。
0227名無しさん@お腹いっぱい。
2010/05/05(水) 13:21:18ありがとうございます。
括弧の数によって、&&や-aの使い方が変わるのですね。
一般的には、二重括弧でよいのでしょうか?
0228名無しさん@お腹いっぱい。
2010/05/05(水) 13:27:30一般的には [ ] の方が良い。
[[ ]] は互換性がないので使わない方がよい。
0229名無しさん@お腹いっぱい。
2010/05/05(水) 18:09:03僕の質問が悪くて、申し訳ありません。
取り敢えず、シェルは完成して、今テスト中です。
結局、シェルの中で、Find -type f して、コマンドに
渡しました。
ここにアップしたら、見てもらえるかなぁなんて都合
良すぎ?
エラー処理とか全然してないんですが・・・。
0230名無しさん@お腹いっぱい。
2010/05/05(水) 18:18:340231名無しさん@お腹いっぱい。
2010/05/05(水) 21:51:50人のことくずとか言うな。
何様?
0232名無しさん@お腹いっぱい。
2010/05/05(水) 21:54:430233名無しさん@お腹いっぱい。
2010/05/05(水) 22:26:27引っ込んでろ。クズ。
0234名無しさん@お腹いっぱい。
2010/05/05(水) 22:36:54おまえさぁ、ここUnix板だぜ。
技術系の板で、あほか。
0235名無しさん@お腹いっぱい。
2010/05/05(水) 22:42:520236名無しさん@お腹いっぱい。
2010/05/05(水) 23:10:59意味不明。引っ込んでろ。クズ。
0237名無しさん@お腹いっぱい。
2010/05/05(水) 23:21:520238名無しさん@お腹いっぱい。
2010/05/06(木) 04:01:37新参乙です(悪いとは言ってない)
さんざんガイシュツ。
ま、ここの人は優しいから俺以外のシッタカが教えてくれます。
0239名無しさん@お腹いっぱい。
2010/05/06(木) 04:30:310240名無しさん@お腹いっぱい。
2010/05/06(木) 12:25:18ローカルと別のマシン hoge.example.net とで同期したいとします。
#!/bin/sh
cd
rsync -avzu -e ssh {tex,org,.emacs.d,.w3m} hoge.example.net:
rsync -avzu -e ssh hoge.example.net:\{tex,org,.emacs.d,.w3m\} .
とすればできますが、この {tex,org,.emacs.d,.w3m} 部分を1つの変数
export FILES="{tex,org,.emacs.d,.w3m}"
のようにしたいのです。これでは {} が展開されず、そんなファイル名はありませんとなります。
for で回すのも手ですが、rsync を何度も呼び出すことになりコストがかさむため一度のrsyncで行いたいのです。
どのようにすればうまく一つの変数に入れられるでしょうか?
0241名無しさん@お腹いっぱい。
2010/05/06(木) 12:48:380242名無しさん@お腹いっぱい。
2010/05/06(木) 12:50:58普通に空白区切りの変数でいいじゃないか
0243名無しさん@お腹いっぱい。
2010/05/06(木) 13:06:20■ このスレッドは過去ログ倉庫に格納されています