トップページunix
988コメント297KB

シェルスクリプト総合 その24©5ch.net

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。 転載ダメ©2ch.net2014/11/11(火) 00:54:03.43
シェルスクリプトの総合スレです。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。
 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でそれらしい単語による簡単な検索もできます。
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)
・シェルスクリプトのことをシェルってゆーな
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 awkまたはperlの方が適した処理にはそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
□回答者への注意事項:
・シェルスクリプトでの処理方法を質問しているのに、よくわからずに
 「そういうのはperl使いましょう」と回答するのはやめましょう。
 安易にperlに逃げずにシェルスクリプトで処理するのが頭のいいやり方。
前スレ
シェルスクリプト総合 その23
http://peace.2ch.net/test/read.cgi/unix/1404204950/
0509名無しさん@お腹いっぱい。2015/05/09(土) 18:51:16.11
if [ -n "$(grep 'bad header' xxxx.log)" ]; then
fi
0510名無しさん@お腹いっぱい。2015/05/09(土) 20:08:36.31
grep -qs "bad header" xxxx.log
case $? in 0) echo "Match";; 1) echo "No match";; *) echo "Error";; esac
0511名無しさん@お腹いっぱい。2015/05/11(月) 21:15:37.13
>>508
これだと判定のたびにログを全部読み直すから無駄無駄
0512名無しさん@お腹いっぱい。2015/05/11(月) 22:56:21.16
>>511
どう直せばいいと思う?
0513名無しさん@お腹いっぱい。2015/05/12(火) 18:27:59.13
bashで
for i in $@
do
command
echo ○○中××番目を処理中です。
done
としたいのですが、○○と××はどうすれば表示できるようになりますか?
0514名無しさん@お腹いっぱい。2015/05/12(火) 19:54:49.92
もう一つ聞きたいことがありました
for i in $@にカレントディレクトリだけじゃなく
そのサブディレクトリのファイルを送るにはどう書けばよいのですか?
0515名無しさん@お腹いっぱい。2015/05/12(火) 19:59:27.57
>>513
count=1
for i in $@
do
echo "$#中${count}番目を処理中です。"
command
count=$(($count + 1))
done
0516名無しさん@お腹いっぱい。2015/05/12(火) 20:00:20.69
コピペから脱却すればその答えはおのずと見つかるであろう
0517名無しさん@お腹いっぱい。2015/05/12(火) 20:18:46.18
わざわざ指摘させる流れですか?もうひとつは残しておいた

in $@ は無駄だな
0518名無しさん@お腹いっぱい。2015/05/13(水) 06:35:40.84
$count の $ は無駄だな。
count=$(($count + 1)) の行自体も無駄とは言わないけどbashなら不要だな。

