10/04/11 16:13:06 1yJmv1GD
初めてシェルスクリプトを加工としていまうs
サブルーチンを作る参考にしようと#!/bin/shなファイルを見ているんですが
関数を使ったスクリプトはほとんどありません
こういうものでしょうか?
任意の値を返せないのでグローバルな変数を介する必要があると思いますが
保守性が低下しないうまい定義の仕方というのはあるんでしょうか
あるいは関数を使わなくてもいいようなシェルスクリプトの特有のコンセプト
とか書き方があるんでしょうか
漠然とした質問ですいません
800:login:Penguin
10/04/11 16:21:22 ESnWs44w
漠然としてるねぇ。
もうちょっとスクリプト書きに慣れてから考えればいいんじゃないかな。
801:login:Penguin
10/04/11 17:04:57 btbPPhym
いやそれより、初心者向きの参考書でも買って
一からじっくり勉強した方が良いと思う。
>>799は、ここで質問して解決するスキルレベルに程遠い。
802:login:Penguin
10/04/11 17:49:36 O63F6ul8
>>801さんまじかっけー
803:login:Penguin
10/04/11 20:21:58 bAKRtVTC
>関数を使ったスクリプトはほとんどありません
>こういうものでしょうか?
いえ。
ただ、スクリプトは、
1) 手っ取り早く仕上げる事が多いので十分に最適化されない
2) 最適化されたスクリプトは必ずしも可読性がよくないので敢えて最適化しない
といったことはあると思います。
804:login:Penguin
10/04/11 20:51:15 eH4Novr7
わざわざ外部関数までつくって何でもシェルスクリプトでやるより多言語から単体のシェルスクリプト叩かせたほうが安心できる
805:login:Penguin
10/04/12 01:55:25 56zfLj4c
>>803
回答ありがとうございます
最適化というのがどういうものか具体的には分かりませんが、例えば関数を組み合わせようと
すると値をやり取りするグローバル変数が必要になるのではと考えました。しかし、必要に
なるごとに関数内で定義、参照するとそういった変数がどこでどう利用されているか確認しなければ
ちょっとした変更も危険になると思います。あるいはメインの手続き側に定義を羅列するとしても
どう利用するのかはコメントでもしないかぎり分からないし、そもそも構造内部を関数へと段階的に
隠蔽する目的を果たせなくなってしまい、やはり可読性保守性は低下します。一方でルールベース
の対策でこういった問題を解決できるようにも感じたので、そういったことについてベーシックな議論を
している人たちがいるのではと思い質問しました。
しかしこのスレッドを読んでいると>>803(1)や>>804にあるように、そういう道具だと割りきって使う
ものだという風にも思いました。シェルスクリプトの欠点を何千万人もの人があえて見なかったこと
にして使っているとすると、とても面白いことですね。それだけ目的を満足させる道具で、また知っ
て初めて分かる魅力があるということなんでしょうかね
(2)については一枚目から鱗が落ちました。習作のつもりでUTF8のテキストをEUC-JPに変換して
からa2psでポストスクリプトを生成するコードを再発明しているのですが、たしかに関数を使っても
全然読みやすくなっていない! いや、正確には処理の始点と大枠の処理の流れは把握しやすく
なっていますが、コード量は後付けでどんどん増加するし、ちょっとした読みやすさのために定義
したマクロ的関数は、それ単体でみるとなんとも得体の知れないものになっていました。
色々な機能を試したいというのもあるのですが、やはり簡潔で読みやすいコードを書くということを
前提にして、そのうえでシェルスクリプトらしい書き方を身につけるようにします
806:799,805
10/04/12 02:02:53 56zfLj4c
勢いでいい子ちゃんぶった嘘をつきました・・
たぶん動けば汚くてもいいやの精神でなんだかよく分からないコードを書き続けると思います
ゴメンナサイです
807:login:Penguin
10/04/12 11:43:55 Qe0ukjkj
/usr/binの中に'['とかゴミがあったので削除したら、起動しなくなったという
笑い話をよく聞いたな。
808:login:Penguin
10/04/12 12:14:55 Cm3bm4a3
>>807
ほう、それは初耳だ。
いまどきの sh は [ を内蔵しているので、
外部コマンドの [ を意図して呼ばないかぎり存在しなくても問題ない。
[ が外部コマンドだった昔は、[ は /usr/bin ではなく /bin にあった。
# つーか、/usr/bin/[ なんて今でも linux だけ。
809:login:Penguin
10/04/12 13:13:25 s3PYGw84
ここはLinux板ですから
810:login:Penguin
10/04/12 13:31:44 FrL0zKPd
「[ を消してうんぬん」は Linux 以前の時代の話だと思う。
811:login:Penguin
10/04/12 18:27:16 rk0wy3GT
プロプラの古いshを使ってないと通じないジョークだな
812:799
10/04/17 23:26:31 f4tmK5PF
先だっては大変お世話になりました
なんとか動くっぽいもの書けました
根本的に間違ってるところやイディオムに直すべきところなど多々あるんだろうと
思うんですが、身近に聞ける人がいなくて困ってます。ので誰かにレビューして欲しいです
なにとぞ、なにとぞー
URLリンク(up.af)
813:799
10/04/17 23:38:16 f4tmK5PF
すんません私のファイルはこっちでした
上のTシャツおっぱいは忘れてください^^
URLリンク(up.af)
814:login:Penguin
10/04/17 23:41:35 xq8djkPZ
わざ。わざ
815:login:Penguin
10/04/18 13:57:11 XFWJRzoK
献上品のTシャツおっぱいが404なので眺めるだけな
>#!/bin/sh
dashで動作確認したのなら素直に#!/bin/dash
> file_num=`expr $file_num + 1`
exprいらなそう
file_num=$((file_num + 1))
> local num=0
> for num in `seq 1 $file_num`; do
> source_files_get $num
> MESSAGE "converting: $file"
> cat "$file" | $NKF -e > "$temp_dir/${file##*/}"
> done
seqとcatいらなそう
local num=1
while [ $num -le $file_num ]; do
source_files_get $num
MESSAGE "converting: $file"
$NKF -e "$file" > "$temp_dir/${file##*/}"
num=$((num + 1))
done
>local status=1
local使う意味なし&多分bashでコケる
816:login:Penguin
10/04/19 01:23:48 ZAvND9//
>>815
式展開というものが色々あるんですね
むやみに外部コマンドを呼ばないという発想もなかったです
マニュアルを引いてあれこれ確認したいと思います
レスありがとうございました
817:login:Penguin
10/04/21 22:02:51 CZfDlwcf
>>813
python風のループだな。
LLみたいに関数を使いたければ値をやり取りするフレームワークを書けばよいかも。
818:login:Penguin
10/04/22 23:27:27 eajRO0wt
commandA > file
commandB > file
と
{ commandA; commandB; } > file
はどっちの方がいいの?
後者の場合は、シェルによってはサブシェルが起動するって聞いたけど本当貝。
819:login:Penguin
10/04/22 23:48:35 sUoTjkov
>>818
上意味違うだろ。
820:login:Penguin
10/04/22 23:52:47 eajRO0wt
間違えた!
前者は
commandA > file
commandB >> file
821:login:Penguin
10/04/23 00:01:08 sUoTjkov
正直、目くそ鼻くそじゃね?
822:login:Penguin
10/04/23 00:03:10 4U7Ovp/A
そう?
じゃあ気にしないでいいか。
823:login:Penguin
10/04/23 00:10:54 Odx5g+6A
悩んでるうちに書いて実行した方が仕事は早く終わるだろ。
824:login:Penguin
10/04/23 05:48:09 0SL93pt/
>>818
後者のほうが効率いい
825:login:Penguin
10/04/24 12:19:07 uV1EwGDC
>>824
スクリプトの一文が長すぎる。
パイプラインもメンドイ。
826:login:Penguin
10/04/24 22:06:24 F/lhQSxk
>>818
前者の場合、commandAの出力はどうなるのかな?w
827:login:Penguin
10/04/24 22:21:58 loCBys/t
↑
大丈夫かな、この人・・・
828:login:Penguin
10/04/24 22:57:54 XH+rWnSs
笑っとけ笑っとけ。
829:login:Penguin
10/04/24 23:02:02 /2NBYvX3
>>826
修正してるじゃないか、 >>820で
830:login:Penguin
10/04/24 23:03:08 loCBys/t
恥ずかしいね
831:login:Penguin
10/04/24 23:51:55 ra/w56Dm
>>825
あれで長いって、普段どんなスクリプト書いてんだ?
832:login:Penguin
10/04/25 09:35:32 iXPvNLwg
>>831
いや、引数が100個とかになってきたら。
潰しが利かない。
833:login:Penguin
10/04/25 09:37:17 pW61wlqY
意味不明
834:login:Penguin
10/04/25 09:39:20 iXPvNLwg
>>833
脊髄じゃなく、脳で考えてください。
835:login:Penguin
10/04/25 10:09:49 ZtdJByaw
その価値のある文章を頼む。
引数とはどの部分の引数なのか?
潰しが利かないという主張の根拠は?
836:login:Penguin
10/04/25 10:39:21 MLqGsd45
これ以上この話を続けても有益な情報は得られないと思う。
837:login:Penguin
10/04/25 11:27:46 iXPvNLwg
>>818
commandA > file
commandB >> file
と
{ commandA; commandB; } > file
コマンドが100個になったのでwhileで省力化したい。
上の方
rm -f file 2>/dev/null
while read cmd;do
$cmd >> file
done < cmds.txt
下の方
xargsを使えば出来そうだけど{}が内部コマンドなのが気になる。
1行のコマンドラインの文字数制限があるシェルもある。
ので、汎用性が無い。
838:login:Penguin
10/04/25 11:34:27 iXPvNLwg
制御構造の使えないシェルスクリプトなんて、バッチファイルの如く、無価値である。
839:login:Penguin
10/04/25 11:37:39 GR3waYM0
>>837
よくわかんねえけど
そのcmd.txtって、事実上シェルスクリプトだよな
単に
sh cmd.txt >file
でいいんじゃねえの
840:login:Penguin
10/04/25 11:46:22 gQNuPSjh
wwww
841:login:Penguin
10/04/25 11:49:42 iXPvNLwg
>>839
そだな。それが最適解だ。
842:login:Penguin
10/04/27 22:06:55 HNWNlh/r
for((i=0; i<6; i++)){
array=("${array[@]}" "i")
}
echo "${array[@]}"
これを実行すると下記のように出力されます。
0 1 2 3 4 5
カンマ区切りで下記のように出力する方法ありますか?
0, 1, 2, 3, 4, 5
843:login:Penguin
10/04/27 23:08:31 3UTvz9hd
>>842
最後の出力を実現するのなら seq -s ', ' 0 5 で済むけど、
配列の各要素を任意の区切文字で繋げて出力する方法を知りたいということかな
zsh/ksh なら echo ${(j:, :)array} でできるけど、bash でどうなのかは知らない
844:login:Penguin
10/04/27 23:18:40 HNWNlh/r
>>843
説明不足で申し訳ないです。
配列の各要素をカンマ区切りで出力する方法です。
・訂正します
array=(1 2 a b 3 c )
echo "${array[@]}"
これを実行すると下記のように出力されます。
1 2 a b 3 c
カンマ区切りで下記のように出力する方法ありますか?
1, 2, a, b, 3, c
echo ${(j:, :)array} は使えませんでした。
845:login:Penguin
10/04/27 23:37:13 wOLuHHkh
>>844
IFS="," ; echo "${array[*]}"
846:login:Penguin
10/04/28 10:15:03 ttzp8AMm
echo "${array[@]}" | sed 's/ /, /g'
847:844
10/04/28 11:26:50 +626EOW1
>>845-846
できました!ありがとうございました。