シェルスクリプト総合 その22
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
2013/11/01(金) 07:58:50.52□お約束
・特記なき場合は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に逃げずにシェルスクリプトで処理するのが頭のいいやり方。
前スレ
シェルスクリプト総合 その21
http://toro.2ch.net/test/read.cgi/unix/1352973453/
0730名無しさん@お腹いっぱい。
2014/05/20(火) 18:17:56.34rubyが駄目だと言うのなら、次に考えるのはawkかsedだろ。常識的に考えて。
0731名無しさん@お腹いっぱい。
2014/05/20(火) 18:33:31.84rubyは入れる物を多少選べば排除できるが、perlへの依存を全て排除するのは無理ではないが結構面倒だろう。
0732名無しさん@お腹いっぱい。
2014/05/20(火) 18:54:13.540733名無しさん@お腹いっぱい。
2014/05/20(火) 19:05:06.070734名無しさん@お腹いっぱい。
2014/05/20(火) 19:29:20.61ビルトインとsedとawkで大抵こと足りるからな。perl使うのに多いのはライブラリ使いたい時とか。
でもそうするとpythonやrubyの方が最近のものがある気がする。pmとかまだ作られてるの?
0735名無しさん@お腹いっぱい。
2014/05/21(水) 00:06:27.58一行野郎と言えば「awkは書かねぇ、たった一行」だろ?
0736名無しさん@お腹いっぱい。
2014/05/21(水) 03:32:28.760737名無しさん@お腹いっぱい。
2014/05/21(水) 05:00:52.020738名無しさん@お腹いっぱい。
2014/05/21(水) 08:41:33.680739名無しさん@お腹いっぱい。
2014/05/21(水) 08:47:53.28rubyを入れなくても何にも困ってない rails?()
perlを入れてないとコンパイルできないものが結構ある(PostgreSQLとか)
ruby信者の視野狭窄は異常
0740名無しさん@お腹いっぱい。
2014/05/21(水) 09:18:31.410741名無しさん@お腹いっぱい。
2014/05/21(水) 09:41:02.86コンパイルの依存関係にperl入れるのは辞めてほしい
0742名無しさん@お腹いっぱい。
2014/05/21(水) 10:01:39.33autotoolsに依存するより全然まし
0743名無しさん@お腹いっぱい。
2014/05/21(水) 10:02:56.580744名無しさん@お腹いっぱい。
2014/05/21(水) 17:28:29.71コンパイルの依存関係にrubyやpythonが入るより少しはマシ
って言おうかと思ったけど自分の遭遇トラブルはperl依存モノの方が多かったorz
>>742
コンパイル省力化に高機能なツールや言語を使い出して、
今度はそっちの互換性問題が火を噴くとか本末転倒にもホドがある…
最小限のシェルスクリプトかMakefileで済む奴が一番気楽だわ
0745名無しさん@お腹いっぱい。
2014/05/21(水) 17:39:42.30その分野ではrubyやpythonは使われてないからだろ。特にrubyは日本限定末端土方専用だから。
使われてなきゃトラブルには遭遇しない。当たり前だ。
0746名無しさん@お腹いっぱい。
2014/05/21(水) 17:42:51.81perlのアップデートとかなったら阿鼻叫喚の渦
あと何かのプロジェクトで頑張ってperl依存をなくしたってニュースになったな
perlは撲滅すべき悪ではあるがまだ依存関係から取り除けてない害虫みたいなもんなんだろう
0747名無しさん@お腹いっぱい。
2014/05/21(水) 18:01:29.51お、懐かしいね。Canna じゃまだ使われているのかな?
0748名無しさん@お腹いっぱい。
2014/05/21(水) 18:15:59.05昔はこんなのを↓よくやってたけどね
$ perl -pi.bak -e 's:#!/usr/bin/perl:#!/usr/local/bin/perl:' *.pl
最近使ったのは…Run Length Encoding かな
$ echo '......' | perl -pe 's/(.)(\1+)/$1.(length($2)+1)/ge'
RLEって sed や awk, UNIX tools を組み合わせて one liner でできるのかな…
0749名無しさん@お腹いっぱい。
2014/05/21(水) 18:35:56.58お察しの通りFreeBSDだが、FreeBSDは脱GPL脱GCCの実績が有るし今後に期待?
0750名無しさん@お腹いっぱい。
2014/05/21(水) 20:41:31.00http://rosettacode.org/wiki/Run-length_encoding
ぐぐったらsed版とawk版があるな
つーかrun length encodingって必要になった状況ないな
0751名無しさん@お腹いっぱい。
2014/05/22(木) 00:16:14.560752名無しさん@お腹いっぱい。
2014/05/22(木) 09:09:18.24運用しているサーバを私は見たことがありません。
でも perl が入ってないサーバって、実は世の中には結構あるんですかね?
0753名無しさん@お腹いっぱい。
2014/05/22(木) 09:30:02.07じょ、冗談で書いてるんだよね?
0754名無しさん@お腹いっぱい。
2014/05/22(木) 10:12:42.49というと?
0755名無しさん@お腹いっぱい。
2014/05/22(木) 12:16:17.560756名無しさん@お腹いっぱい。
2014/05/22(木) 12:20:57.50必要なら入れれば?な感じ。
0757名無しさん@お腹いっぱい。
2014/05/22(木) 15:33:22.17その言語自身のセクションと、libsは除いてみた。
$ for l in perl python ruby ;do echo -n "$l ";aptitude search ~D$l\!~s$l\!~slibs|wc -l;done
perl 962
python 1603
ruby 204
0758名無しさん@お腹いっぱい。
2014/05/22(木) 15:41:24.610759名無しさん@お腹いっぱい。
2014/05/22(木) 21:37:53.41それでタイプ量の多さに失望するんですね。
0760名無しさん@お腹いっぱい。
2014/05/24(土) 11:07:22.49sh系なら-e''の中に改行含めれるし。
最近はもう、awkをさけるようになったなぁ
なんで正規表現の互換性をなくしてしまったのか。
0761名無しさん@お腹いっぱい。
2014/05/24(土) 11:56:11.33autotoolsって、シェルスクリプトとm4とmakeで
できてるから、このスレ的には新参スクリプト言語よりは
歓迎なんじゃないかって気がするw
0762名無しさん@お腹いっぱい。
2014/05/24(土) 21:11:49.14「auto」toolsはマニュアルで修正しないとコンパイル通らない場合が…
0763名無しさん@お腹いっぱい。
2014/05/24(土) 21:55:46.180764名無しさん@お腹いっぱい。
2014/05/25(日) 14:19:48.290765名無しさん@お腹いっぱい。
2014/05/29(木) 00:34:01.910766名無しさん@お腹いっぱい。
2014/05/29(木) 17:22:41.57もう、何年も前からcshは入ってないが何も不都合は生じてない
0767名無しさん@お腹いっぱい。
2014/06/07(土) 16:19:13.77プログレスバーを作って待ち時間のストレスを抑えようと思う
今何%進んでるかは実行行/全体行で簡単に分かるんだが、これを画面上に出力する時に、
単純に計算結果を出力するだけだと
[05%]・・・・・
[06%]・・・・・・
[07%]・・・・・・・
という風に毎回改行されて表示されて画面が汚くなるのが嫌だ
つまり何が聞きたいかというと、既に出力された結果を書き換えるような仕組みはshで実現可能なのだろうか
分かりにくくてすまない
0768名無しさん@お腹いっぱい。
2014/06/07(土) 16:20:12.71^M
0769名無しさん@お腹いっぱい。
2014/06/07(土) 16:26:43.020770名無しさん@お腹いっぱい。
2014/06/07(土) 16:34:33.530771名無しさん@お腹いっぱい。
2014/06/07(土) 16:57:46.030772名無しさん@お腹いっぱい。
2014/06/07(土) 17:01:08.23ありがとう。tputを初めて知ったが、勉強してみる
しかし^Mがわからん。何のことだ
>>771
echo -nで改行無し出力は出来るから、いわゆる伸びていく棒は再現出来た
が、すでに出力したn%のnを書き換えるような操作が出来ない
printfはそういうの出来るんだろうか?
0773名無しさん@お腹いっぱい。
2014/06/07(土) 17:17:09.83コントロール-Mを知らんのか? キャリッジリターンだぞ。カーソルは左端に戻る。
0774名無しさん@お腹いっぱい。
2014/06/07(土) 17:23:46.19いや^MがCtrl-Mなのは知ってたけどそんな効果あったのか
次会社いったら試してみる、ありがとう
ついでに調べてたら、某ブログでecho "\r\c"なるものを目撃した
これも同じ意味かな
0775名無しさん@お腹いっぱい。
2014/06/07(土) 17:34:07.91もしNetBSDならprogress(1)に逃げるって手もある
0776名無しさん@お腹いっぱい。
2014/06/07(土) 17:47:05.140777名無しさん@お腹いっぱい。
2014/06/07(土) 17:49:02.970778名無しさん@お腹いっぱい。
2014/06/07(土) 20:29:23.800779名無しさん@お腹いっぱい。
2014/06/07(土) 20:46:07.95FreeBSDがどうのというより、termcapとterminfoの違い。
0780名無しさん@お腹いっぱい。
2014/06/07(土) 20:47:59.07そんなことわかった上で言ってるんだがw
0781名無しさん@お腹いっぱい。
2014/06/08(日) 00:08:18.41ただ、ログのこと考えると、ただ延びていくだけのプログレスで十分だと思うけどなー
0782名無しさん@お腹いっぱい。
2014/06/08(日) 01:23:49.35URL2=...
URL3=...
と定義して
for ((i=1;3>i;i++))
do
処理
done
の形で $URL$i と書いても URL1 などに展開されないのだが
正しくはどう書けばよいのでしょうか?
0783名無しさん@お腹いっぱい。
2014/06/08(日) 02:03:50.42eval url='$'URL$i
echo $url
0784名無しさん@お腹いっぱい。
2014/06/08(日) 02:38:49.86declare -a URL
URL[1]=...
URL[2]=...
URL[3]=...
for ((i=1;4>i;i++))
do
echo ${URL[$i]}
done
0785名無しさん@お腹いっぱい。
2014/06/08(日) 02:48:13.36数値とプログレスバーと両方あるといいね。rpm -ivh みたいに。
sun wsのブート時みたいに棒を回すのもなかなかいいよ
0786名無しさん@お腹いっぱい。
2014/06/08(日) 02:58:19.850787名無しさん@お腹いっぱい。
2014/06/08(日) 03:04:42.61とりあえず暫定的に下のforループでしのぎました。
数が多くなると保守性が終わるけど。
for i in $URL1 $URL2 $URL3
do
......
done
>>783,784,786
文字連結のための''を使った回避術、
declareを使った配列宣言、
いいアイデアをいただきました。ありがとうございます。
0788名無しさん@お腹いっぱい。
2014/06/08(日) 07:08:45.79上書き方法会得したらそれも試してみよう
0789名無しさん@お腹いっぱい。
2014/06/08(日) 07:47:05.10for t in '|\r' '/\r' '-\r' '\\\r'; do
echo -en "$t"
sleep 0.1
done
done
0790名無しさん@お腹いっぱい。
2014/06/08(日) 16:28:53.32\\がうまくいきゃいいが
0791787
2014/06/08(日) 17:36:41.96配列良いね
素晴らしく短くまとまった
保守性もばっちりだ
重ね重ね感謝申し上げる
URL=( \
#valiant
http://m...
#watchSomething
http://j...
#script
http://b...
)
# download from URL, and add header
for ((i=0;i<3;i++))
do
echo ${URL[i]}
done
0792名無しさん@お腹いっぱい。
2014/06/08(日) 17:42:21.90for ((i=0; i<${#URL[*]}; i++))
do
echo ${URL[i]}
done
手元に実行環境がなくて検証出来ないから間違ってたらスマン
0793名無しさん@お腹いっぱい。
2014/06/08(日) 17:53:32.13ありがとう。
httpで件数だけ埋め込む作業要らなくなった
${#配列名[*]}で取り出せるのか
こんな#が合ったなんて知らなかったよ
0794名無しさん@お腹いっぱい。
2014/06/08(日) 21:41:28.47一部のファイルをrmしてないバグがあるスクリプトを走らせてしまい/tmpに多数ファイルを残してしまった
このようなミスを抑える対策とかありますか
0795名無しさん@お腹いっぱい。
2014/06/08(日) 21:45:16.18入力、処理、出力、という流れを意識して、設計書を書き、
ポイントポイントで処理の目的に即したテスト項目を作って、
結果を他人が評価できるようにテストを実施することだよ
0796名無しさん@お腹いっぱい。
2014/06/08(日) 22:51:32.33シェルスクリプト一般だと、tmpfile(3)みたいにプログラムが終わると勝手に消える
ようにするのは難しいだろうね。頑張れば出来るかもしれないけど・・。
一時ファイルというと、とりあえずファイル名に$$を入れたりすることが多いけど、
そういうのを含めない(可能なら固定名にする)のが、バグがあっても
悲惨なこと(/tmpが枯渇するなど)にならない設計方法のひとつ。
もちろん可能な場合だけど
0797名無しさん@お腹いっぱい。
2014/06/08(日) 23:43:54.83オブジェクト指向で設計し、インスタンスの寿命が尽きる時にファイルが消去されてることを確認し、されていなければ破棄する。
サポートされていない言語だと例外時に忘れがちなので注意。
0798名無しさん@お腹いっぱい。
2014/06/08(日) 23:53:29.64rm -f /tmp/アプリ名-プロセス番号 すれば良いだけでは?
trap 使えば SIGTERM とか SIGINT にも対応できるし、bash なら終了時にキックもできる。
複数インスタンスの稼働を想定しないなら >>796 の言うように名前固定して、既存ファイルが
ある場合にエラーでとまるようにするとかもアリかな。
0799名無しさん@お腹いっぱい。
2014/06/09(月) 00:03:28.760800>>794
2014/06/09(月) 00:26:53.38チェック漏れがこんなことになるとはなあ
/mntにはtempfsをマウントしていないから簡単には使い切れないのが幸いだった
tempfileとrmをループ外へ追い出してみるのと、こんな感じで一時ファイルの場所の移動を試してみます
export TMPDIR=$(mktemp -d)
trap "rm -rf $TMPDIR" EXIT
>>797
言葉足らずで申し訳ない。問題のスクリプはzshスクリプトです
0801名無しさん@お腹いっぱい。
2014/06/09(月) 00:57:13.180802名無しさん@お腹いっぱい。
2014/06/09(月) 02:38:45.23なんて用法があったのか。やはりこのスレは勉強になる
0803名無しさん@お腹いっぱい。
2014/06/09(月) 11:27:14.45実装ミスであるなら、どんな仕組みを使っても同じ。
設計手法はそういったミスを抑えるためにもある。
そして設計ミスが生まれる。
おそらくは例外時だろうけど、具体的なバグを聞かないと実装による対処方法は確定しない。
0804名無しさん@お腹いっぱい。
2014/06/09(月) 11:33:19.20パイプやコマンド置換でかなりのところまで行ける。
どうしても一時ファイルが要る場合でも、openしたまま先にrmしとくとかでかなり対処できる。
trap 'rm file' 0 とかで消すのはkill -9 された場合は無理だし。
0805名無しさん@お腹いっぱい。
2014/06/09(月) 13:22:45.340806名無しさん@お腹いっぱい。
2014/06/09(月) 15:57:02.71シェルスクリプトでやるのは労力に見合うのだろうか…
0807名無しさん@お腹いっぱい。
2014/06/09(月) 16:03:28.200808名無しさん@お腹いっぱい。
2014/06/09(月) 16:39:23.190809名無しさん@お腹いっぱい。
2014/06/09(月) 20:29:57.190810名無しさん@お腹いっぱい。
2014/06/09(月) 23:23:09.12AA(55)
AA(20)
FOOTER
となっているファイルを食わせて、
HEADER
AA(11)
AA(4)
FOOTER
を吐かせたい。
つまり()内の数値を5で割ったものを吐かせたいんだが、これをshでやるとしたらどういうやり方する?
試しにsed噛ませようと試みたけどあれ演算するのすごいめんどくさそうで
0811名無しさん@お腹いっぱい。
2014/06/09(月) 23:39:14.150812名無しさん@お腹いっぱい。
2014/06/09(月) 23:41:42.9555
$ echo $((55/5))
11
$
0813名無しさん@お腹いっぱい。
2014/06/10(火) 00:06:17.61sed -e 's/\$/\\$/' -e 's!\(([0-9][0-9]*)\)!(\$((\1/5)))!g' | while read l; do eval echo "\"$l\"";done
0814名無しさん@お腹いっぱい。
2014/06/10(火) 00:24:48.890815名無しさん@お腹いっぱい。
2014/06/10(火) 00:55:00.720816名無しさん@お腹いっぱい。
2014/06/10(火) 01:23:49.760817名無しさん@お腹いっぱい。
2014/06/10(火) 09:08:48.05sedにshスクリプトを書かせてるわけだね。
0818名無しさん@お腹いっぱい。
2014/06/10(火) 10:03:19.340819名無しさん@お腹いっぱい。
2014/06/10(火) 10:44:55.16sed -e 's/\([$`]\)/\\\\\1/g' -e 's!\(([0-9][0-9]*)\)!(\$((\1/5)))!g' -e 's/^/"/'
-e 's/$/"/'|while read l; do eval echo "$l";done
>>818
$((expr))のこといってるならposix shellだよ
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
0821名無しさん@お腹いっぱい。
2014/06/10(火) 12:15:49.480822810
2014/06/10(火) 12:29:01.86自分の発想が貧困だったことを思い知らされる
ありがとう
0823名無しさん@お腹いっぱい。
2014/06/10(火) 14:09:06.280824名無しさん@お腹いっぱい。
2014/06/10(火) 14:28:20.320825名無しさん@お腹いっぱい。
2014/06/10(火) 14:32:11.80while IFS='()' read a b; do
if [ "$b" ]; then
echo "$a(`expr $b / 5`)"
else
echo "$a"
fi
done
0826名無しさん@お腹いっぱい。
2014/06/10(火) 14:53:54.80AA(55) や AA(20) の行末に何か文字が入ってしまうとエラーになる
>>819 なら "AA(20) BB(100) CC(65)" とかになっていてもOK
0827名無しさん@お腹いっぱい。
2014/06/10(火) 14:56:24.36そんなことわかった上で、要求仕様だけ満たす最小限で書いているのだよ。
0828名無しさん@お腹いっぱい。
2014/06/10(火) 14:58:01.830829名無しさん@お腹いっぱい。
2014/06/10(火) 15:05:19.71>>819 は入力に " が1個とか(奇数個)含まれてるとエラーになるぞ。
>>825 ならOK
■ このスレッドは過去ログ倉庫に格納されています