!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
探検
シェルスクリプト総合 その29
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん (ワッチョイ 3efb-m2E0)
2018/09/22(土) 11:53:21.38ID:BBiLRgnj0605デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/11(日) 00:30:20.21ID:PRctJ18Z0 >>603
ほ ん と そ れ
そして今調べて気が付いたがsh -xじゃねーなw
set -xだわ。
> The -a, -b, -C, -e, -f, -m, -n, -o option, -u, -v, and -x options
> are described as part of the set utility in Special Built-In Utilities.
> The option letters derived from the set special built-in
> shall also be accepted with a leading <plus-sign> ( '+' ) instead of a leading <hyphen-minus>
> (meaning the reverse case of the option as described in this volume of POSIX.1-2017).
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html#tag_20_117_04
ほ ん と そ れ
そして今調べて気が付いたがsh -xじゃねーなw
set -xだわ。
> The -a, -b, -C, -e, -f, -m, -n, -o option, -u, -v, and -x options
> are described as part of the set utility in Special Built-In Utilities.
> The option letters derived from the set special built-in
> shall also be accepted with a leading <plus-sign> ( '+' ) instead of a leading <hyphen-minus>
> (meaning the reverse case of the option as described in this volume of POSIX.1-2017).
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html#tag_20_117_04
606デフォルトの名無しさん (ワッチョイ b903-wpdm)
2018/11/11(日) 00:55:22.01ID:TQKm/8h90 >>604
なんでワイに聞くねんwバカなんかおまえ?
なんでワイに聞くねんwバカなんかおまえ?
607デフォルトの名無しさん (ブーイモ MMab-/quP)
2018/11/11(日) 00:56:50.21ID:AsOVz6G5M それを質問の意味で受け取るとか日本語大丈夫?
608デフォルトの名無しさん (ワッチョイ b903-wpdm)
2018/11/11(日) 01:00:58.12ID:TQKm/8h90 日本語が大丈夫ってどおゆう意味や?
609デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/11(日) 01:05:43.58ID:Tyd11AGx0 おちつけ、今はまだ慌れるときじゃない。
610デフォルトの名無しさん (ワッチョイ b903-wpdm)
2018/11/11(日) 01:09:59.72ID:TQKm/8h90 慌れるて日本語あるんか?ちょっと落ち着けやw
611デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/11(日) 02:43:07.51ID:Tyd11AGx0 りっしんべんが余計だった
612デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/11(日) 12:28:16.92ID:PRctJ18Z0 C言語ではなくシェルスクリプトでシグナルって活用してる?
kill(1)ユーティリティの-s KILLオプションくらいしか使ったことがないので
いまいち便利さが分からない。
利用者定義シグナルSIGUSER1とか 使いこなせたらシェルスクリプトでできることの幅が広がりそう
kill(1)ユーティリティの-s KILLオプションくらいしか使ったことがないので
いまいち便利さが分からない。
利用者定義シグナルSIGUSER1とか 使いこなせたらシェルスクリプトでできることの幅が広がりそう
613デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/11(日) 12:33:00.83ID:Tyd11AGx0 CTRL-Cされたときとかプログラム終了時に
作業ファイルを削除することぐらいかなぁ
あとはシグナルじゃないけど、bashの疑似シグナル
ERRとかDEBUGとかで遊んだことある
サービスなんかだとシグナル送ったら設定ファイル再読込したり
ddだったら進捗状況表示したりするね
作業ファイルを削除することぐらいかなぁ
あとはシグナルじゃないけど、bashの疑似シグナル
ERRとかDEBUGとかで遊んだことある
サービスなんかだとシグナル送ったら設定ファイル再読込したり
ddだったら進捗状況表示したりするね
614デフォルトの名無しさん (ワッチョイ db9f-ki2E)
2018/11/11(日) 22:34:54.73ID:0F8Q4Ddx0 >>612
終了処理をちゃんとやらないといけないような処理の場合に trap 使ってシグナルに対して
特定の変数を 1 にするだけとか、そういうやり方で終了処理後にその変数見て 1 になって
いたら exit みたいな感じでシグナル利用するな。
後は普通に kill で他のプロセス終了させたい場合。pkill 使う事もある。
終了処理をちゃんとやらないといけないような処理の場合に trap 使ってシグナルに対して
特定の変数を 1 にするだけとか、そういうやり方で終了処理後にその変数見て 1 になって
いたら exit みたいな感じでシグナル利用するな。
後は普通に kill で他のプロセス終了させたい場合。pkill 使う事もある。
615デフォルトの名無しさん (ワッチョイ 9164-TRt+)
2018/11/12(月) 12:58:25.45ID:JkRQG90v0 実行してるシェルスクリプトに行番号を付けるのさ,
PS4変数にn=$((n+1))みたいなのを入れてset -xとやればうまくいくかな と思ったんだが無理っぽいな。
どっかで無限ループして何も出力されないw
PS4変数にn=$((n+1))みたいなのを入れてset -xとやればうまくいくかな と思ったんだが無理っぽいな。
どっかで無限ループして何も出力されないw
616デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/13(火) 19:40:03.28ID:0Ele5WZ80 算術式のなかにコマンド展開を突っ込むのってPOSIX違反かしら
echo $(($(< ./file.txt wc -l)-1))←こういうの。
echo $(($(< ./file.txt wc -l)-1))←こういうの。
617デフォルトの名無しさん (ワッチョイ 0123-kOF1)
2018/11/13(火) 20:47:22.69ID:tvSD0Nan0 >>616
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_04
これを読む限りは特に規定されてるようには見えない
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_04
これを読む限りは特に規定されてるようには見えない
618デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/14(水) 15:25:56.02ID:P8pvRdrO0619デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/14(水) 15:29:13.15ID:Da4Ohzbn0 えぇ・・・
俺普通にこんなの使ってんだけど?
value=$(( ${value:-0} + 1 ))
普通に展開されるんじゃないの?
俺普通にこんなの使ってんだけど?
value=$(( ${value:-0} + 1 ))
普通に展開されるんじゃないの?
620デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/14(水) 16:18:09.15ID:P8pvRdrO0 >>619
まあ俺も使い捨てのスクリプトでは使うけど
ただPOSIX 2017では
x=3; x=$((x+1))
↑これすら正常に動くとは定義されてないんだよね
ただ単に
x=3のとき$((x))は$(($x))と「同じ値になる」とだけ。
だから例示されるスクリプトでも
x=$(($x + 1))
みたいに書かれてる。
まあ俺も使い捨てのスクリプトでは使うけど
ただPOSIX 2017では
x=3; x=$((x+1))
↑これすら正常に動くとは定義されてないんだよね
ただ単に
x=3のとき$((x))は$(($x))と「同じ値になる」とだけ。
だから例示されるスクリプトでも
x=$(($x + 1))
みたいに書かれてる。
621デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/14(水) 16:40:42.71ID:Da4Ohzbn0 >>620
> x=$(($x + 1))
shellcheckではそれ不要だから外せって言われるよ?
shellcheckが完璧だとは思わないけど、
あえてそうしてるんだからPOSIXだと思うんだけどなぁ
> x=$(($x + 1))
shellcheckではそれ不要だから外せって言われるよ?
shellcheckが完璧だとは思わないけど、
あえてそうしてるんだからPOSIXだと思うんだけどなぁ
622デフォルトの名無しさん (ワッチョイ 9164-TRt+)
2018/11/14(水) 16:46:17.02ID:P8pvRdrO0 >>621
shellcheckはそれに関しては間違ってると言えるな
なぜなら もう言ったが
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04_01
↑ここで
x=$(($x-1))とはっきり書かれてるんだよ。
shellcheckはそれに関しては間違ってると言えるな
なぜなら もう言ったが
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04_01
↑ここで
x=$(($x-1))とはっきり書かれてるんだよ。
623デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/14(水) 17:07:17.10ID:Da4Ohzbn0 >>616
あ、大丈夫みたいだよ。
コマンドも展開されるって書いてある
$((expression))
The shell shall expand all tokens in the expression
for parameter expansion, command substitution, and quote removal.
あ、大丈夫みたいだよ。
コマンドも展開されるって書いてある
$((expression))
The shell shall expand all tokens in the expression
for parameter expansion, command substitution, and quote removal.
624デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/14(水) 17:18:05.78ID:Da4Ohzbn0 あ、なるほど。わかった。
${a} って書いたときの、aの部分が式なんだ。$は含まれない。それと同じで
$((a)) もaの部分が式で>>623に書いてあるように、先に展開される仕様だから
$(($a))だと先に$aの部分が文字列として展開されて$((123))のように解釈される
だから https://github.com/koalaman/shellcheck/wiki/SC2004 に書いてあるように
> $ a='1+1'
> $ echo $(($a * 5)) # becomes 1+1*5
> 6
これだと、式が評価される前に文字列として展開されちゃうから変な計算になるが
> $ echo $((a * 5)) # evaluates as (1+1)*5
> 10
${a}と同じように$((a))と書くと、ちゃんと算術演算が行われるんだ
ということで、やっぱり$(($a))は間違いで$((a))が正しいようだね
${a} って書いたときの、aの部分が式なんだ。$は含まれない。それと同じで
$((a)) もaの部分が式で>>623に書いてあるように、先に展開される仕様だから
$(($a))だと先に$aの部分が文字列として展開されて$((123))のように解釈される
だから https://github.com/koalaman/shellcheck/wiki/SC2004 に書いてあるように
> $ a='1+1'
> $ echo $(($a * 5)) # becomes 1+1*5
> 6
これだと、式が評価される前に文字列として展開されちゃうから変な計算になるが
> $ echo $((a * 5)) # evaluates as (1+1)*5
> 10
${a}と同じように$((a))と書くと、ちゃんと算術演算が行われるんだ
ということで、やっぱり$(($a))は間違いで$((a))が正しいようだね
625デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/14(水) 18:02:30.17ID:Da4Ohzbn0 間違いっていうのは仕様違反って意味じゃなくて
算術演算をするなら$をつけないのが正しいって意味ね。
算術演算の前に$とかコマンドが展開されるっていうのも
仕様なのでそれも書いたとおりに動作する
算術演算をするなら$をつけないのが正しいって意味ね。
算術演算の前に$とかコマンドが展開されるっていうのも
仕様なのでそれも書いたとおりに動作する
626デフォルトの名無しさん (オッペケ Srcd-3Pmj)
2018/11/14(水) 19:06:25.03ID:vF6ts/2/r 大きなファイルがいくつも入ったディレクトリのmvして分かったけど
ファイルがいくつあっても全部のcpが終わったあとにrmされるんだね
てっきり1ファイル毎かと思ってた
ファイルがいくつあっても全部のcpが終わったあとにrmされるんだね
てっきり1ファイル毎かと思ってた
627デフォルトの名無しさん (アウアウウー Sa05-pmE1)
2018/11/14(水) 19:23:07.48ID:bryEJhFFa >>626
途中で中止した時に移動先を削除するだけで済むからじゃないかな。
途中で中止した時に移動先を削除するだけで済むからじゃないかな。
628デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/14(水) 19:34:11.25ID:P8pvRdrO0 >>625
んー。でも俺には
> If the shell variable x contains a value that forms a valid integer constant,
> optionally including a leading or ,
> then the arithmetic expansions "$((x))" and "$(($x))" shall return the same value.
は$((x))の「時だけ」$(($x))と等しいと読めるがな。
いずれにしても算術展開で算術計算をする際に変数を使いたいときは
$(( ($x) + 1 ))
にしてるわ。どっかで$(( x + 1 ))がエラーになるのが怖いので。
んー。でも俺には
> If the shell variable x contains a value that forms a valid integer constant,
> optionally including a leading or ,
> then the arithmetic expansions "$((x))" and "$(($x))" shall return the same value.
は$((x))の「時だけ」$(($x))と等しいと読めるがな。
いずれにしても算術展開で算術計算をする際に変数を使いたいときは
$(( ($x) + 1 ))
にしてるわ。どっかで$(( x + 1 ))がエラーになるのが怖いので。
629デフォルトの名無しさん (アウアウウー Sa05-Vzv6)
2018/11/14(水) 21:35:28.76ID:tEjpeAN9a630デフォルトの名無しさん (ブーイモ MMb3-D3se)
2018/11/14(水) 21:50:05.93ID:D6nmDs23M $(())が展開できるものは限定されていて、$((x+1))が意図通りに展開される根拠は$((x))と$(($x))が等しいって書いてある一文しかない。
これは$(())の中だけはx=$xであると解釈できなくもないけど、算術演算をするなら$をつけないのが正しいとは読めないな。
これは$(())の中だけはx=$xであると解釈できなくもないけど、算術演算をするなら$をつけないのが正しいとは読めないな。
631デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/14(水) 22:59:44.88ID:Da4Ohzbn0 > $((x+1))が意図通りに展開される根拠は$((x))と$(($x))が等しいって書いてある一文しかない。
一つあれば十分じゃん。逆に展開されない根拠はないんだし
そもそも ${expression} と $((expression)) という記述があるんだから
expressionの中は同じ意味のはずだろう
一つあれば十分じゃん。逆に展開されない根拠はないんだし
そもそも ${expression} と $((expression)) という記述があるんだから
expressionの中は同じ意味のはずだろう
632デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/14(水) 23:06:12.49ID:Da4Ohzbn0 > どっかで$(( x + 1 ))がエラーになるのが怖いので。
それがエラーになるなら、とっくに検出してるだろうな。
複数のシェルで確認してるからさ
それ関連で注意が必要なのは $(($#-1))
zshだと81になる。
それがエラーになるなら、とっくに検出してるだろうな。
複数のシェルで確認してるからさ
それ関連で注意が必要なのは $(($#-1))
zshだと81になる。
633デフォルトの名無しさん (ワッチョイ 2105-jVda)
2018/11/15(木) 07:34:42.91ID:CPG8nmHa0 >>631
いや算術演算するときは$をつけないのが正しいとは何処にも書いてないけど
いや算術演算するときは$をつけないのが正しいとは何処にも書いてないけど
634デフォルトの名無しさん (ワッチョイ 9564-ddua)
2018/11/15(木) 08:48:01.92ID:sJsqi8La0 というか,shellcheckでの検査結果うんぬんよりも本家POSIXの記述のほうが優先して考慮されるべきだと思うのだが。
635デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/15(木) 10:49:23.03ID:gWaB1LhD0 本家POSIXに$((x))が動くと書いてあるだろ
636デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/15(木) 11:23:09.13ID:gWaB1LhD0 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04_01
に書いてあるだろ
> Arithmetic expansion provides a mechanism for evaluating an arithmetic expression and substituting its value.
> The format for arithmetic expansion shall be as follows:
>
> $((expression))
>
> The expression shall be treated as if it were in double-quotes, except that a double-quote inside
> the expression is not treated specially. The shell shall expand all tokens in the expression for
> parameter expansion, command substitution, and quote removal.
まず、$(( )) の中にある。これがexpressionだ。
expand all tokens in the expression 式の中にある以下のトークンの展開、
for parameter expansion, command substitution, and quote removal.
パラメータ展開、コマンド置換、クォートの削除
> Next, the shell shall treat this as an arithmetic expression and substitute the value of the expression.
その次(Next)に この式を arithmetic expression (算術式)として扱う
つまりだ。パラメータ展開( $(($x))の$xの展開 )が行われるまでは、まだ算術式として扱う前なんだよ
そもそもだな。 x=123を見て分かる通り。変数名はxだぞ。$xじゃない。
他の言語では変数名が$で始まるものがあるが、シェルスクリプトにおいて、
$は、パラメータ展開、コマンド置換、算術展開等を行うための記号だって書いてあるだろ?
特殊変数の説明だって、$@じゃなくて@、$*じゃなくて*、$#じゃなくて#、$$じゃなくて$ と書いており
変数名とは最初の$は含まれない部分だってことが読み取れるだろ
に書いてあるだろ
> Arithmetic expansion provides a mechanism for evaluating an arithmetic expression and substituting its value.
> The format for arithmetic expansion shall be as follows:
>
> $((expression))
>
> The expression shall be treated as if it were in double-quotes, except that a double-quote inside
> the expression is not treated specially. The shell shall expand all tokens in the expression for
> parameter expansion, command substitution, and quote removal.
まず、$(( )) の中にある。これがexpressionだ。
expand all tokens in the expression 式の中にある以下のトークンの展開、
for parameter expansion, command substitution, and quote removal.
パラメータ展開、コマンド置換、クォートの削除
> Next, the shell shall treat this as an arithmetic expression and substitute the value of the expression.
その次(Next)に この式を arithmetic expression (算術式)として扱う
つまりだ。パラメータ展開( $(($x))の$xの展開 )が行われるまでは、まだ算術式として扱う前なんだよ
そもそもだな。 x=123を見て分かる通り。変数名はxだぞ。$xじゃない。
他の言語では変数名が$で始まるものがあるが、シェルスクリプトにおいて、
$は、パラメータ展開、コマンド置換、算術展開等を行うための記号だって書いてあるだろ?
特殊変数の説明だって、$@じゃなくて@、$*じゃなくて*、$#じゃなくて#、$$じゃなくて$ と書いており
変数名とは最初の$は含まれない部分だってことが読み取れるだろ
637デフォルトの名無しさん (ワッチョイ 9564-ddua)
2018/11/15(木) 11:44:50.73ID:sJsqi8La0 >>636
そのすぐあとに
x=$(($x - 1))
という記述があるんですが。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04_01
そのすぐあとに
x=$(($x - 1))
という記述があるんですが。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04_01
638デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/15(木) 12:00:52.72ID:gWaB1LhD0 >>637
あるからなんだよ?
パラメータ展開が行われるから
x=$(($x - 1)) は x=$((100 - 1)) となって動くだろうさ
それは x=$((x - 1)) がだめな理由になってない
あるからなんだよ?
パラメータ展開が行われるから
x=$(($x - 1)) は x=$((100 - 1)) となって動くだろうさ
それは x=$((x - 1)) がだめな理由になってない
639デフォルトの名無しさん (ワッチョイ 9564-uG0O)
2018/11/15(木) 12:27:06.72ID:sJsqi8La0640デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/15(木) 12:34:01.42ID:gWaB1LhD0 shellcheckは間違いだから不要と言ってるんじゃなくて、
意味がないから不要って言ってるんだよ。
お前コードチェックツールで変数が使われていませんって
指摘されたら、文法上は間違ってねーよって文句言うのかよ?
意味がないから不要って言ってるんだよ。
お前コードチェックツールで変数が使われていませんって
指摘されたら、文法上は間違ってねーよって文句言うのかよ?
641デフォルトの名無しさん (アウアウカー Sa85-57oK)
2018/11/15(木) 12:36:27.53ID:zXViJGdda ファイッ
642デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/15(木) 12:36:35.34ID:gWaB1LhD0 > shellcheckの「後者にしろ」っていう判定は絶対におかしい。
後者にしろって言う判定は、前者が間違ってるって話じゃなくて、
後者もOK、だから後者はPOSIX違反ではない(POSIX違反を提案するわけがない)って話だよ
もうちょっと落ち着けよ。お前否定されたらすぐカッとなるだろw
後者にしろって言う判定は、前者が間違ってるって話じゃなくて、
後者もOK、だから後者はPOSIX違反ではない(POSIX違反を提案するわけがない)って話だよ
もうちょっと落ち着けよ。お前否定されたらすぐカッとなるだろw
643デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/15(木) 12:41:58.45ID:gWaB1LhD0 > つまりx=$(($x + 1))の「$x」が不要という主張は完全に間違いってことだ。
> x = $(($x - 1))とx = $((x - 1))のどっちが正しいかなんて言ってねえよ。
後者が動くのであれば
>「$x」が不要という主張は完全に間違い
という主張の方が間違ってる。
そして後者は実際に動く
> x = $(($x - 1))とx = $((x - 1))のどっちが正しいかなんて言ってねえよ。
後者が動くのであれば
>「$x」が不要という主張は完全に間違い
という主張の方が間違ってる。
そして後者は実際に動く
644デフォルトの名無しさん (ワッチョイ 9564-uG0O)
2018/11/15(木) 13:09:09.63ID:sJsqi8La0 前者も実際に動くんですがそれは
645デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/15(木) 13:35:59.93ID:gWaB1LhD0 だから前者が動かないなんていてないだろ
前者に$(($x -1))の$xの$が意味がないから
(POSIX準拠で問題がない)後者の方が良いって話であって
たまにいるんだよな。誰かにより良いコードの提案をされたら
俺の書いたコードが間違っているっていうんか、仕様どおりだ!って怒るやつ
仕様違反だとか間違ってるかどうかの話なんかしてない
(正しいコードの範囲で)より良いコードにしましょうってことなのに
前者に$(($x -1))の$xの$が意味がないから
(POSIX準拠で問題がない)後者の方が良いって話であって
たまにいるんだよな。誰かにより良いコードの提案をされたら
俺の書いたコードが間違っているっていうんか、仕様どおりだ!って怒るやつ
仕様違反だとか間違ってるかどうかの話なんかしてない
(正しいコードの範囲で)より良いコードにしましょうってことなのに
646デフォルトの名無しさん (ワッチョイ 9564-uG0O)
2018/11/15(木) 14:51:03.70ID:sJsqi8La0 すまん。怒らせるつもりは毛頭なかったんだわ。
ただ,「標準でははこうなってますよ」と示しただけ。
まあちょっと俺の言い方もキツかったな。
言い訳させてもらうと,今までPOSIXの仕様書も読まずに
$(())算術展開は``に書き改めるべきとか,その割に[[文を使ってたりだとか
そういう人間と多く議論してきて,こっちもかなり厳密さを求めるようになってしまっていた。
正直なところ仕様違反でもほとんどの環境で動くなら,別にそっちを使ってもいいかもね。
ただ,「標準でははこうなってますよ」と示しただけ。
まあちょっと俺の言い方もキツかったな。
言い訳させてもらうと,今までPOSIXの仕様書も読まずに
$(())算術展開は``に書き改めるべきとか,その割に[[文を使ってたりだとか
そういう人間と多く議論してきて,こっちもかなり厳密さを求めるようになってしまっていた。
正直なところ仕様違反でもほとんどの環境で動くなら,別にそっちを使ってもいいかもね。
647デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/15(木) 14:58:36.45ID:gWaB1LhD0 だから仕様違反じゃないつってるだろうが
なんでこいつ理解能力無いんだろう?
冷静なふりして、冷静じゃないだろ
なんでこいつ理解能力無いんだろう?
冷静なふりして、冷静じゃないだろ
648デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/15(木) 15:08:37.91ID:gWaB1LhD0 $(($x - 1)) と $((x - 1)) のどちらも仕様違反じゃないのに
$(($x - 1)) が動くってことは、 $((x - 1)) は仕様違反に違いニダ!って
どういう思考回路なんだろ?
$(($x - 1)) と $((x - 1)) は前者が先に$xのパラメータ展開が行われるため動作に違いがある
https://github.com/koalaman/shellcheck/wiki/SC2004 に書いてあるとおり。
それはおそらく意図しないものだろうから警告される。
お前がPOSIXの仕様を読んでいない相手と議論してきたとか知らんが、
お前なんかよりも shellcheck の作者の方がよっぽどPOSIXの仕様に詳しいだろうよ
なにせシェルスクリプトの構文解析機を作ってるし、
世界中から間違いがあったら指摘される立場にあるんだから
$(($x - 1)) が動くってことは、 $((x - 1)) は仕様違反に違いニダ!って
どういう思考回路なんだろ?
$(($x - 1)) と $((x - 1)) は前者が先に$xのパラメータ展開が行われるため動作に違いがある
https://github.com/koalaman/shellcheck/wiki/SC2004 に書いてあるとおり。
それはおそらく意図しないものだろうから警告される。
お前がPOSIXの仕様を読んでいない相手と議論してきたとか知らんが、
お前なんかよりも shellcheck の作者の方がよっぽどPOSIXの仕様に詳しいだろうよ
なにせシェルスクリプトの構文解析機を作ってるし、
世界中から間違いがあったら指摘される立場にあるんだから
649デフォルトの名無しさん (ブーイモ MMf1-ed7b)
2018/11/15(木) 20:59:56.50ID:8sDmawlrM またvoid君かよ
650デフォルトの名無しさん (アウアウウー Sa91-AAco)
2018/11/16(金) 18:15:57.23ID:4Z/2Zn+la Windows用の busybox.exe なんてものがあることをたった今知った。
こんなのあったんだな。
まあしかしよくよく考えてみればWindows用のgccとかのコンパイラでコンパイルすれば良いだけだからさほど凄いことではないか。
こんなのあったんだな。
まあしかしよくよく考えてみればWindows用のgccとかのコンパイラでコンパイルすれば良いだけだからさほど凄いことではないか。
651デフォルトの名無しさん (ワッチョイ 9564-ddua)
2018/11/16(金) 20:52:55.20ID:0Fk/0vf10 case "$(<なにかの処理>)" in
'A'|'aaa') echo 'B' ;;
*) echo "$(<なにかの処理>)" ;;
esac
みたいな文でさ,<なにかの処理>を(できれば変数とか使わずに)一つにまとめたいんだけど
できるかな。
"$(<なにかの処理>)"の結果が'A'か'aaa'の時のみ'B'を出力して,それ以外の場合はその処理のまんまを出力したい。
RESULT="$(<なにかの処理>)"
case "$RESULT" in
'A'|'aaa') echo 'B' ;;
*) echo "$RESULT" ;;
esac
でもいいんだけどな〜んか無駄がある気がするんだよね……近い場所で二回同じ変数使ってるっていうのが。
'A'|'aaa') echo 'B' ;;
*) echo "$(<なにかの処理>)" ;;
esac
みたいな文でさ,<なにかの処理>を(できれば変数とか使わずに)一つにまとめたいんだけど
できるかな。
"$(<なにかの処理>)"の結果が'A'か'aaa'の時のみ'B'を出力して,それ以外の場合はその処理のまんまを出力したい。
RESULT="$(<なにかの処理>)"
case "$RESULT" in
'A'|'aaa') echo 'B' ;;
*) echo "$RESULT" ;;
esac
でもいいんだけどな〜んか無駄がある気がするんだよね……近い場所で二回同じ変数使ってるっていうのが。
652デフォルトの名無しさん (アウアウウー Sa91-AAco)
2018/11/16(金) 21:08:59.95ID:4Z/2Zn+la 気のせい
653デフォルトの名無しさん (ブーイモ MM2e-lnvm)
2018/11/16(金) 23:08:25.02ID:pv33BTTMM 算術展開で$付けるのはナンセンスだからやめたほうがいい
654デフォルトの名無しさん (ワッチョイ 3903-k2K5)
2018/11/16(金) 23:43:45.38ID:HodhQ/sE0 いい感じのバカっぽさw
655デフォルトの名無しさん (ブーイモ MM2e-lnvm)
2018/11/17(土) 00:11:39.03ID:dLBGWOhBM >>654
お前の書き込みがな
お前の書き込みがな
656デフォルトの名無しさん (ワッチョイ 3903-k2K5)
2018/11/17(土) 00:41:14.93ID:eQWBxdMf0 なんか悔しかったんかなw
657デフォルトの名無しさん (ワッチョイ ca98-9Fzi)
2018/11/17(土) 01:07:52.12ID:LhPQgZnG0 >>651
変数を使わないの書き方の基本の一つは引数(パラメータ)を使うことだよ
引数を変数の代わりとして使う。そのやり方に2パターンある
・パターン1 関数を作る(呼び出し先の関数の引数にする)
foo() {
case "$1" in
'A'|'aaa') echo 'B' ;;
*) echo "$1" ;;
esac
}
foo "$(<なにかの処理>)"
・パターン2 引数を再設定する(自分自身の引数にする)
set -- "$(<なにかの処理>)"
case "$1" in
'A'|'aaa') echo 'B' ;;
*) echo "$1" ;;
esac
パターン2はこのままだと自分自身の引数がなくなってしまうが、
set -- "$(<なにかの処理>)" "$@"
とすることで、残しておくことが可能。以降は引数の番号をずらして
扱うかshiftで元に戻すなりするか、引数の個数が固定なら、
set -- "$@" "$(<なにかの処理>)" と逆にしてもよい
余談だが、そんなコードを書くぐらいなら素直に変数を使えばいいと思うかもしれないが、
シェルスクリプトの変数がグローバル変数なのに対して、
引数は(レキシカルスコープ的な)ローカル変数になってるという重要な違いがある
localやtypesetを使った変数のローカル化はダイナミックスコープなのでそれとも違う
変数を使わないの書き方の基本の一つは引数(パラメータ)を使うことだよ
引数を変数の代わりとして使う。そのやり方に2パターンある
・パターン1 関数を作る(呼び出し先の関数の引数にする)
foo() {
case "$1" in
'A'|'aaa') echo 'B' ;;
*) echo "$1" ;;
esac
}
foo "$(<なにかの処理>)"
・パターン2 引数を再設定する(自分自身の引数にする)
set -- "$(<なにかの処理>)"
case "$1" in
'A'|'aaa') echo 'B' ;;
*) echo "$1" ;;
esac
パターン2はこのままだと自分自身の引数がなくなってしまうが、
set -- "$(<なにかの処理>)" "$@"
とすることで、残しておくことが可能。以降は引数の番号をずらして
扱うかshiftで元に戻すなりするか、引数の個数が固定なら、
set -- "$@" "$(<なにかの処理>)" と逆にしてもよい
余談だが、そんなコードを書くぐらいなら素直に変数を使えばいいと思うかもしれないが、
シェルスクリプトの変数がグローバル変数なのに対して、
引数は(レキシカルスコープ的な)ローカル変数になってるという重要な違いがある
localやtypesetを使った変数のローカル化はダイナミックスコープなのでそれとも違う
658デフォルトの名無しさん (ブーイモ MM2e-lnvm)
2018/11/17(土) 01:38:27.92ID:dLBGWOhBM >>656
お前が?w
お前が?w
659デフォルトの名無しさん (ワッチョイ 9564-ddua)
2018/11/17(土) 09:28:35.93ID:XLrbbNN30660デフォルトの名無しさん (ワッチョイ 56be-JwVn)
2018/11/17(土) 18:51:09.82ID:ikDL4PRg0 ちょっと力を貸してほしい
https://paste.ubuntu.com/p/hx6cFRKJKm/
今、↑こういう引数処理を書いている。
動作としては
$ ./argprs.sh -abc VAR -pqr FILE --long-opt --opt-req-par="foo bar" -- --not-opt
短いオプション1: a; 'VAR'
短いオプション2: b
短いオプション3: c
短いオプション4: p
短いオプション5: q
短いオプション6: r
被演算子1: FILE
長いオプション1: long-opt
長いオプション2: opt-req-par; 'foo bar'
被演算子2: --not-opt
こういう出力ができるはず。つまり-aと--opt-req-parはパラメータを取って、--以降はオプションとして解釈されないっていうやつ。
ところが俺の知識量では短いオプションを解析する部分をすごく冗長にしか書けない。いちいちループを回すせいで遅いし。
動作自体はこれでいいので、短いオプションをもうちょっとうまく解析する方法とかないかな。
https://paste.ubuntu.com/p/hx6cFRKJKm/
今、↑こういう引数処理を書いている。
動作としては
$ ./argprs.sh -abc VAR -pqr FILE --long-opt --opt-req-par="foo bar" -- --not-opt
短いオプション1: a; 'VAR'
短いオプション2: b
短いオプション3: c
短いオプション4: p
短いオプション5: q
短いオプション6: r
被演算子1: FILE
長いオプション1: long-opt
長いオプション2: opt-req-par; 'foo bar'
被演算子2: --not-opt
こういう出力ができるはず。つまり-aと--opt-req-parはパラメータを取って、--以降はオプションとして解釈されないっていうやつ。
ところが俺の知識量では短いオプションを解析する部分をすごく冗長にしか書けない。いちいちループを回すせいで遅いし。
動作自体はこれでいいので、短いオプションをもうちょっとうまく解析する方法とかないかな。
661デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/17(土) 19:14:04.69ID:DG9kgnl30 なんで、aのあとにVARくるんだ? 仕様がおかしくないか?
VARが単体の値もしくは、-cの値っていうのならまだわかるんだが
VARが単体の値もしくは、-cの値っていうのならまだわかるんだが
662デフォルトの名無しさん (ワッチョイ 3903-k2K5)
2018/11/17(土) 19:19:32.18ID:eQWBxdMf0 エクセルマクラーと同じ病気やね
663デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/17(土) 19:49:25.15ID:DG9kgnl30 tarで試したが、これで動くのかよ・・・
tar czvf a.tar.gz a
tar fczv a.tar.gz a
パラメータ取る短いオプションが複数あったとき
どう解釈するのが普通なんだろ
tar czvf a.tar.gz a
tar fczv a.tar.gz a
パラメータ取る短いオプションが複数あったとき
どう解釈するのが普通なんだろ
664デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/17(土) 20:09:39.20ID:DG9kgnl30 getoptやgetoptsは短いオプションがパラメータを取るとき、
短いオプション以降がパラメータとみなされるようだ
-abcde で cがパラメータを取るとき、
-a -b -c de と解釈される
実装によってバラバラなのは当然だろうが
こっちのほうが楽だろうな
>>660の仕様だと、aとcがパラメータを取るとき
-abcde VAR をどう解釈して良いのかわからない
-abcde VAR1 VAR2 とすりゃいいのかもしれんが、
これは人間にとってわかりやすいんだろうか?
短いオプション以降がパラメータとみなされるようだ
-abcde で cがパラメータを取るとき、
-a -b -c de と解釈される
実装によってバラバラなのは当然だろうが
こっちのほうが楽だろうな
>>660の仕様だと、aとcがパラメータを取るとき
-abcde VAR をどう解釈して良いのかわからない
-abcde VAR1 VAR2 とすりゃいいのかもしれんが、
これは人間にとってわかりやすいんだろうか?
665デフォルトの名無しさん (ワッチョイ 3903-k2K5)
2018/11/17(土) 20:18:41.59ID:eQWBxdMf0 バカは考えるだけムダやぞw
666デフォルトの名無しさん (ワッチョイ ad23-H6Qh)
2018/11/17(土) 20:23:56.08ID:UtANxJrV0 >>663
tarはハイフン無しでオプションを書くといい感じに並べ替えてくれる
tarはハイフン無しでオプションを書くといい感じに並べ替えてくれる
667デフォルトの名無しさん (ワッチョイ 56be-JwVn)
2018/11/17(土) 20:45:00.33ID:ikDL4PRg0 つまり
-aVAR
-xyza VAR
みたいなのは許容して
-axyz VAR
は許容しないようにすればいいのかな。
まあ結局一文字オプションを扱う方法はくっそ遅いルーチンなのだがw
-aVAR
-xyza VAR
みたいなのは許容して
-axyz VAR
は許容しないようにすればいいのかな。
まあ結局一文字オプションを扱う方法はくっそ遅いルーチンなのだがw
668660 (ワッチョイ 56be-JwVn)
2018/11/17(土) 21:16:27.44ID:ikDL4PRg0 こうしてみました。
短いオプションの解析ルーチンの遅さは改善してませんが
値を取るオプションの解釈を皆さんから提示された方式に変えました。
https://paste.ubuntu.com/p/n7m8qZHwMb/
短いオプションの解析ルーチンの遅さは改善してませんが
値を取るオプションの解釈を皆さんから提示された方式に変えました。
https://paste.ubuntu.com/p/n7m8qZHwMb/
669デフォルトの名無しさん (ワッチョイ 3903-k2K5)
2018/11/17(土) 21:33:05.69ID:eQWBxdMf0 >>668
提示てwバカにされとんのやぞおまえw
提示てwバカにされとんのやぞおまえw
670デフォルトの名無しさん (ワッチョイ 56be-JwVn)
2018/11/17(土) 22:38:36.24ID:ikDL4PRg0 こういういったシェルスクリプトを書くの大変なので自動的に生成してくれるのがあればいいですけどね。
Pythonのdocoptみたいな。
Pythonのdocoptみたいな。
671デフォルトの名無しさん (ワッチョイ 3903-k2K5)
2018/11/17(土) 22:57:50.85ID:eQWBxdMf0672デフォルトの名無しさん (ワッチョイ 5633-wOWl)
2018/11/17(土) 23:25:40.65ID:4Do7jDVB0 ふつーに、getopts でええやん!
入力補完を使ったら、別にコマンドが長くてもわかりやすさ優先でかまへんわ。
入力補完を使ったら、別にコマンドが長くてもわかりやすさ優先でかまへんわ。
673デフォルトの名無しさん (ワッチョイ 8680-vjqa)
2018/11/17(土) 23:58:26.07ID:2WlUsnTW0 Ruby にも、OptionParser, ARGV.getopts などのモジュールがあるので、自作などしない
674デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 00:47:33.69ID:tOYW/MHy0675デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 01:05:23.45ID:tOYW/MHy0676デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 01:17:46.87ID:tOYW/MHy0 余計な変数を消したり、被演算子の部分を外出ししたりした
https://paste.ubuntu.com/p/p7VwzJZ8Hv/
あとオレがリファクタリングするときによくやるんだが、
(他人の)リファクタリングする前のコードは長いことが多い
全体を把握しやすくするためにあえて一行にしたりして短くしている。
最終的にこのような書き方をするというわけではなくて一時的な処置
https://paste.ubuntu.com/p/p7VwzJZ8Hv/
あとオレがリファクタリングするときによくやるんだが、
(他人の)リファクタリングする前のコードは長いことが多い
全体を把握しやすくするためにあえて一行にしたりして短くしている。
最終的にこのような書き方をするというわけではなくて一時的な処置
677デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 01:19:40.72ID:tOYW/MHy0 あと、これもしたな。こんな部分、あとでどうとでもなるんだからここでやることじゃない
長いオプション1: long-opt
長いオプション2: opt-req-par; 'foo bar'
↓
長いオプション1: --long-opt
長いオプション2: --opt-req-par; 'foo bar'
長いオプション1: long-opt
長いオプション2: opt-req-par; 'foo bar'
↓
長いオプション1: --long-opt
長いオプション2: --opt-req-par; 'foo bar'
678デフォルトの名無しさん (ワッチョイ 86cc-sJSV)
2018/11/18(日) 01:21:35.58ID:dx8aUZPH0 caseの後の変数はダブルコーテーションで括らなくていいって知ってた?
679デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 01:26:08.97ID:tOYW/MHy0 長いオプションの部分をフラットにした。
https://paste.ubuntu.com/p/Y4nTQBnTFw/
あとはクソめんどくさい一文字の部分だな。
どうするか考えとらんのだがw
仕様は変えるかもしれん。
https://paste.ubuntu.com/p/Y4nTQBnTFw/
あとはクソめんどくさい一文字の部分だな。
どうするか考えとらんのだがw
仕様は変えるかもしれん。
680デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 01:27:00.28ID:tOYW/MHy0 >>678
うん。だから徐々に消してるよw
うん。だから徐々に消してるよw
681デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 01:28:24.11ID:tOYW/MHy0 あ、いくつかパっと見でわかるミスがw
まあ途中のコードは参考だから
俺がどうやってリファクタリングしているか
まあ途中のコードは参考だから
俺がどうやってリファクタリングしているか
682デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 02:04:33.63ID:tOYW/MHy0 とりあえずは大まかな仕様は変えてない
https://paste.ubuntu.com/p/SQFnqmCJs2/
変数をなくそうか、でもそうすると再帰ありの関数を追加するか
setを使わないといけなくてごちゃごちゃする。
いろいろ悩んだがとりあえずそのままにしている。
cutの呼び出しはなくしたので速くなってるはず。
といっても、この程度だとLinuxなら体感できないはずなんだがWSLでやってる?
1文字オプションの分解の所がやはり面倒だな。
知らないオプションはエラーにするようにすれば、
1文字を抜き出す必要はなくなるかもしれないが
https://paste.ubuntu.com/p/SQFnqmCJs2/
変数をなくそうか、でもそうすると再帰ありの関数を追加するか
setを使わないといけなくてごちゃごちゃする。
いろいろ悩んだがとりあえずそのままにしている。
cutの呼び出しはなくしたので速くなってるはず。
といっても、この程度だとLinuxなら体感できないはずなんだがWSLでやってる?
1文字オプションの分解の所がやはり面倒だな。
知らないオプションはエラーにするようにすれば、
1文字を抜き出す必要はなくなるかもしれないが
683デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 02:13:58.54ID:tOYW/MHy0 >>670
> Pythonのdocoptみたいな。
あと一応あるで
https://github.com/docopt/docopts
goバイナリでオプション解析して、シェルスクリプトで
evalできるコードを出力して、そのコードで環境変数を
設定するという仕組みで、純粋なシェルスクリプト実装ではないけど
> Pythonのdocoptみたいな。
あと一応あるで
https://github.com/docopt/docopts
goバイナリでオプション解析して、シェルスクリプトで
evalできるコードを出力して、そのコードで環境変数を
設定するという仕組みで、純粋なシェルスクリプト実装ではないけど
684デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 02:21:13.13ID:tOYW/MHy0 ちなみにオプション解析の部分は一般的に最初に一回だけ行う部分なので
被らないようにしたり、無理して変数をなくす必要はないんだけどね
被らないようにしたり、無理して変数をなくす必要はないんだけどね
685デフォルトの名無しさん (ワッチョイ 56be-JwVn)
2018/11/18(日) 17:17:51.79ID:Fz4U8sel0 >>674
オプションの番号は,競合するオプションが指定された時に後者を優先する目的です。
rm -i -f
としたときに「確認する」のではなく「強制的に消し」たいので。
alias rm='\rm -i'
の状態でrm -fとしたときは確認オプションが有効になるんじゃなくて強制的に消去したいよね?
オプションの番号は,競合するオプションが指定された時に後者を優先する目的です。
rm -i -f
としたときに「確認する」のではなく「強制的に消し」たいので。
alias rm='\rm -i'
の状態でrm -fとしたときは確認オプションが有効になるんじゃなくて強制的に消去したいよね?
686デフォルトの名無しさん (ワッチョイ 56be-JwVn)
2018/11/18(日) 17:19:37.66ID:Fz4U8sel0687デフォルトの名無しさん (ワッチョイ 56be-JwVn)
2018/11/18(日) 17:23:02.81ID:Fz4U8sel0 連投すまん。
ちなみにどうやら汎用性のあるシェルスクリプトではローカル変数というのはsetを使わない限り実現できないようで,
そしてsetは今まさに解析すべき引数郡がが格納されているので安易に書き換えられない。
だからPythonの慣例を参考にして前後にアンダースコアを二つ続けて(無意味だけど)ローカル変数であることを示してるつもり。
ちなみにどうやら汎用性のあるシェルスクリプトではローカル変数というのはsetを使わない限り実現できないようで,
そしてsetは今まさに解析すべき引数郡がが格納されているので安易に書き換えられない。
だからPythonの慣例を参考にして前後にアンダースコアを二つ続けて(無意味だけど)ローカル変数であることを示してるつもり。
688デフォルトの名無しさん (ワッチョイ 56be-JwVn)
2018/11/18(日) 17:35:21.66ID:Fz4U8sel0 ${numbar:-0}←これすごいアイデアですね。
シェルスクリプトの冒頭でnumber=0とかで初期化しなくても、
「カウンターを初期化するのは値が設定されてないときである」ことを利用して変数展開を行なうのか。
シェルスクリプトの冒頭でnumber=0とかで初期化しなくても、
「カウンターを初期化するのは値が設定されてないときである」ことを利用して変数展開を行なうのか。
689デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 17:59:50.57ID:tOYW/MHy0 >>685
> オプションの番号は,競合するオプションが指定された時に後者を優先する目的です。
それなら変数に入れておけば良いんだよ。
競合するオプションなら、変数を同じにしておけば良い
基本的に「オプションの解析」では変数に値を入れるのみ
その場で処理はしない。変数に入れた値が後者で上書きされるから
必然的に後者が優先される
> その通り。WSLでやってる。なるほどLinuxネイティブではcutを一文字ごとに呼び出しても十分早いのかな?
time dash -c 'i=0; while [ $i -lt 1000 ]; do echo a | cut -c 1 > /dev/null; i=$((i+1)); done'
Linuxでこれを実行すると約1秒。WSLでこれを実行すると15秒。fork(サブプロセス生成)が行われるとこれだけの差がでる
元々forkは遅いのだが、WSL上だと更に輪をかけて遅くなるのがわかる
これをforkなしのシェルだけで実行できる同等のコードに置き換えるとWSLで50ミリ秒に減る。Linuxだと20ミリ秒にへる
time dash -c 'i=0; while [ $i -lt 1000 ]; do v=abc; v=${v%"${v#?}"}; echo $v >/dev/null ; i=$((i+1)); done'
もっともforkなしのコードは万能ではなく、文字列の最初の一文字を取るために「文字列の最初の一文字を取り除いた残り」を
求めてから、全体から抜き取っているために、文字列が長くなると極端に遅くなる。
文字列を1文字ずつ処理するコードを書いたとして、1000文字〜1万文字程度が限界。(数秒〜数十秒かかる)
それ以上の長さの文字列を1文字ずつ処理するコードを書くならsedあたりで1文字ずつに分解して処理したほうが良いだろう
POSIX準拠しなくていいなら${v:0:1} を使ったほうが速いと思う(計測はしてない)
だけど一般的なオプション程度の長さであれば十分速い。少なくともcutを使うよりも遅くなることはないだろう
> オプションの番号は,競合するオプションが指定された時に後者を優先する目的です。
それなら変数に入れておけば良いんだよ。
競合するオプションなら、変数を同じにしておけば良い
基本的に「オプションの解析」では変数に値を入れるのみ
その場で処理はしない。変数に入れた値が後者で上書きされるから
必然的に後者が優先される
> その通り。WSLでやってる。なるほどLinuxネイティブではcutを一文字ごとに呼び出しても十分早いのかな?
time dash -c 'i=0; while [ $i -lt 1000 ]; do echo a | cut -c 1 > /dev/null; i=$((i+1)); done'
Linuxでこれを実行すると約1秒。WSLでこれを実行すると15秒。fork(サブプロセス生成)が行われるとこれだけの差がでる
元々forkは遅いのだが、WSL上だと更に輪をかけて遅くなるのがわかる
これをforkなしのシェルだけで実行できる同等のコードに置き換えるとWSLで50ミリ秒に減る。Linuxだと20ミリ秒にへる
time dash -c 'i=0; while [ $i -lt 1000 ]; do v=abc; v=${v%"${v#?}"}; echo $v >/dev/null ; i=$((i+1)); done'
もっともforkなしのコードは万能ではなく、文字列の最初の一文字を取るために「文字列の最初の一文字を取り除いた残り」を
求めてから、全体から抜き取っているために、文字列が長くなると極端に遅くなる。
文字列を1文字ずつ処理するコードを書いたとして、1000文字〜1万文字程度が限界。(数秒〜数十秒かかる)
それ以上の長さの文字列を1文字ずつ処理するコードを書くならsedあたりで1文字ずつに分解して処理したほうが良いだろう
POSIX準拠しなくていいなら${v:0:1} を使ったほうが速いと思う(計測はしてない)
だけど一般的なオプション程度の長さであれば十分速い。少なくともcutを使うよりも遅くなることはないだろう
690デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/18(日) 18:05:11.85ID:tOYW/MHy0 >>668
今回は長いコードが邪魔だったので使ったけど、
例えばnumberが環境変数としてexportされていたりしたら
おかしいことになるので最初に初期化するほうが良いけどね
毎回パラメータ展開してるからわずかとはいえ遅くなるだろうし
それよりも、所見では使い道がわからない
${var:+value}の方が凄いアイデア
シェルを作った人はよくもまあこんな応用例が
高いものを作ったもんだと思うよ
今回は長いコードが邪魔だったので使ったけど、
例えばnumberが環境変数としてexportされていたりしたら
おかしいことになるので最初に初期化するほうが良いけどね
毎回パラメータ展開してるからわずかとはいえ遅くなるだろうし
それよりも、所見では使い道がわからない
${var:+value}の方が凄いアイデア
シェルを作った人はよくもまあこんな応用例が
高いものを作ったもんだと思うよ
691デフォルトの名無しさん (ワッチョイ 56be-JwVn)
2018/11/18(日) 23:06:30.15ID:Fz4U8sel0 test <string>は<string>が非空に限り成功するのね。これも知らんかったわ……。
692デフォルトの名無しさん (ワッチョイ 9564-ddua)
2018/11/21(水) 17:53:42.80ID:OLor19Fe0 しつこくてすまん。
シェルスクリプトの引数解析の話なんだが
(-cが引数を取るオプションとして)
「$ somecmd -c -- --not-a-opt」
っていうコマンドラインにおいて,
・「--」を-cオプションの引数として見るか
・「--」はいかなる場所(オプションの引数の位置だとしても)においても
以降が被演算子であることを示すものであると見るか
どっちが自然だろう。GNU getoptは前者の解析結果を出すけど恐らく内部的には後者の解釈で
エラーになる。
シェルスクリプトの引数解析の話なんだが
(-cが引数を取るオプションとして)
「$ somecmd -c -- --not-a-opt」
っていうコマンドラインにおいて,
・「--」を-cオプションの引数として見るか
・「--」はいかなる場所(オプションの引数の位置だとしても)においても
以降が被演算子であることを示すものであると見るか
どっちが自然だろう。GNU getoptは前者の解析結果を出すけど恐らく内部的には後者の解釈で
エラーになる。
693デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/21(水) 18:33:47.11ID:UM5ff+tU0 引数取るなら何であれ引数に決まってるだろ
どうでもいいけどさ、その被演算子ってのやめてくんない?
演算子なんて登場してないんだから
どうでもいいけどさ、その被演算子ってのやめてくんない?
演算子なんて登場してないんだから
694デフォルトの名無しさん (ワッチョイ 9564-ddua)
2018/11/21(水) 18:55:25.78ID:OLor19Fe0 operandって被演算子のことだと思うんだけど。
まあ「--」を引数と見るってことね。ありがとう。
まあ「--」を引数と見るってことね。ありがとう。
695デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/21(水) 19:16:12.30ID:UM5ff+tU0 だからそのoperandが出てこないって話
696デフォルトの名無しさん (ワンミングク MM5a-sJSV)
2018/11/21(水) 20:33:17.21ID:cLxfY5McM697デフォルトの名無しさん (ワッチョイ 8698-9Fzi)
2018/11/21(水) 21:01:13.07ID:UM5ff+tU0698デフォルトの名無しさん (ワッチョイ 9564-ddua)
2018/11/21(水) 21:31:00.38ID:OLor19Fe0 ああ。ほんとだ。The Open Groupの文書を参考にする限り
somecmd -c XXX FILE
とあった場合被演算子はFILEでXXXはオプション引数だね。勘違いしてた。
somecmd -c XXX FILE
とあった場合被演算子はFILEでXXXはオプション引数だね。勘違いしてた。
699デフォルトの名無しさん (ワッチョイ 8fbe-pqc8)
2018/11/24(土) 12:14:20.49ID:I8hvszb00 Qiitaで知ったけどこの構文便利だね。
${VAL+:} false
↑これで$VAL変数が空文字だろうが定義されてさえいれば真,そうでなけば偽。
今まで[ -n ]と[ "x$VAL" = "$VAL:-x" ]とか組み合わせてたけどこれでスッキリ解決。
コマンド呼び出しも少なくなるから微妙に処理速度も上がるだろうし。
ただ難点は,test構文を用いた方法より遥かに難読になること。${VAL+:} false←これで何をやってるかなんて注釈がないと分からん。
${VAL+:} false
↑これで$VAL変数が空文字だろうが定義されてさえいれば真,そうでなけば偽。
今まで[ -n ]と[ "x$VAL" = "$VAL:-x" ]とか組み合わせてたけどこれでスッキリ解決。
コマンド呼び出しも少なくなるから微妙に処理速度も上がるだろうし。
ただ難点は,test構文を用いた方法より遥かに難読になること。${VAL+:} false←これで何をやってるかなんて注釈がないと分からん。
700デフォルトの名無しさん (ワッチョイ cf98-/G1A)
2018/11/24(土) 12:41:53.30ID:emfrr2Lm0701デフォルトの名無しさん (アウアウカー Sa87-fvbk)
2018/11/24(土) 14:04:21.10ID:jPqivsUqa 定義されてるかどうかってどういう時に用いるんだ
C言語やってた頃は二重インポート防ぐためとかやってたけど同じような感じ?
C言語やってた頃は二重インポート防ぐためとかやってたけど同じような感じ?
702デフォルトの名無しさん (ワッチョイ 8fbe-pqc8)
2018/11/24(土) 14:31:59.62ID:I8hvszb00 >>700
「一般的」かどうかは知らない。それともその形式がより多く使われているという根拠があるのかな?
いずれにしてもコロンコマンド(と変数展開)がシェルのビルトインとしてPOSIXで定められているのに対して
testコマンドはPOSIXにおいては外部コマンド。尤もBashやZshではシェルに組み込まれてるけど。
外部コマンドを呼び出すのとシェルの内部でコマンドを展開するとでは後者のほうが早いよ。
君にとっては「Qittaクオリティ」でも,速度が優秀なのは君が提示したほうじゃなく「Qittaクオリティ」の方。
「一般的」かどうかは知らない。それともその形式がより多く使われているという根拠があるのかな?
いずれにしてもコロンコマンド(と変数展開)がシェルのビルトインとしてPOSIXで定められているのに対して
testコマンドはPOSIXにおいては外部コマンド。尤もBashやZshではシェルに組み込まれてるけど。
外部コマンドを呼び出すのとシェルの内部でコマンドを展開するとでは後者のほうが早いよ。
君にとっては「Qittaクオリティ」でも,速度が優秀なのは君が提示したほうじゃなく「Qittaクオリティ」の方。
703デフォルトの名無しさん (ワッチョイ 8fbe-pqc8)
2018/11/24(土) 14:49:43.89ID:I8hvszb00 dashでも[はシェル組込だね。実際testユーティリティを外部コマンドに頼ってるシェルって今現在存在しているのだろうか。
Heirloom shellあたりだとありえそう(試してないけど)
Heirloom shellあたりだとありえそう(試してないけど)
704デフォルトの名無しさん (ワッチョイ cf98-/G1A)
2018/11/24(土) 15:54:11.31ID:emfrr2Lm0 > 「一般的」かどうかは知らない。それともその形式がより多く使われているという根拠があるのかな?
ぐぐればコレばっかり見つかるはずだが?
> testコマンドはPOSIXにおいては外部コマンド。尤もBashやZshではシェルに組み込まれてるけど。
全てのシェルで [ はビルトインだ
シェルに組み込まれていないというものがあれば教えてくれ
ぐぐればコレばっかり見つかるはずだが?
> testコマンドはPOSIXにおいては外部コマンド。尤もBashやZshではシェルに組み込まれてるけど。
全てのシェルで [ はビルトインだ
シェルに組み込まれていないというものがあれば教えてくれ
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【調査】クレジットカード、1人何枚持つのが「平均的」?★3 [ひぃぃ★]
- 【テレビ】池上彰氏 報道の自由度が高い国の特徴「どんどん政府を批判する。政治家は受け入れる」 一方独裁国家は… [冬月記者★]
- 【サッカー】カズ J復帰も!福島がオファー 鈴鹿無念の地域リーグ降格…59歳シーズン新天地はJ3? [征夷大将軍★]
- 小6がオスカー大型オーディションのグランプリ!横須賀京香「唯一無二の俳優に」目標は大谷翔平 [征夷大将軍★]
- 「『ETC』←なんて読んでますか?」 公募で決めたのに全然呼ばれなかった“幻の愛称”とは [七波羅探題★]
- 【サッカー】カズ・三浦知良 来季も現役続行を明言! 来年2月に59歳 「12月から来季に向けての自主トレを予定してます」 [冬月記者★]