echo "$#中$(( count++ ))番目を処理中です。"
0519名無しさん@お腹いっぱい。2015/05/13(水) 07:02:23.50
>>518
可読性・保守性が悪いから却下
0520名無しさん@お腹いっぱい。2015/05/13(水) 07:23:59.83
for ((i=1;i<=$#;i++)); do echo "${#}中${i}番目を処理中"; done
0521名無しさん@お腹いっぱい。2015/05/13(水) 07:39:14.30
>>520
それだと肝心の $@ の処理ができないじゃん、本末転倒。
0522名無しさん@お腹いっぱい。2015/05/13(水) 08:39:25.96
$@ をどう処理したいの? 例えばこんな感じ?

for ((i=1;i<=$#;i++)); do eval item=\${$i};echo "${#}中${i}番目($item)を処理中"; done
0523名無しさん@お腹いっぱい。2015/05/13(水) 13:58:41.25
curlでメールチェックできないかと思ったんだけど、どうも参考コードが見当たらないなあ。
もしかしてtelnetのような感じの方法になってスマートには無理なのだろうか?
0524名無しさん@お腹いっぱい。2015/05/13(水) 17:11:23.00
こういうことではなくて?

http://blog.sarabande.jp/post/88910085203
0525名無しさん@お腹いっぱい。2015/05/13(水) 17:26:02.42
送信と受信の違いがわからない男おことわりw
0526名無しさん@お腹いっぱい。2015/05/13(水) 17:49:35.48
ああなるほど、送信がわかれば受信もできるのがわかるから
調べればいいのにと思ったのに
実装されてるコードそのものが欲しかったのね
キミのレベルに合わせられなくてごめんね
0527名無しさん@お腹いっぱい。2015/05/13(水) 17:52:16.16
マニュアル見れば受信できることなんて一目瞭然だよ
0528名無しさん@お腹いっぱい。2015/05/13(水) 19:45:16.01
カウントありがとうございます
サブディレクトリのほうは無理のでしょうか?
0529名無しさん@お腹いっぱい。2015/05/14(木) 01:27:00.37
>>528
$ hogehoge.sh *     カレントディレクトリのファイルだけ
$ hogehoge.sh $(find)  カレントとサブディレクトリ全部
0530名無しさん@お腹いっぱい。2015/05/14(木) 02:06:32.75
>>527
できないなんて話は最初からどこにもないしなあ。

送信と受信の違いというかプロトコル自体が違うんだから参考になるかどうか。
0531名無しさん@お腹いっぱい。2015/05/14(木) 05:00:09.66
マニュアルにPOP3の記載とかあると思うんだが
脳内で>>524=>>527って妄想でもしたか?
0532名無しさん@お腹いっぱい。2015/05/14(木) 06:30:49.15
>>528
IFS=$'\n'
set -- $( find . -type f )
count=0
for i

もしくは、

IFS=$'\n'
fileList="$( find . -type f )"
fileLength=$( echo "$fileList" | wc -l )
count=0
for i in ${fileList}

ところで、v="$( )" のダブルクォートって無駄かな?
0533名無しさん@お腹いっぱい。2015/05/14(木) 07:13:26.75
v= のように直接代入する場合はダブルクォートは無駄。

それより、findでスペース入りファイル名が見つかった場合とかの対応ができてない。
0534名無しさん@お腹いっぱい。2015/05/14(木) 07:25:46.50
findで苦労してスペース入りファイル名の対処するより、

for f in * */* */*/* */*/*/*

って書いちゃった方が早いんだよな。どうせ階層は何段階か有限だし、
アスタリスクならスペース入りでも無問題。
0535名無しさん@お腹いっぱい。2015/05/14(木) 07:27:50.46
> findでスペース入りファイル名が見つかった場合とかの対応
IFS=$'\n'
0536名無しさん@お腹いっぱい。2015/05/14(木) 07:35:52.80
findで改行入りファイル名が見つかった場合とかの対応ができてない
0537名無しさん@お腹いっぱい。2015/05/14(木) 07:44:29.36
> 改行入りファイル名が

それは
IFS=$'\n'
と書いてある時点で、自明じゃない?

指摘自体が無駄だな
0538名無しさん@お腹いっぱい。2015/05/14(木) 07:46:27.90
自明ならバグを作り込んでもいいのかよw 結局使いものにならない
0539名無しさん@お腹いっぱい。2015/05/14(木) 07:49:42.88
シェルなどのコマンドラインの入力に再利用可能な方法でちゃんとエスケープしてファイル名出力できるようなオプションが
findに欲しいな。(スペースも改行もその他記号もちゃんとクォートして、シェルで評価すると元のファイル名に戻る形式)
(-print0 は xargs 用にしか使えないし)
0540名無しさん@お腹いっぱい。2015/05/14(木) 08:06:46.69
やるならこんな感じかな。

$ find . -print0 | while read -r -d $'\0' f; do echo $f; done

それから bash の組み込み関数 printf にある %q が使えるかも

bash$ help printf
:
%q quote the argument in a way that can be reused as shell input
0541名無しさん@お腹いっぱい。2015/05/14(木) 09:04:56.24
while read -rd ''
0542名無しさん@お腹いっぱい。2015/05/14(木) 09:46:33.11
>>531
なぜそういう話になるのかよくわからんが、記載があるならぐだぐだ言うよりコピペで一発なんじゃないか?
0543名無しさん@お腹いっぱい。2015/05/14(木) 10:26:05.55
誰も相手してないのになぜその質問に触れるかなあ・・・
0544名無しさん@お腹いっぱい。2015/05/14(木) 10:28:14.98
read -rd '' とかはbash依存なんだよなぁ。。

read: 1: Illegal option -d
0545名無しさん@お腹いっぱい。2015/05/14(木) 10:36:47.40
>>543
どの質問の話?
0546名無しさん@お腹いっぱい。2015/05/14(木) 11:21:47.00
コマンド置換とシェル関数の違いがピンとこないのですけど
どう違うのでしょか?
0547名無しさん@お腹いっぱい。2015/05/14(木) 11:31:29.33
記載がある筈 なんてはっきりしない話は要らないんだよなあ。
このスレのネタなんて大抵記載がある筈だから。
0548名無しさん@お腹いっぱい。2015/05/14(木) 12:13:05.97
どう勘違いしたらコマンド置換とシェル関数が同じようなものに思えるんだ??
0549名無しさん@お腹いっぱい。2015/05/14(木) 12:15:56.28
>>546
使う分には
・コマンド置換は再利用ができない
・シェル関数は再利用ができる
の違いがある
0550名無しさん@お腹いっぱい。2015/05/14(木) 12:19:07.87
それこそ置き換えの効かない例でも出せば理解するだろ。
0551名無しさん@お腹いっぱい。2015/05/14(木) 12:21:29.00
ll(){ ls -l;}
ll
ってのがシェル関数。

hoge=`ls`
echo "$hoge"
ってのがコマンド置換。

どこも似てない。
0552名無しさん@お腹いっぱい。2015/05/14(木) 12:25:28.02
どう勘違いしたら言語的文法的に似てるかという話に思えるんだ?
0553名無しさん@お腹いっぱい。2015/05/14(木) 12:45:56.98
むしろ似てると思うのは何か根本的な勘違いが原因
0554名無しさん@お腹いっぱい。2015/05/14(木) 13:19:51.91
コマンド置換をaliasと勘違いしてるとか?
0555名無しさん@お腹いっぱい。2015/05/14(木) 13:27:28.77
>>544
今回はbash限定でいい話しだよ。まあ、無駄じゃあないけど

>>513
> bashで
> bashで
> bashで
0556名無しさん@お腹いっぱい。2015/05/14(木) 14:08:51.71
違いを聞くのは別に似てるからじゃないと思うぞ。
単にとある使い方では等価に思えたってだけだろう。
重箱の隅が知りたいみたいな話だな。
0557名無しさん@お腹いっぱい。2015/05/14(木) 14:28:51.82
どう勘違いしたらコマンド置換とシェル関数が等価に思えるような使い方があるんだ??
0558名無しさん@お腹いっぱい。2015/05/14(木) 14:47:51.26
ageてる人が等価に思えるような話だろう。
0559名無しさん@お腹いっぱい。2015/05/14(木) 18:12:58.96
おっしゃる通り、使い方が同じに見えたので
どんな使い分けをしたらいいのだろうと思っていました
0560名無しさん@お腹いっぱい。2015/05/14(木) 19:43:10.96
>>556
いや、その気持ちが分かるなら答えてやれよ。
さっぱり分からん人間には答えようがないんだから。
0561名無しさん@お腹いっぱい。2015/05/14(木) 20:08:14.55
使い分けとか考えなくていいんじゃないの?
期待通りの動作をしない場合がないのかだけ考えれば。
0562名無しさん@お腹いっぱい。2015/05/14(木) 20:38:06.69
>>560
わからなきゃ聞くしかなかろ。
気持ちの想像すらできなければ回答役なんて荷が重いから
黙って見守るべきだと思う。
0563名無しさん@お腹いっぱい。2015/05/14(木) 20:54:02.91
>>562
は?だからお前が適任だろ?って話をしてるんだが?
さてはお前どえらい馬鹿だな?
0564名無しさん@お腹いっぱい。2015/05/14(木) 21:13:48.75
聞こうとしている時にそんな暴言を言うから
気持ちの想像すらできないなんて言われるんですよ。
0565名無しさん@お腹いっぱい。2015/05/14(木) 21:20:34.11
>>564
なんか壮大な勘違いをしてるようだから言っとくけど
お前かなり性格悪そうに見えてるぞ
0566名無しさん@お腹いっぱい。2015/05/14(木) 21:25:29.94
>>561以外になにか言う事でもあるの?
0567名無しさん@お腹いっぱい。2015/05/15(金) 06:21:18.71
echo $(a=A;echo $a)
echo $a

b () {a=A;echo $a;}
b
echo $a

unset a

(a=A)
echo $a

a=A
echo $a

unset a

# 以下zsh。
() {typeset a=A;}
echo $a
() {a=A;}
echo $a
0568名無しさん@お腹いっぱい。2015/05/15(金) 07:08:32.05
色々言ってたけど結局メールチェックは誰も試してないの?
0569名無しさん@お腹いっぱい。2015/05/15(金) 08:03:24.42
curlでやってるよ
IMAPもPOP3も普通に使える
0570名無しさん@お腹いっぱい。2015/05/15(金) 08:50:33.60
./test.sh: 行 5: 予期しないトークン `{a=A' 周辺に構文エラーがあります

b () (a=A;echo $a)
0571名無しさん@お腹いっぱい。2015/05/15(金) 11:06:13.53
ここ見てると昔書いたスクリプトについて
あのコマンドはああするべきだったとか思うことはあるけど
曲がりなりにも期待した動作はしてたから問題ないと思い直した
0572名無しさん@お腹いっぱい。2015/05/15(金) 13:23:55.72
>>570
そう。そこに違いがある事が言いたかった。
0573隼人新聞社2015/05/15(金) 17:26:05.10
★サヨクを応援して1票入れた人は強く反省してください

★民主 枝 野 は殺人を平気で行う極左テロ暴力団と親密交際があった!!!親密交際!テロの手先!北朝鮮の手先(安倍総理の談話)

★   菅 直 人 は朝鮮人と親密交際、献金があった!!朝鮮韓国の傀儡手先(TVで報道!)

★民主は日教組の巣窟。極めて危険な団体、危険な政権だった!北朝鮮を熱烈に支援するのが日教組(信頼できる情報スジの話)!!北朝鮮の手先!

民主の基本姿勢は死刑廃止!!だから自民の安倍総理を支援してください!

サヨクと公明創価を応援するは地獄行き

サヨクを応援して1票入れた人は反省してください
0574名無しさん@お腹いっぱい。2015/05/16(土) 18:18:52.70
キー入力を受け付けを待って止まっているコマンドを
何らかの方法で次のコマンドに行かせる方法はありますか?
0575名無しさん@お腹いっぱい。2015/05/16(土) 18:38:27.01
zshだとzpty
tclだとexpect
ただ単純な事なら
command<<EOF
y
y
n
EOF
とかこんなんで処理できるよ。
0576名無しさん@お腹いっぱい。2015/05/16(土) 18:41:48.45
マウスつかってどうのこうのの話なら、xdotoolとかいうのが使えそう。
plamolinuxのこじま氏の2015/1/8の日記に少し使い方が書いてある。
0577名無しさん@お腹いっぱい。2015/05/17(日) 09:38:15.41
>>575, >>576
ありがとう
早速、調べてみます
今までできないものと思って諦めていたから感動
0578名無しさん@お腹いっぱい。2015/05/17(日) 18:06:01.98
freebsdのスレッドの人なのかなと思ったので以下でできたよ。詳しい事は知らない。
最近はbashのほうが強力なのかもしれないし、おそらく似た機能はあると思う。
ただexpectが定番だと思う。ただ構文はtclだけど、
たぶん他のshellを使うのって嫌な部分があるだろうし。

# まず以下のpasswordの部分を書いて、試して、感じる。
expect -c '
spawn su
expect Password:
send "your password\r"
interact
'

# passwordとpromptの指定の部分を書換える必要があると思う。
expect -c '
spawn su ;# expectで制御できるようにsuを起動する。
expect Password: ;# promptにPassword:が来るまで待機。
send "your password\r" ;# 来たら引数で指定されたpasswordを入力する。
expect -re {(%|#|\\$) $} ;# Password:が来るまで待機になってたものを、
;# promptの入力受け付け画面に変える。
;# -reは正規表現。ここはmanpageそのまま写しました。
;# 各々によって変える必要があるでしょう。

send "whoami\r"
send "exit\r"
expect eof
'
0579名無しさん@お腹いっぱい。2015/05/19(火) 17:38:24.79
forやwhileとかの中でコマンドを実行するとき
そのコマンドをforやwhileに直接書いて実行させるか
変数扱いさせてのforやwhile上にコマンドを書いて実行させるか
関数として定義してやってforやwhileの中で実行させてやるか
どれが効率的で高速に実行することができるようになるんだろう?
コマンドの呼び出しや実行や終了の重複を考えるとどうなんだろう?
シェルスクリプトを自分で書けるようになってきて、こんな疑問を持つようになりました
皆さんの意見を聞かせて下さい
0580名無しさん@お腹いっぱい。2015/05/19(火) 17:45:28.31
高速っていうなら直接コマンド記述が高速。
for/whileループであっても、ループ内をキャッシュしたりせず、
毎回コマンド行とか変数とか関数を評価し直しながら実行してる。
しかしシェルスクリプトに高速性なんて求めてはいけない。
0581名無しさん@お腹いっぱい。2015/05/19(火) 20:08:13.54
そもそも高速化ってそういう事じゃないしな。
何回そのプログラムを実行すれば、そんな間違った高速化の為に費した時間を取り戻せると思う?
0582名無しさん@お腹いっぱい。2015/05/19(火) 21:29:44.56
高速化したいならプログラム書くしかない
プロセスを起動するコストは莫大だから
0583名無しさん@お腹いっぱい。2015/05/19(火) 21:54:05.59
iniファイルを読み書きして、ファイル名をキーにしてすでに処理済みのファイルかどうかを条件判定、
みたいなことをbusyboxに内包された汎用コマンドだけでやるには、どうしたらいい?

決められたディレクトリの中に、リサイズしたいjpg画像群があって、
処理済みかどうかを条件分岐したかったんだけど、時間が無くて別のツールで
間に合わせてしまった。再びやりたくて調べてみたけど、実装事例を見つけられず。
0584名無しさん@お腹いっぱい。2015/05/19(火) 22:48:04.62
busyboxでやりたいならそちらでどうぞ

ちなみにシェルスクリプトでやるならlsでリスト作って
ループしながら処理すればいいと思う
処理済はどこかのファイルにファイル名を書き出して
ループでの処理前にその中にファイルがあるかどうかgrepなどで見て
無ければ処理すればいい

あとなんとなく579=583臭がするけど気のせいか
0585名無しさん@お腹いっぱい。2015/05/19(火) 22:58:05.98
ありがと。大きなヒントをもらえたので、作ってみる。

ちなみに同一人物じゃないよ。
0586名無しさん@お腹いっぱい。2015/05/20(水) 11:34:26.93
>>581, >>582
ドツボにはまりかけてました
d

>>584
妄想、乙
0587名無しさん@お腹いっぱい。2015/05/20(水) 13:31:28.02
なんだコイツ
0588名無しさん@お腹いっぱい。2015/05/20(水) 17:55:29.75
よう、ネット番長
0589名無しさん@お腹いっぱい。2015/05/20(水) 18:12:52.71
こんな>>579
何言いたいか曖昧な事にまともに答えてくれた人に感謝する事だね。
私は何も答えなかったよ。それこそ妄想、乙と感じたしね。
0590名無しさん@お腹いっぱい。2015/05/20(水) 18:24:21.97
× 答えなかった
○ 答えられなかった(コミュ能力不足)
0591名無しさん@お腹いっぱい。2015/05/20(水) 18:27:39.23
まぁある意味答えられなかったとは言えるな。
認めよう。
0592名無しさん@お腹いっぱい。2015/05/20(水) 18:33:19.73
少なくとも、ほかの人はある程度の要求仕様をくみ取るところまでは出来たわけだから、
コミュ能力であることは明白。キミさー、これじゃ仕事できないよ。
0593名無しさん@お腹いっぱい。2015/05/20(水) 18:38:02.12
そうだねバファリンの半分が優しさでできているのだとしたら、
彼等は九割方優しさで出来てるといえるね。
0594名無しさん@お腹いっぱい。2015/05/20(水) 19:11:05.53
追っ払っといた。以降スルーで。
あいつはおたくらが汚いレスする値打ちも無い。だからこそ俺の様な男がいるのさ。
0595名無しさん@お腹いっぱい。2015/05/21(木) 06:15:13.14
-gt の利点について教えてください。
[ HOGE -gt 123 ]
は、
((HOGE > 123))
とも記述できますよね? なら -gt の必要性はあるのでしょうか?
0596名無しさん@お腹いっぱい。2015/05/21(木) 10:47:36.25
>>569
一体どういう書式のどんな結果をどうやって受け取っているのか、参考までに見せて欲しい。
0597名無しさん@お腹いっぱい。2015/05/21(木) 13:10:57.30
>>595
前者はbourne shellから使える一般的な方法
後者は一部のシェルの拡張機能で、使えない場合がある。
使えるならどっちでもいい。上で出てたbusyboxのshだと使えないんじゃないかな多分
0598名無しさん@お腹いっぱい。2015/05/21(木) 15:22:40.17
>>595
数値比較だから16進や8進表現が使える
0599名無しさん@お腹いっぱい。2015/05/21(木) 16:10:57.08
>>598
-gt の利点として??
0600名無しさん@お腹いっぱい。2015/05/21(木) 16:34:31.27
利点欠点というより
数値比較と文字列比較で機能が異なるので
比べるものじゃない
0601名無しさん@お腹いっぱい。2015/05/21(木) 17:02:11.38
[ -gt ] も (( > )) も、数値としての比較だが、、
0602名無しさん@お腹いっぱい。2015/05/21(木) 17:12:42.96
ごめ、誤解してたわ
0603名無しさん@お腹いっぱい。2015/05/21(木) 22:58:30.82
>>596
いくら?
0604名無しさん@お腹いっぱい。2015/05/22(金) 10:22:56.55
まず自分なりに作ったサンプル出してからうまくいかないと相談すればいいのに
はなから見せろとか無いわ〜
0605名無しさん@お腹いっぱい。2015/05/22(金) 11:00:25.39
#/bin/sh
curl

ほい
0606名無しさん@お腹いっぱい。2015/05/22(金) 11:11:39.20
すみませんが詳しい方のみ回答をお願いします
0607名無しさん@お腹いっぱい。2015/05/22(金) 11:19:33.89
>>605
ドキュメント読んで出直してこい
0608名無しさん@お腹いっぱい。2015/05/22(金) 11:36:29.05
やだね

(echo USER hoge; echo PASS pass; echo STAT) | nc server 110
■ このスレッドは過去ログ倉庫に格納されています