シェルスクリプト総合 その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/03(水) 13:43:00.79ID:NkO7phbc0
別件で現在主要のシェルで何がビルトインか調べたことがあるよ

. : [ break cd command continue echo eval exec exit export false kill pwd
read readonly return set shift test times trap true umask unset wait

これらは全てのシェルで使えると言っていいだろう

poshはログインシェルとしては使わないもの扱いなのか
alias bg fg type ulimitが削除されている。(typeないとか地味につらい)
busyboxはgetoptsがないみたい

意外だったのはprintfがビルトインでないシェルがmkshとposhの2つもあったこと。
しかも両方共echoでエスケープシーケンスを解釈してくれるから文字をそのまま出力できない。
mkshの方はset -o posixでエスケープシーケンスを無効にできるしビルトインのprintで代用できるんだが
poshは調べた限りビルトインコマンドでそのまま出力する方法がない
2018/10/03(水) 13:47:38.74ID:m57KKa9e0
いいから、お題の参考答えを出しなさいw
オレオレ定義が曖昧すぎでお題になってないから、もういいでしょ
2018/10/03(水) 13:57:02.54ID:NkO7phbc0
>>131
問題訂正してやるから、もう少し頑張れやw

お題

ある関数に対して、apple orange banana ... とN個(Nは任意の個数)の引数を渡した時、
以下のような、引数とその引数のインデックス番号を出力する関数を作成せよ
(単語に対して数値が対応しているわけではない)

apple 1
orange 2
banana 3



ただし、変数の使用は禁止とし、シェル機能とビルトインコマンドのみを用いること
(ここでいう変数とはsetコマンドで表示されるもののことである)
(使用するコマンドはいずれかのシェルのビルトインコマンドであればよいが、
この問題用に独自シェルを作成するのは禁止とする)
2018/10/03(水) 13:59:49.96ID:m57KKa9e0
なんの目的かさっぱりわからんな。自分でできてんの?っていう疑問からなんだけどなw

>変数の使用は禁止とし
>(ここでいう変数とはsetコマンドで表示されるもののことである)
環境変数のことを言っているのかと思えば違うし、これだけでも曖昧というかオレオレ定義が曖昧だろう
2018/10/03(水) 14:11:05.97ID:NkO7phbc0
>>133
setコマンド実行してみてみばわかるでしょw

setコマンドで表示される変数はシェル変数(環境変数含む)だよ
それを使うのは禁止ってこと
2018/10/03(水) 14:13:32.35ID:NkO7phbc0
今日の24時までに答えが出なければヒント出しますw
2018/10/03(水) 14:16:57.73ID:6m7pNgyW0
そのヒントとやらもグダグダなんでしょw
2018/10/03(水) 14:17:05.40ID:m57KKa9e0
変数を使わない 言語(マシン語すら) は知らんなあ。そういう縛りを設けての目的はなんなん?
やってみたできるけど、クソのようなwにしかならんから、どうか、参考の答えを出してw
2018/10/03(水) 14:19:23.20ID:NkO7phbc0
答えは明日。まあヒントみれば気づく人はすぐわかるでしょう。
コロンブスの卵だよ
2018/10/03(水) 14:20:30.02ID:m57KKa9e0
なんで常時上から目線なのかw コードで語ればいいのに
素晴らしいコードならそんなおれおれ上から目線しなくてもいいくらいなのに。なんかしらんがもったいつけてのまだ「ヒント」とかもったいつけてるしw
2018/10/03(水) 14:21:39.64ID:m57KKa9e0
なんかしらんが見つけて、俺すげーしたいだけっぽいなw
2018/10/03(水) 14:22:11.11ID:NkO7phbc0
> そういう縛りを設けての目的はなんなん?
その理由も答えと一緒に明かします
2018/10/03(水) 14:23:23.18ID:m57KKa9e0
いや、もういらんわw なんかキモすぎて付き合いきれないw
2018/10/03(水) 14:36:43.15ID:ej0n10jM0
多分だけど学校の課題だと予想
根拠は二点:
1. 問題が実利的でない。学校(それもあまり学力の高くない)にありがちな「こんなのできるかな?」系の問題である。
2. 煽ったらそれに乗っかって答えを出してくれる人が思ってるという点で質問者が精神的に幼ない。(高校生くらいか?)
2018/10/03(水) 14:45:22.66ID:m57KKa9e0
posh とかいつもの人でしょ
いつもの人が学校の課題をしなきゃならん人なのか知らんけどw
2018/10/03(水) 15:06:30.08ID:ej0n10jM0
poshなんていうシェルがあるのね。初耳だわ。
2018/10/03(水) 15:10:04.24ID:NkO7phbc0
>>2に書いてあるよ。俺もここ(の何スレか前)で初めて知った
147デフォルトの名無しさん (アウアウカー Saab-XaUO)
垢版 |
2018/10/03(水) 15:58:50.21ID:4kFnpcnsa
$# と shift を使って逆順に値を付加することは簡単にできたんだがな。
2018/10/03(水) 17:25:26.25ID:NkO7phbc0
>>147
俺も第一歩目はそこまでだったw
俺の本来の目的(今回の問題とは別件)は逆順でも実現できたんだけど
なんか悔しかったので、もう一歩進めたら逆にすることなく実現できた
2018/10/03(水) 21:20:26.89ID:SM8JpmZX0
ちょっと前にもこんなグダグダ無かったっけ?
150デフォルトの名無しさん (アウウィフ FFdb-LSDD)
垢版 |
2018/10/03(水) 21:48:53.18ID:Tma5IQlaF
変数使ってはダメって、非合理的でない?
シェルの仕様否定してどーするの?
外部コマンドだって、それがUNIXの設計思想なんだからそれさえも否定するってのも理解不能

ならば、OSそのものを仮想的なものを仮定して
その上で動かすとでもしないと
大昔の情報処理技術者試験用に作られたアセンブラみたいな感じでさ

変数使わない、外部コマンド使用禁止、そんなアルゴリズムが何の役に立つんだろう?
2018/10/03(水) 22:35:14.41ID:ej0n10jM0
でも前はワッチョイやIDがなかったから もっと酷かった。
今はNGすればオッケー☆
2018/10/04(木) 00:37:38.01ID:8ua9ZMtc0
ヒント忘れてたわw

func() {
 *********
 while [ $# -gt 1 ]; do
  *********
  shift
 done
}

func apple orange banana

********の所は1行とは限りません
2018/10/04(木) 00:41:45.65ID:8ua9ZMtc0
>>150
シェルスクリプトはPOSIXの範囲では
ローカル変数がないから、変数名がかぶると困るんだよ
もちろんサブシェルを使うという手もあるが
引き出しは多いほうが良い
2018/10/04(木) 00:43:44.36ID:8ua9ZMtc0
>>151
それなw 見たくないやつが絡んでこなくなったので
過ごしやすくなった。
2018/10/04(木) 00:46:12.13ID:8ua9ZMtc0
>>150
ちなみにこれアルゴリズムじゃないよ
アルゴリズム系だと一時変数を使わずに変数を入れ替える方法とかあるけど
これはシェルの機能を使った、あぁ、なるほど系の問題
2018/10/04(木) 00:49:17.75ID:C6pwZkBD0
いきなりレス数増えたと思ったらもう木曜か
2018/10/04(木) 04:55:02.39ID:/YMF27MO0
>>152よ、お前のなかでは「$#」は変数じゃないのか……。
人様にクイズとやらを出す前にシェルとはなんなのかを学んだらどうだ?
2018/10/04(木) 05:43:44.35ID:8ua9ZMtc0
出題ぐらいちゃんと読もうぜw

> ただし、変数の使用は禁止とし、シェル機能とビルトインコマンドのみを用いること
> (ここでいう変数とはsetコマンドで表示されるもののことである)
2018/10/04(木) 08:51:53.43ID:/YMF27MO0
bash 4.2以降はset組み込みコマンドの中に$#が含まれるようになったんだよなぁ…
ちゃんと調べて、どうぞ。
2018/10/04(木) 09:17:07.53ID:8ua9ZMtc0
ないですね。ちゃんと調べてどうぞ

foo() { set | grep '#='; }; foo



$ bash --version
GNU bash, バージョン 4.4.19(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>;

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
161デフォルトの名無しさん (アウアウカー Sa0a-iYeS)
垢版 |
2018/10/04(木) 09:50:29.05ID:8DudSISka
>>160
grap のパターンはそれでいいのか?
2018/10/04(木) 10:01:44.50ID:8ua9ZMtc0
>>161
良いに決まってるだろ
正規表現に自信がないなら自分で調べたら?
質問してるってことは、動かしてないんだろうし。
163デフォルトの名無しさん (アウアウカー Sa0a-iYeS)
垢版 |
2018/10/04(木) 10:47:30.53ID:8DudSISka
ああ。そうか。最初の$は要らないからそれでいいのか。
2018/10/04(木) 14:55:58.09ID:7ib5/eAS0
grap コマンドか、なんか強うそうなイメージ
2018/10/04(木) 16:22:52.78ID:/YMF27MO0
なんかもう誰かが作ってそうだよね。
まるでyaから始まる4文字のソフトウェアが被りまくってるように。
2018/10/04(木) 16:55:15.20ID:8ua9ZMtc0
犯人はya
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
どういたしまして
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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