シェルスクリプト総合 その29

■ このスレッドは過去ログ倉庫に格納されています
2018/09/22(土) 11:53:21.38ID:BBiLRgnj0
!extend:on:vvvvv:1000:512
!extend:on:vvvvv:1000:512
シェルスクリプトに関する総合スレッドです。

スレ立て時は以下の文を先頭行に加えて下さい。
後のつけ忘れ防止の為に複数行重ねて追加推奨
!extend:on:vvvvv:1000:512

全般
・荒しは無視しましょう。
・丁寧な姿勢を心掛けましょう。
・ネチケット(死語)を意識しましょう。

前スレ
シェルスクリプト総合 その28
http://mevius.5ch.net/test/read.cgi/tech/1532397676/
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
2018/10/04(木) 20:00:19.77ID:8ua9ZMtc0
正解者もいないようなのででは解答
このコードがどういうときに有用かは>>153で書いたとおり
set は使わなくても別にもう一つ関数を作れば同じことができるが
関数を作らずとも引数の再設定という方法がある。意外と便利だよ

func() {
set -- "$@" $(($#+2))

while [ $# -gt 1 ]; do
eval "echo \"$1 \$((\$$#-$#))\""
shift
done
}

func apple orange banana
2018/10/04(木) 20:11:54.69ID:n5lIiyiD0
そんなクソなコードを意気揚々としてあげてるけどさ、なんか変数被るからというもっともらしい言い訳してたけど、なるべく変数使わないように書くわけだ、これから。ほーっw。そんなのクソだな、個人的にw

なんでそういうお題をそんな俺偉いじゃなくてできないのかな。よほどそれを出すのに時間かかったとか??
2018/10/04(木) 20:12:23.41ID:8ua9ZMtc0
はい。想定通りのレスだね。
言い訳だけは一人前w
2018/10/04(木) 20:13:26.14ID:n5lIiyiD0
いや、ふつうわかるだろう。まあ、かなり頑張って出したんだね、やっぱりw
2018/10/04(木) 20:14:13.91ID:8ua9ZMtc0
じゃあもう一問。そんなに言うなら次は答えてね
2018/10/04(木) 20:15:02.61ID:n5lIiyiD0
だから、なんでそんな上から目線なのよ
んなのに付き合うと思ってるの?あんた自体が上から目線でモノ言われたらすぐ反発するくせにww
2018/10/04(木) 20:18:43.51ID:n5lIiyiD0
いや、上から目線じゃなくても反論されたらかwww
2018/10/04(木) 20:20:37.56ID:8ua9ZMtc0
>>172
お前はこのおっさんと同じ種類の人間だろうな
相手が下だと思って接してるやつ。
まずお前が上から目線を止めたら?

https://togetter.com/li/1175445
おっさんがタメ語で聞いてきたからタメ語で返したらショックを受けてた。敬意が返ってくると思ってる日本のおっさんって不思議。
2018/10/04(木) 20:24:38.91ID:n5lIiyiD0
いや、お前に合わせているだけだな。さすが常時上から目線なんかしらんが常時上に立ちたいの人は言うことが違うなw
2018/10/04(木) 20:27:29.69ID:8ua9ZMtc0
上にたってるつもりはないんですが、上に見えちゃうんですかね?w

悪い奴らが「正義の味方のつもりかよwww」って
笑ってるようなシーンがあるけど、あれも悪い奴らに
正義に見えてるからそう言うんでしょうねぇ
2018/10/04(木) 20:28:28.79ID:n5lIiyiD0
忘れているのか常時上に立っているつもりで気がつけないwのか知らんが、ID:8ua9ZMtc0 の上から目線なレスに対しての俺のレスでしかないよ
なので、その得意げの>>174はそっくりそのままあんたにお返しいたします
2018/10/04(木) 20:29:44.58ID:n5lIiyiD0
あーあ、病気なのか社会性がないのか話にならんな。まあ、いつもの無理やりなごまかしモードかな?w
179デフォルトの名無しさん (ワッチョイ 9c03-GavF)
垢版 |
2018/10/04(木) 20:33:31.45ID:vhCji18k0
目くそ鼻くそに上も下もないわwwww
2018/10/04(木) 20:34:30.94ID:n5lIiyiD0
やかましいわっw
2018/10/04(木) 20:50:21.03ID:8ua9ZMtc0
これはある意味有名だから簡単だと思う

お題

ある関数に対して1以上の整数Nを引数にして呼び出した時、
1からNまでを出力する関数を作成せよ(要するにseqコマンドの簡易版)

seq 5
1
2
3
4
5



ただし、シェルビルトイン関数のみを使い、変数の使用は禁止とする
(ここでいう変数とはsetコマンドで表示されるもののことである)
182デフォルトの名無しさん (ワッチョイ 9c03-GavF)
垢版 |
2018/10/04(木) 20:52:49.73ID:vhCji18k0
>>181
調子にのるな鼻くそ
183デフォルトの名無しさん (アウアウカー Sa0a-iYeS)
垢版 |
2018/10/04(木) 21:39:22.36ID:sVn7z6Qaa
>>167
それ最初のposix縛りがあったら解けなくないか?
$(( ))で計算させてるし。
2018/10/04(木) 23:11:17.39ID:4+O8yrpt0
こいつ構わん方がいいゼ、俺スゲーしたいだけだから
2018/10/04(木) 23:14:04.78ID:GYhkNq19a
レス番飛び過ぎにも程があるだろ
まぁいつもの長文だらだら流して悦に浸ってるんだろうが
2018/10/04(木) 23:32:35.30ID:n5lIiyiD0
>>183
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html

2004の時点であるらしい。++と--は任意。sizeof()なんてあるのかよっ
2018/10/04(木) 23:46:42.45ID:/YMF27MO0
>>181
これは興味から訊くんだけど,
「(POSIXの範囲では)変数の局所化ができないので
変数をなるべく使わないべき」
という主張は理解できるし,俺自身もそう思う。
しかしシェルビルトイン関数しか使わず,例えば
sed(1)やawk(1)など目的に合った有用なコマンドを用いない理由はなんだ?
ただの趣味?
2018/10/05(金) 01:23:25.22ID:x9IT1j0q0
>>181
$(( )) での計算をしていいなら簡単だよ。

#!/bin/bash

f() {
if [[ $1 -gt 0 ]]; then
f $(( $1 - 1 ))
echo $1
fi
}

f $1
2018/10/05(金) 01:24:51.76ID:x9IT1j0q0
>>186
そうだったのか。
2018/10/05(金) 02:53:44.46ID:bSHFQ9XI0
>>187
現実的なポータビリティと速度のため

POSIXの範囲でやれば、シェルが異なっても動くことが期待できる
だけど現実的にはすべての環境がPOSIXに準拠してるわけではない
特にbusyboxは組み込み向けに必要最小限の機能に減らせるから
sedやawkすらない環境というのもあり得るだろう

そしてもう一つforkは遅い。WSL上だと目に見えて遅い
以下のコードをWSLで実行すると約25秒かかる。fork一回あたり2.5ミリ秒
Linuxだと約2秒。fork1回あたり2ミリ秒。10倍以上の差がある
i=0
while [ $i -lt 10000 ]; do
( :; )
i=$((i+1))
done

この()を外すとWSL上で0.05秒にまで減る。コマンド実行のオーバーヘッドに
埋もれてしまってよくわからないので、10,000から1,000,000から増やすと約1.7秒
つまり一回あたり0.0017ミリ秒。この値はLinuxでも変わらない

外部コマンドの実行でもforkが行われるから
Linux・・・0.0017ミリ秒 → 2ミリ秒 (約1176倍)
WSL・・・0.0017ミリ秒 → 25ミリ秒 (約14706倍)
と大幅に速度が落ちる。シェルスクリプトが遅いと言われる原因の一つ
191デフォルトの名無しさん (ワッチョイ d980-A6IM)
垢版 |
2018/10/05(金) 02:58:21.89ID:elz6X2140
なんもわかってない低学歴知恵遅れが
はりきってしょうもないwsl使ってキャッキャッいってるわけか

なるほどなるほど

wsl使ってるのなんかニートぐらいしかいないわ
マジで
2018/10/05(金) 03:00:21.47ID:bSHFQ9XI0
>>188
やっぱり簡単だったかw
再帰を使うやり方で関数型言語ではおなじみの問題

もちろんシェルスクリプトは関数型ではないし
末尾最適化も行われないのでどうしても遅くなる
さすがにこれは変数使ったほうが良いかな思ったw

他にも問題を作れそうなネタのはいくつかあるんで
気が向いたらまた問題にしてみるよ
2018/10/05(金) 03:01:11.86ID:bSHFQ9XI0
>>191
やっぱ内容には全く触れず
叩けそうな所を叩くだけなんだなw
技術者としてつまらないね
2018/10/05(金) 03:25:46.03ID:98l9MfY+0
実用的じゃないもの書いてるうちは似非の技術者じゃの
2018/10/05(金) 03:52:16.47ID:DwOdckeN0
>>190
シェルスクリプトはストリーミング指向だから
そもそも制御文を多用することは避けたほうがいいのではってのは違うのかな。
2018/10/05(金) 08:48:03.27ID:bSHFQ9XI0
>>195
ストリーミング指向と制御文はあまり関係ないと思うよ
流れてくるものに対してなにか処理をしたいなら必ず
制御文を使うことになるし

ストリーミング指向の話をするなら、関数呼び出しし結果の標準出力を
変数にキャプチャするっていうのはストリーミング指向と反してると思う
例えば result=$(command "$data") みたいな形のことね
俺もこの書き方はなるべく避けるようになった

ストリーミング指向的には echo "$data" | command | 別のなにか
とするほうが良いだろう

ただ気づいたのがこの形だとサブシェルになってしまうから、
commandや別のなにかから、呼び出しの起点にデータを戻すことが
簡単にはできないという所。値を戻すこと自体がストリーミングの流れに反しているし
かと言ってそれが必要な場合もある。例えば処理した行数をカウントしたりとかね。

なので最近はイベントハンドラ方式を使うようになった
echo "$data" | command "別のなにか(関数名)" (または command "$data" "別のなにか")

例えばだけどこんな感じにして、commandで$dataを1行ずつ処理して
その都度、別のなにか(関数)を呼び出す。そうするとサブシェルにはならないので
ストリーミングで処理しつつ、グローバル変数経由で呼び出し元に結果を返すことができる

この時、別の何かがシェル関数の場合に、commandが外部コマンドだとシェル関数を呼び出せないので
連鎖的にcommandもシェル関数として実装。みたいなこともやってたりする
2018/10/05(金) 17:11:32.63ID:bSHFQ9XI0
10. 移植性のあるシェルプログラミング
http://web.sfc.wide.ad.jp/~sagawa/gnujdoc/autoconf-2.59/autoconf-ja_10.html
2018/10/05(金) 21:16:49.85ID:NK5dBb8n0
>>196
なるほど。
俺は
https://www.ipsj.or.jp/dp/contents/publication/32/S0804-R1601.html
ここの3.1.1を読んで、制御文をなるべく使わない方向に開発をシフトしてみたんだよね。
まあどうしても必要な部分はあなたも云ってる通りもちろんあるけど。
2018/10/06(土) 08:20:34.66ID:Sfai+wMy0
>>198
別にその記事に大きく反対したいわけじゃないけど
おかしな点は指摘しておかないといけない

その手続き型コーディングがステップ数が多く処理効率が低いと書いてある所だが
その原因はストリーミング型コーディングのせいじゃない
rmコマンドの発行回数が原因だ

■手続き型コーディング(ステップ数が多く処理効率が低い)
i=3
while [ $i -le 10000 ]; do
 file="file${i}.txt"
 rm -f "$file" # 何度もrmコマンドを実行している
 i=$((i+3))
done

結果
real 0m3.232s
user 0m2.488s
sys 0m0.808s

■ストリーミング型コーディング
awk 'BEGIN{for(i=3;i<=10000;i+=3){print i;}}' |
sed 's/.*/file&.txt/' |
xargs rm -f

結果
real 0m0.040s
user 0m0.004s
sys 0m0.040s
2018/10/06(土) 08:23:22.22ID:Sfai+wMy0
プロセスが分かれており並列で動く可能性があるから
多少ストリーミング型の方が早くはなるとは思うが
以下のように修正すると差は殆ど無くなる。

■手続き型コーディング修正版
i=3
files() {
while [ $i -le 10000 ]; do
file="file${i}.txt"
echo $file
i=$((i+3))
done
}
rm -f $(files)

結果
real 0m0.052s
user 0m0.018s
sys 0m0.044s


余談だがこれはLinuxで実行した結果だがforkが遅いWSLだと
起動プロセスが多い分逆転するかもしれない
2018/10/06(土) 08:41:27.69ID:Sfai+wMy0
訂正

その手続き型コーディングがステップ数が多く処理効率が低いと書いてある所だが
その原因は手続き型コーディングのせいじゃない
2018/10/06(土) 10:50:18.29ID:10V4sLOp0
>>200
非本質的だけど
rm -f $(files)とかだとARG_MAXに引っ掛かる可能性がない?
尤も手元の機械では
$ getconf ARG_MAX
2097152
だったので無問題かも知れないけど。
2018/10/06(土) 11:49:41.89ID:Sfai+wMy0
>>202
> rm -f $(files)とかだとARG_MAXに引っ掛かる可能性がない?
あるよ。それならxargsを使えばいいし、
xargsはファイルから読み込む方法もあるからパイプ使わなくても使える。
ともかく速さの理由はストリーミング型コーディングではないと言いたかっただけ

だいたいawkの中に書いてあるコードは手続き型だろといいたいし、
ステップ数だってちょっと書き方変えれば、大差ないってのがわかるだろう

i=3; while [ $i -le 10000 ]; do rm -f "file${i}.txt"
i=$((i+3)); done

awk 'BEGIN{for(i=3;i<=10000;i+=3){print i;}}' |
sed 's/.*/file&.txt/' |
xargs rm -f
2018/10/07(日) 07:00:55.51ID:9DLOHMhB0
お題

関数fooに対して3つ以上の引数を渡した時、1番目と2番目の引数を入れ替え以下の例のように出力せよ
(引数が3つ未満の場合は考慮する必要はなし)

ただし、シェルビルトイン関数のみを使い、変数の使用は禁止とする
(ここでいう変数とはsetコマンドで表示されるもののことである)

foo 1 2 3 4 5
2
1
3
4
5

レベル1: 引数に使用する文字は英数のみとする
レベル2: 引数にダブルクォート、シングルクォート、スペース、タブが含まれていても動作するようにせよ
2018/10/07(日) 07:03:41.18ID:9DLOHMhB0
あ、いかん。>>204は簡単な解答があるわw
ちょっと修正する
2018/10/07(日) 07:13:43.37ID:9DLOHMhB0
お題(>>204の訂正版)

次のような関数barがある。
bar() { echo 'begin'; printf '%s\n' "$@"; echo 'end'; }

3つ以上の引数を渡した時、1番目と2番目の引数を入れ替えて関数barを呼び出す関数fooを作成し
以下の例のような出力をせよ(引数が3つ未満の場合は考慮する必要はなし)

ただし、シェルビルトイン関数のみを使い、変数の使用は禁止とする
(ここでいう変数とはsetコマンドで表示されるもののことである)

foo 1 2 3 4 5

[出力]
begin
2
1
3
4
5
end

レベル1: 引数に使用する文字は英数のみとする
レベル2: 引数にダブルクォート、シングルクォート、スペース、タブが含まれていても動作するようにせよ
2018/10/07(日) 07:18:54.69ID:9DLOHMhB0
余談だが、

func() { printf '%s\n' "begin$@end";} という関数の時、

func 1 2 3 4 5 って書いたら

begin1
2
3
4
5end

func 3 って書いたら
begin3end

って表示されるんだよな。

理解はできるが、なんか不思議だ
2018/10/08(月) 03:36:26.64ID:tKqgyITq0
お題はお題スレに

プログラミングのお題スレ Part12
https://mevius.5ch.net/test/read.cgi/tech/1538096947/
2018/10/08(月) 18:41:40.22ID:IMi/szTI0
func -a --foo file1 -b file2 -c --bar

みたいな、オプションとファイル名が交互に来てるときに
オプションを全部解析し終わってから
ファイルに対して処理を実行していくのってけっこう大変なんだな
forで回すのもwhileで回すのも一筋縄ではいかない
もちろんbashなんかの配列を使わないという前提
2018/10/08(月) 18:48:20.63ID:IMi/szTI0
func -a --foo foo1 file1 -b file2 -c --bar

あ、例えば、foo1は--fooはパラメータ、のようなものが有る場合だった
-で始まる or 始まらないだけで見分けるならまだ簡単
2018/10/08(月) 18:50:15.77ID:NcWFD+EU0
そもそもそんな指定の仕方ありうる?
ありえない状況を想定してヤキモキするのは非生産的だと思うんだけど……。
2018/10/08(月) 19:10:00.18ID:IMi/szTI0
>>211
よくやるよ。
前打ったコマンドをヒストリで呼び出して、後ろにオプション追加して実行とか
2018/10/08(月) 20:52:36.04ID:NcWFD+EU0
>>212
仮にそうだとして ということは
>>210を正規化≠キると
func -a --foo foo1 -b -c --bar -- file1 file2
っていうことかな?
2018/10/08(月) 21:02:29.11ID:IMi/szTI0
>>213
そういうこと
215デフォルトの名無しさん (ワッチョイ 969f-XQ2D)
垢版 |
2018/10/08(月) 23:31:18.49ID:tKqgyITq0
GNUのgetoptのロングのやつ使えればなんとかなるんじゃないか?
2018/10/09(火) 02:27:08.37ID:cJ7fFqob0
これでいいな。
$ getopt --options 'a,b,c' --longoptions 'foo:,bar' -- -a --foo foo1 file1 -b file2 -c --bar
2018/10/09(火) 02:29:18.52ID:i1ZCVGtYa
195から207まで丸ごと吹っ飛んでんだがどんだけレスバトルしてたんだ
見る気もないが
2018/10/09(火) 07:22:02.82ID:UgeI4/Dm0
>>216
Macでは動きませんでした
2018/10/09(火) 07:51:19.69ID:cJ7fFqob0
>>218
たのむから一つ前のレスくらい読んでくれ>>215
2018/10/09(火) 07:55:02.13ID:UgeI4/Dm0
>>219
だからMacのgetoptはGNUのgetpotではないから動かないって言ったんだけど?
2018/10/09(火) 07:57:18.12ID:UgeI4/Dm0
GNUのgetoptなら動く。そうでないなら動かないと言われても、
どの環境がGNUのgetoptかなんてわからないでしょう?

GNUのgetoptがほとんどの環境で使われているなら問題ないが
使われてな環境は多いかもしれない。そしてそれがMacという形で
現実になったということを書いたんだけど
2018/10/09(火) 07:58:09.40ID:cJ7fFqob0
>>220
ああそうなの。
Macのgetopt(1)がGNU製じゃないことを知らないような書きぶりだったから てっきり。
すまんな

つーか孰れにしても可搬性は皆無w
2018/10/09(火) 08:18:38.20ID:UgeI4/Dm0
やはりgetoptは可搬性は皆無か

日本語でgetoptでぐぐるとこれが上の方に出てくるけど
相変わらずの、qiitaクオリティってことでいいのかな?
https://qiita.com/b4b4r07/items/dcd6be0bb9c9185475bb

> 一般に 使用される getopt のテンプレートは以下です。
>
> getopt.sh
> set -- 'getopt ad: "$@"'
初っ端からおかしいし。バッククォート書いたつもりが、シングルクォートに化けた?
しかもset --じゃだめだろうと思ってたら、後半では正しい書き方してたが

> OPT=`getopt -o ab:c --long long-a, long-b:,long-c -- "$@"`
> 略
> eval set -- "$OPT"

で、次
> getopt には重大な落とし穴があります。それは、スペースや特殊文字が
> 引数に含まれていた場合、正しく処理できないということです。

特殊文字まではやってないが、スペース入れても普通に動いたんだが?
デフォルトでクォートされてるよな?

man getoptすると「伝統的なgetoptの実装では 〜略〜 空白 〜略〜 使うことができない 〜略〜
この実装ではクォートした出力を生成する」ってことは(この記事で言及できないほど)最近対応したのか?
それはそれとしてクォート方法の指定ができて、shとbash(違いあるの?)があるからシェルごとに
使い分けなきゃいけない気がしていやなんだが

ま、この記事のBSD系ではロングオプション非対応っていうのはgetoptを候補からすばやく外すのには役に立ったなw
GNU版ならもう少し色々できることがわかったが、やはり大変だな。今回は書かなかったがサブコマンド対応とか。
あとgetopt使っても自前処理でもコードの量に大差ないってのはなんなだろう?と前から思っている
2018/10/09(火) 13:51:30.72ID:cJ7fFqob0
parsargコマンドみたいなのを再発明したほうが早いかもね
GNU getoptと同じ(もしくはもうちょっと拡張)挙動でかつ可搬なのを。
2018/10/15(月) 14:55:49.61ID:Q15q2Q7Cd
質問しようと思ったけど初心者の俺にはレベル高い話ばかりで恥ずかしいぜ、、
2018/10/15(月) 15:15:36.15ID:9UZy+Ppr0
どうぞどうぞ
2018/10/15(月) 15:50:29.54ID:Q15q2Q7Cd
ありがとう
やりたいことは、環境を判定して対象の環境にある複数サーバーに対して一括でコマンド発行したい、です

条件
・A環境とB環境があり、引数でそれぞれ指定し(test.sh A のようにしたい)、シェルスクリプト側でどちらが入力されたか判定する

・サーバーにssh接続するためのIPアドレス等は外部ファイルに記載されているため、環境判定後にファイルを読み込んでsshアクセスする必要がある

・サーバーは両環境それぞれ25台ずつあるが、5台ずつコマンドを発行し、waitしてからまた5台と、塊毎にやりたい

質問1
外部ファイルの指定方法が分からないです
ifで環境を判定してthenの後にファイルを指定すれば良いのか?

質問2
5台ずつ、を実現するためにはwhileで良いのか?
そもそも、sshをまとめてやって後からそれらにコマンド発行ってできるのか

初歩的すぎて恥ずかしい限りですがお願いします
228デフォルトの名無しさん (アウアウカー Sa7b-GU/K)
垢版 |
2018/10/15(月) 15:55:57.71ID:oz1FOCTra
どうぞどうぞ
2018/10/15(月) 16:39:55.24ID:Q15q2Q7Cd
>>227
自己解決
やり方を変えることにしました
2018/10/15(月) 16:43:11.45ID:9UZy+Ppr0
どういたしまして
2018/10/15(月) 18:26:03.30ID:A4+xGAqjM
僕にも感謝して
232デフォルトの名無しさん (アウアウカー Sa7b-GU/K)
垢版 |
2018/10/15(月) 18:56:32.85ID:3C5NcaRXa
>>229
どうやることにしたの?
2018/10/15(月) 20:03:34.75ID:dTacK6h30
ssh ... [command] ができるのがわかったとかじゃないのかな
2018/10/15(月) 21:27:00.70ID:0gVRdy5i0
>>232
233の言うとおりです
opensshのマニュアル呼んだら、ファイル指定もコマンド発行方法も書いてあったので、それでやることに
あとはifとの組み合わせで頑張ります
まぁつまずいてるんだけど
2018/10/15(月) 21:32:13.05ID:E6pr56BO0
 私たち日本人の、日本国憲法を改正しましょう。
総ム省の、『憲法改正國民投票法』、でググって
みてください。拡散も含め、お願い致します。
2018/10/18(木) 12:14:09.96ID:/ofNkRJS0
ksh、関数のオーバーライド、くせっていうかバグあるわ

(foo() { echo 1; }; foo; (foo() { echo 2; }; foo;); foo)
何度実行しても1 2 1 と表示される(想定通り)

foo() { echo 1; }; foo; (foo() { echo 2; }; foo;); foo
最初の1回は1 2 1 と表示されるが、
2回目以降は1 1 1 としか表示されない(2でオーバーライドできなくなる)
2018/10/18(木) 12:32:51.57ID:/ofNkRJS0
もう一つ。kshで関数の定義の場所でオーバーライドできない
場合があるんだが原因がよくわからない。

多分これ関連なんだろうけど
https://github.com/modernish/modernish/blob/master/libexec/modernish/cap/BUG_FNSUBSH.t
これはメインシェルの定義がある場合、サブシェルの中での定義が無視されるということだから、
サブシェルの中で定義していれば、その中のサブシェルではオーバーライドできると解釈できる
たしかに>>236はそのとおりの動きはしてる

もう一つの問題も同じなんだろうか、定義の順番を変えればうまくいくんだが
サブシェルに関しては定義の順番を変えても同じだと思うんだけどなぁ。
.コマンドを使ってるのが関係してるのかなんだこりゃって感じだ
2018/10/18(木) 12:40:28.86ID:/ofNkRJS0
もう一つの問題は、ちょっとコードが入り組んでて調べるのが面倒くさい。
なんでこれで解決したのかわかってない状況だが、今のところ動いているので
まあなにかわかったら書くよw
2018/10/18(木) 16:05:20.75ID:q7k/ngFed
初心者です、while文の質問です
このようなスクリプトがあったとします
a=0
while [ $a -le 50 ]
do
a=`expr $a +1`
echo "${a}個目
done

とやると、50個目まで表示されると思いますが、この数値が5の倍数の時だけ、echoで表示させたあとsleepを入れるようにするには、contiuneを使えばよい?
それともifでやる?
よくわからず
240デフォルトの名無しさん (アウアウカー Safb-nHS7)
垢版 |
2018/10/18(木) 16:38:15.26ID:hfM3a7YWa
>>239
continue はループ内のその後の処理を飛ばすやつだからできないと思うが。

普通に if 使ってやるしかないのでは?
if [ `expr $a % 5` -eq 0 ] ; then sleep 1 ; fi
とか、done の直前に入れる。
2018/10/18(木) 17:31:05.73ID:/ofNkRJS0
>>240
> continue はループ内のその後の処理を飛ばすやつだからできないと思うが。
5の倍数以外でsleepを飛ばせばできるYO!

>>239
> とやると、50個目まで表示されると思いますが
51個目まで表示される

> a=`expr $a +1`
は a=$((a+1)) の方が良い
シェルによって実行されるから速い

俺だったらif使わないでこう書くかな
[ $(($a % 5)) = 0 ] && sleep 1
ただこの書き方は if を使った場合と完全に等価なわけじゃなくて
後続行実行時点でのexit codeが異なることがあるから使い方に注意だけど
242デフォルトの名無しさん (アウアウカー Safb-nHS7)
垢版 |
2018/10/18(木) 17:40:57.72ID:hfM3a7YWa
あ。そうか。なるほど。
2018/10/18(木) 17:41:55.70ID:/ofNkRJS0
ついでだから書いておくと、
a=`expr $a +1` でも大差ないだろ?と思った人
WSLの酷さがわかるぞ

たった50回のループ、sleepを行わない状態で
a=$((a+1)) だと 約0.025秒なのに、
a=`expr $a +1` だと 約0.5秒にもなるのだ

10000回のループだと
a=$((a+1)) だと 約0.1秒のところ、
a=`expr $a +1` だと 約90秒

早くWSLのfokの遅さが解決すると良いな
2018/10/18(木) 17:43:58.54ID:/ofNkRJS0
× [ $(($a % 5)) = 0 ] && sleep 1
○ [ $((a % 5)) = 0 ] && sleep 1

書き込む前に気づいて直したと思ったんだがコピペミスったか
上でも動かないわけではない。無駄なだけ
245デフォルトの名無しさん (ワッチョイ 6a7c-fIkj)
垢版 |
2018/10/18(木) 17:56:39.61ID:uRBurQVb0
> [ $((a % 5)) = 0 ]
新旧混ぜんなw
arithmetic使うなら、そのままevaluation記法にしてしまえばいい。
((...))
あと、旧testでの数値比較は-eqを使え。
2018/10/18(木) 18:24:07.81ID:/ofNkRJS0
>>245
ん? どういうふうに書くってこと?

>>237の件、ぼや〜っとだけどわかりかけてきた気がする

スクリプトのコードが.(ドット)コマンドで評価された時点で、
関数がすでに存在している場合、その関数を使用するコードがあれば
事前にリンクされているような動きをしている

その場合サブシェルで関数を再定義しようとしてもできないんじゃないかな
だから事前にリンクできないようにeval呼び出しに変更したら
再定義された方の関数を呼び出すようになった
247デフォルトの名無しさん (ワッチョイ 6a7c-fIkj)
垢版 |
2018/10/18(木) 18:35:46.85ID:uRBurQVb0
((a % 5 == 0))&& ...
なんで一々ここまで言わんとわからんような奴が、他人の指摘しているんだろうかね。。。
-eqでの数値比較とか基本中の基本だろうに。
2018/10/18(木) 18:50:03.03ID:/ofNkRJS0
>>247

$ dash -c 'a=0; ((a % 5 == 0)) && echo ok'
dash: 1: a: not found

$ dash -c 'a=0; (($a % 5 == 0)) && echo ok'
dash: 1: 0: Permission denied

なぜかって?
その書き方はPOSIX準拠じゃないもの

https://github.com/koalaman/shellcheck/wiki/SC2039#standalone-
2018/10/18(木) 18:56:56.93ID:/ofNkRJS0
動かないコード出されて、偉そうにされても
やれやれって言うしか無いわなw
250デフォルトの名無しさん (アウアウカー Safb-nHS7)
垢版 |
2018/10/18(木) 19:33:42.29ID:9i8IzX+1a
(( )) ではなく [[ ]] では?
2018/10/18(木) 19:37:12.04ID:/ofNkRJS0
[[ ]] もPOSIX準拠ではない
2018/10/18(木) 22:39:25.80ID:3W2GDYvfa
またぽっじくすか
2018/10/19(金) 00:21:19.12ID:0zKHBU8T0
>>239だけど、奥が深いね
if使わずにもできたりするのか
はぁ、先は長そうだ、ありがとう
2018/10/19(金) 01:23:10.99ID:JmLVta5V0
cat file.txt | ( head; tail) は最高
2018/10/20(土) 02:22:05.90ID:V0y1IBp60
>>224
> parsargコマンドみたいなのを再発明したほうが早いかもね

違うもの調べてて、こういうのを見つけた。
見つけたってだけでどんなものかは調べていない

http://zentoo.hatenablog.com/entry/20110708/1310124831
> ちょっとした理由でgit-flow (https://github.com/nvie/gitflow) のソースを
> ちょっとちょっと眺めていたんだけど、内部でコマンドライン引数を
> パースするためにshflagsというツールが使われていたのでメモ。
2018/10/20(土) 06:26:18.72ID:EzXK/x1W0
>>254
おまえらなんでそんなに猫が好きなん?
2018/10/20(土) 12:30:19.19ID:o8LOHz9N0
それを疑問に思う人間に説明するのは困難だ
258デフォルトの名無しさん (オッペケ Srb3-iHQf)
垢版 |
2018/10/20(土) 12:37:11.93ID:MzLaXRRvr
猫好きてそんなに言語化しにくい複雑怪奇な感情持っとるんか?
2018/10/20(土) 12:43:08.81ID:o8LOHz9N0
例えば女をみて欲情しない人間に、なぜ欲情するのかを説明するのは難しいだろう
言葉を並べるだけなら本能だとか体の特徴なんかを言えるが、共感はされまい
つまりそれを疑問に感じる人間には、その時点ですでに納得させる言葉がないのだ
260デフォルトの名無しさん (オッペケ Srb3-iHQf)
垢版 |
2018/10/20(土) 12:48:37.62ID:MzLaXRRvr
でもそもそも説明するのが困難なのやろ?
おまえが言ったんやで
2018/10/20(土) 12:55:36.75ID:V0y1IBp60
おい、スレと無関係な話をして荒らすな
2018/10/20(土) 12:56:11.89ID:o8LOHz9N0
なぜ説明するのが困難かを説明したつもりだったんだが
2018/10/20(土) 13:01:22.08ID:V0y1IBp60
つまんねーよ。シェルスクリプトに関係ある話をしろ

ってか、>>206お願い
2018/10/20(土) 14:52:07.13ID:ZWcyeiuM0
お前がつまんねーんだよ
2018/10/20(土) 14:54:50.53ID:2nu5r9gua
なんかレス番飛んだけどなんだこれ
2018/10/20(土) 16:25:12.28ID:EzXK/x1W0
>>265
自分でそういう設定してんだろ。
ngしてますアピールうざいよ。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況