!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:BBiLRgnj0537デフォルトの名無しさん (ワッチョイ 039f-VYDo)
2018/11/07(水) 13:45:31.17ID:v2POOMdv0 ほんと場合によってってって無いやつだな。原理主義者か?
538デフォルトの名無しさん (ガックシ 06b6-ofXo)
2018/11/07(水) 13:49:03.61ID:8DqZdVO16539デフォルトの名無しさん (ワッチョイ 9a98-QXT6)
2018/11/07(水) 13:57:13.33ID:UCphLCxy0 ロックの確認とロックかけるのをアトミックにやらないとか
まともにロック処理やったことがない証拠だよ
これは初心者は誰でもやる典型的な間違いだからな
基本を知らずに独自の思いつきで実装するからそうなる
言われれ初めて気づく。だが一回言われればこうやれば
解決できるのかと深く記憶する話だから、単純に知識が欠けてるということ
だから他の言語でもどうせ同じなんだろということ。
まともにロック処理やったことがない証拠だよ
これは初心者は誰でもやる典型的な間違いだからな
基本を知らずに独自の思いつきで実装するからそうなる
言われれ初めて気づく。だが一回言われればこうやれば
解決できるのかと深く記憶する話だから、単純に知識が欠けてるということ
だから他の言語でもどうせ同じなんだろということ。
540デフォルトの名無しさん (ガックシ 06b6-ofXo)
2018/11/07(水) 15:22:16.58ID:8DqZdVO16 ksh --helpは出力される手引きが装飾されてるね
541デフォルトの名無しさん (ブーイモ MM7f-bq42)
2018/11/07(水) 15:56:27.81ID:A+xcJusCM 最初っから主張の根拠を提示すれば良かったのに
何だかんだで下らないレスが続くの止めて欲しい
何だかんだで下らないレスが続くの止めて欲しい
542デフォルトの名無しさん (アウアウエー Sa52-lVsa)
2018/11/07(水) 17:41:34.46ID:P+AQGnBFa echo "echo \"Hello, world\!\""
これ実行したら
echo "Hello, world!"
にならない
echo "Hello, world\!"
なぜか!だけ手前についてしまう
これ実行したら
echo "Hello, world!"
にならない
echo "Hello, world\!"
なぜか!だけ手前についてしまう
543デフォルトの名無しさん (ワッチョイ 5b64-ofXo)
2018/11/07(水) 18:45:58.27ID:XzpCa+6s0544デフォルトの名無しさん (ワッチョイ 5b64-ofXo)
2018/11/07(水) 18:49:27.43ID:XzpCa+6s0 間違えてた。
「echo "echo \"Hello, world!\""」にして。
スクリプトの中ではPOSIX互換のインタラクティブシェルは
履歴展開をしないので上手くいく。
「echo "echo \"Hello, world!\""」にして。
スクリプトの中ではPOSIX互換のインタラクティブシェルは
履歴展開をしないので上手くいく。
545デフォルトの名無しさん (ワッチョイ 9a98-QXT6)
2018/11/07(水) 19:24:02.67ID:UCphLCxy0 そういやkshで思い出したけど、
ksh88ってもしかして比較的最近(今も?)使われてたりする?
ksh88っていうぐらいだから1988年だろ?ksh93っていうぐらいだから1993年だろ?
流石にksh88はなんて30年前の化石使われてないだろ?と思ったけど
Solaris 11 でこんなこと書かれてたんだよね。意外と最近まで使われていたのかなぁ?と
https://docs.oracle.com/cd/E26924_01/html/E25934/userenv-1.html
> シェルの変更 - デフォルトのシェル /bin/sh が ksh93 にリンクされるようになりました。
> レガシー Bourne シェルは /usr/sunos/bin/sh として使用可能です。
> 旧バージョンの ksh88 は、shell/ksh88 パッケージの /usr/sunos/bin/ksh として使用可能になっています。
Solaris 11が最新版って言っても2011年11月9日リリースなので2日後に7年前のOSになるけど
(でもサポートはSolaris 10が2021年までなのか・・・)
そしてksh93の機能でこんな事書いてたんで、$(( )) が使えないシェルはksh88だったんだなって思ったところ
https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/com.ibm.aix.osdevice/korn_shell_enhanced.htm
ksh88ってもしかして比較的最近(今も?)使われてたりする?
ksh88っていうぐらいだから1988年だろ?ksh93っていうぐらいだから1993年だろ?
流石にksh88はなんて30年前の化石使われてないだろ?と思ったけど
Solaris 11 でこんなこと書かれてたんだよね。意外と最近まで使われていたのかなぁ?と
https://docs.oracle.com/cd/E26924_01/html/E25934/userenv-1.html
> シェルの変更 - デフォルトのシェル /bin/sh が ksh93 にリンクされるようになりました。
> レガシー Bourne シェルは /usr/sunos/bin/sh として使用可能です。
> 旧バージョンの ksh88 は、shell/ksh88 パッケージの /usr/sunos/bin/ksh として使用可能になっています。
Solaris 11が最新版って言っても2011年11月9日リリースなので2日後に7年前のOSになるけど
(でもサポートはSolaris 10が2021年までなのか・・・)
そしてksh93の機能でこんな事書いてたんで、$(( )) が使えないシェルはksh88だったんだなって思ったところ
https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/com.ibm.aix.osdevice/korn_shell_enhanced.htm
546デフォルトの名無しさん (アウアウエー Sa52-lVsa)
2018/11/07(水) 20:49:34.06ID:nHlOtVrla547デフォルトの名無しさん (ワッチョイ 5b64-74J5)
2018/11/07(水) 20:55:26.75ID:XzpCa+6s0548デフォルトの名無しさん (ワッチョイ 5b64-74J5)
2018/11/07(水) 21:01:40.12ID:XzpCa+6s0 >>546
「echo "echo \"Hello, world"'!'"\""」とかどうだろう。
参考: https://www.gnu.org/software/bash/manual/html_node/History-Interaction.html#History-Interaction
History expansions are introduced by the appearance of the history expansion character, which is ‘!’ by default. Only ‘\’ and ‘'’ may be used to escape the history expansion character,
but the history expansion character is also treated as quoted if it immediately precedes the closing double quote in a double-quoted string.
「echo "echo \"Hello, world"'!'"\""」とかどうだろう。
参考: https://www.gnu.org/software/bash/manual/html_node/History-Interaction.html#History-Interaction
History expansions are introduced by the appearance of the history expansion character, which is ‘!’ by default. Only ‘\’ and ‘'’ may be used to escape the history expansion character,
but the history expansion character is also treated as quoted if it immediately precedes the closing double quote in a double-quoted string.
549デフォルトの名無しさん (ワッチョイ 9a98-QXT6)
2018/11/07(水) 21:21:50.95ID:UCphLCxy0 >>547
ksh・・・お前が諸悪の根源だったか
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=861743
> % posh -u -c 'echo "$@"'
> posh: @: parameter not set
poshはpdkshからフォークしている
> posh (0.0.1) unstable; urgency=low
> * Initial release. (copied from pdksh 5.2.14-6). closes: bug#150431.
そしてシンプルな(笑)解決方法をありがとう
(if書くのはもっと面倒だった)
もっとバッドノウハウあったら教えてくれ!
ksh・・・お前が諸悪の根源だったか
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=861743
> % posh -u -c 'echo "$@"'
> posh: @: parameter not set
poshはpdkshからフォークしている
> posh (0.0.1) unstable; urgency=low
> * Initial release. (copied from pdksh 5.2.14-6). closes: bug#150431.
そしてシンプルな(笑)解決方法をありがとう
(if書くのはもっと面倒だった)
もっとバッドノウハウあったら教えてくれ!
550デフォルトの名無しさん (ワッチョイ 5b64-74J5)
2018/11/07(水) 22:18:01.95ID:XzpCa+6s0 >>549
あー。分かってると思うがこれは俺が考えた方法じゃない。
古いGNU grepでegrepコマンドを
https://git.savannah.gnu.org/cgit/grep.git/tree/src/Makefile.am?h=v2.5.1#n23
↑こうやって作ってたのを見掛けてさ。
これはすごい方法だと思って自分のシェルスクリプトに取り入れた。
でもPOSIX 2013でset -uが有効のときでも空の変数$@および変数$*がエラーにならない
っていうことが決定されたのでもう不必要。
http://pubs.opengroup.org/onlinepubs/9699919799.2013edition/utilities/V3_chap02.html#tag_18_25_18
あー。分かってると思うがこれは俺が考えた方法じゃない。
古いGNU grepでegrepコマンドを
https://git.savannah.gnu.org/cgit/grep.git/tree/src/Makefile.am?h=v2.5.1#n23
↑こうやって作ってたのを見掛けてさ。
これはすごい方法だと思って自分のシェルスクリプトに取り入れた。
でもPOSIX 2013でset -uが有効のときでも空の変数$@および変数$*がエラーにならない
っていうことが決定されたのでもう不必要。
http://pubs.opengroup.org/onlinepubs/9699919799.2013edition/utilities/V3_chap02.html#tag_18_25_18
551デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/08(木) 00:40:04.66ID:rJTiWJ810 >>550
modernishでも言及されてた。時代遅れのワークアラウンドだってw
でも現存するシェルに蘇っておるのじゃよ
昔の人には有名な回避策なのかな?
https://github.com/modernish/modernish/blob/master/README.md
> BUG_PARONEARG: When IFS is empty on bash 3.x and 4.x (i.e. field splitting is off),
> ${1+"$@"} is counted as a single argument instead of each positional parameter as
> separate arguments. To avoid this bug, simply use "$@" instead. (${1+"$@"}
> is an obsolete workaround for a fatal shell bug, FTL_UPP.)
modernishでも言及されてた。時代遅れのワークアラウンドだってw
でも現存するシェルに蘇っておるのじゃよ
昔の人には有名な回避策なのかな?
https://github.com/modernish/modernish/blob/master/README.md
> BUG_PARONEARG: When IFS is empty on bash 3.x and 4.x (i.e. field splitting is off),
> ${1+"$@"} is counted as a single argument instead of each positional parameter as
> separate arguments. To avoid this bug, simply use "$@" instead. (${1+"$@"}
> is an obsolete workaround for a fatal shell bug, FTL_UPP.)
552デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/08(木) 06:54:13.32ID:RnVV1kHy0 modernishおもしろいね。
modernishプロジェクトはcase文の条件の先頭に開き丸括弧を付けてるのか。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04_05
ここには確かに開き丸括弧を前置してもいいとあるけど一般的には省略されるでしょ。
なにかこれも旧時代のシェルの不具合への回避策なのかな。
それこそGNU Bash 3.xで動かない,とか。
modernishプロジェクトはcase文の条件の先頭に開き丸括弧を付けてるのか。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04_05
ここには確かに開き丸括弧を前置してもいいとあるけど一般的には省略されるでしょ。
なにかこれも旧時代のシェルの不具合への回避策なのかな。
それこそGNU Bash 3.xで動かない,とか。
553デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/08(木) 21:39:50.16ID:rJTiWJ810 >>552
やっとmodernishに興味を持ってくれた人がw
まあ俺もバグ情報とか参考になるなって程度にしか見てないんだけど
> modernishプロジェクトはcase文の条件の先頭に開き丸括弧を付けてるのか。
それ見た時、何この文法?modernishでそこまで拡張できるの?って驚いたw
単なる普通の文法だったわけだけど
> それこそGNU Bash 3.xで動かない,とか。
少なくともbash 2.03では開き括弧なくて動くよ
やっとmodernishに興味を持ってくれた人がw
まあ俺もバグ情報とか参考になるなって程度にしか見てないんだけど
> modernishプロジェクトはcase文の条件の先頭に開き丸括弧を付けてるのか。
それ見た時、何この文法?modernishでそこまで拡張できるの?って驚いたw
単なる普通の文法だったわけだけど
> それこそGNU Bash 3.xで動かない,とか。
少なくともbash 2.03では開き括弧なくて動くよ
554デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/08(木) 21:43:11.48ID:rJTiWJ810 話変わるけど、 foo | bar みたいなコマンドで
fooからたくさん出力されるけど、barの処理が遅いってとき
fooからの出力ってブロックされるのかな?
なんか20〜30行ぐらいでブロックされるような
出力の停止、遅延が起きてる気がする
メモリにバッファリングするだろうから、それが溢れないような処置として
そういう仕様は理解できるけど、どこかに書いてあるのかな?
シェルの仕様っぽい気がするけど、OSも絡んでいそうな気もする
fooからたくさん出力されるけど、barの処理が遅いってとき
fooからの出力ってブロックされるのかな?
なんか20〜30行ぐらいでブロックされるような
出力の停止、遅延が起きてる気がする
メモリにバッファリングするだろうから、それが溢れないような処置として
そういう仕様は理解できるけど、どこかに書いてあるのかな?
シェルの仕様っぽい気がするけど、OSも絡んでいそうな気もする
555デフォルトの名無しさん (ワッチョイ 418a-ANGR)
2018/11/08(木) 21:57:11.56ID:M53t5TPP0 >>554
タネンバウム先生の本は読んでるんだよね?
タネンバウム先生の本は読んでるんだよね?
556デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/08(木) 21:59:18.34ID:rJTiWJ810 >>555
読んでないよ。どれ読めばいい?
読んでないよ。どれ読めばいい?
557デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/08(木) 22:12:14.64ID:RnVV1kHy0 全然かわいくないアライグマの表紙の本じゃない?
558デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/08(木) 22:21:06.03ID:rJTiWJ810 お、再現した
i=0
while :; do
i=$((i+1))
echo test$i
echo log$i>&2
done | while read line; do
echo $line
sleep 3
done
パイプの前で無限ループで標準出力と標準エラー出力に高速に出力してるとき
パイプの後ろの遅い標準入力から入力の処理によって
パイプの前の標準エラー出力への出力がブロックされてる
7400行(64KB程度?)ぐらいまでは、パイプの後ろの処理を待つことなく高速に
標準エラー出力に出力するが、それ移行は1行ずつ出力するようになった。
i=0
while :; do
i=$((i+1))
echo test$i
echo log$i>&2
done | while read line; do
echo $line
sleep 3
done
パイプの前で無限ループで標準出力と標準エラー出力に高速に出力してるとき
パイプの後ろの遅い標準入力から入力の処理によって
パイプの前の標準エラー出力への出力がブロックされてる
7400行(64KB程度?)ぐらいまでは、パイプの後ろの処理を待つことなく高速に
標準エラー出力に出力するが、それ移行は1行ずつ出力するようになった。
559デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/08(木) 22:23:20.00ID:rJTiWJ810560デフォルトの名無しさん (ワッチョイ db9f-9t8X)
2018/11/09(金) 04:14:42.04ID:hZOut+vv0561デフォルトの名無しさん (ワッチョイ 2b80-KpfW)
2018/11/09(金) 04:37:21.46ID:WTWdJdbs0 パイプは、入力が来るまで、ブロックされる
562デフォルトの名無しさん (ワッチョイ 9164-TRt+)
2018/11/09(金) 05:22:03.56ID:3ZHBVzZ50 いわゆる普通のプログラミング言語(PythonやCやJavaScript)に対して,シェルスクリプトを作る上で気をつけてることってある?
例えば「局所変数や局所関数が宣言できないのでなるべく使わない」とかさ。
例えば「局所変数や局所関数が宣言できないのでなるべく使わない」とかさ。
563デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 08:16:02.70ID:UVRb8J0Z0564デフォルトの名無しさん (ワッチョイ dbe7-Llh/)
2018/11/09(金) 08:22:51.21ID:PBD+wepW0 パイプはカットすればいい
565デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 08:36:27.28ID:UVRb8J0Z0 >>562
個人的な特殊な状況下で気をつけてることならたくさんあるんだけどな
パイプを(なるべく)使わないとかwww
そうさなぁ、例えば意図せぬエラーで落ちるように、set -eを使う場合は
挙動をよく理解して使うこととかかな
set -eは戻り値がエラーになった時点で中断される
set -e
foo() { echo foo begin; bar; echo foo end; }
bar() { echo bar begin; baz; echo bar end; }
baz() { echo baz; false; }
foo
これを実行すると、foo -> bar -> baz の呼び出しの流れが、bazのfalseで中断されて
foo begin
bar begin
baz
と表示されるんだが
foo の代わりに if foo; then :; fi と実行すると
なんと、foo end も bar end も表示されるんだよ
つまり foo を if や && や || と組み合わせて使うと、エラー中断機能が無効化される
だから、比較関数みたいに if foo; then という使い方を想定している関数は
中でしっかりエラーチェックをしておくこと
他の言語の例外みたいに考えてはいけない
個人的な特殊な状況下で気をつけてることならたくさんあるんだけどな
パイプを(なるべく)使わないとかwww
そうさなぁ、例えば意図せぬエラーで落ちるように、set -eを使う場合は
挙動をよく理解して使うこととかかな
set -eは戻り値がエラーになった時点で中断される
set -e
foo() { echo foo begin; bar; echo foo end; }
bar() { echo bar begin; baz; echo bar end; }
baz() { echo baz; false; }
foo
これを実行すると、foo -> bar -> baz の呼び出しの流れが、bazのfalseで中断されて
foo begin
bar begin
baz
と表示されるんだが
foo の代わりに if foo; then :; fi と実行すると
なんと、foo end も bar end も表示されるんだよ
つまり foo を if や && や || と組み合わせて使うと、エラー中断機能が無効化される
だから、比較関数みたいに if foo; then という使い方を想定している関数は
中でしっかりエラーチェックをしておくこと
他の言語の例外みたいに考えてはいけない
566デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 08:39:06.36ID:UVRb8J0Z0 ↑ これが理由で、set -eは使うな派もいるらしいねw
>>562
> 例えば「局所変数や局所関数が宣言できないのでなるべく使わない」とかさ。
俺は訳あってそうしてるけど、特定のシェルに限って良いのなら
localもしくはtypesetで局所変数使えるよ
ただし、他の言語と違ってレキシカルスコープじゃなくて
ダイナミックスコープなので注意が必要
これも気をつけていることかな
>>562
> 例えば「局所変数や局所関数が宣言できないのでなるべく使わない」とかさ。
俺は訳あってそうしてるけど、特定のシェルに限って良いのなら
localもしくはtypesetで局所変数使えるよ
ただし、他の言語と違ってレキシカルスコープじゃなくて
ダイナミックスコープなので注意が必要
これも気をつけていることかな
567デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 08:44:20.66ID:UVRb8J0Z0 あと他の言語でも同じだけどshellcheckは基本やね
ダブルクォートでくくるとか、shellcheckで警告出るものは
ここでグダグダ書かないよ。
ダブルクォートでくくるとか、shellcheckで警告出るものは
ここでグダグダ書かないよ。
568デフォルトの名無しさん (アウアウウー Sa05-ahuQ)
2018/11/09(金) 09:08:37.30ID:JsSTi+Gxa569デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 09:16:09.65ID:UVRb8J0Z0570デフォルトの名無しさん (アウアウカー Sa9d-f/7Y)
2018/11/09(金) 09:18:07.88ID:FKBIIb3sa 明らかにそんなレベルの回答求めてないよねっていう語りたがり
571デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 09:24:33.15ID:UVRb8J0Z0 ん? あぁ、質問はコレね
> メモリにバッファリングするだろうから、それが溢れないような処置として
> そういう仕様は理解できるけど、どこかに書いてあるのかな?
>
> シェルの仕様っぽい気がするけど、OSも絡んでいそうな気もする
> メモリにバッファリングするだろうから、それが溢れないような処置として
> そういう仕様は理解できるけど、どこかに書いてあるのかな?
>
> シェルの仕様っぽい気がするけど、OSも絡んでいそうな気もする
572デフォルトの名無しさん (アウアウウー Sa05-ahuQ)
2018/11/09(金) 09:31:46.72ID:JsSTi+Gxa どう考えてもOSの仕様だろう。
573デフォルトの名無しさん (ワッチョイ 9164-TRt+)
2018/11/09(金) 09:40:49.31ID:3ZHBVzZ50574デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 09:55:47.54ID:UVRb8J0Z0575デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/09(金) 10:07:47.85ID:3ZHBVzZ50 ああ。たしかにパイプ越しに変数を参照させようと思ったらexportして環境変数にしなくちゃらんもんな。
576デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 10:31:29.63ID:UVRb8J0Z0 > ああ。たしかにパイプ越しに変数を参照させようと思ったらexportして環境変数にしなくちゃらんもんな。
もうちょっと説明すると
foo() {
output | bar | baz
}
fooで見えてる変数を、bar, bazに見せるのは簡単なんだよ。
exportしなくても見せられる。
outputが出力する1行をbarが解析して変数に入れたとして、その変数を
bazで見ることはできない(barでexportしても無理)
bazが複数行の入力を集計した結果の変数をfooで見ることが出来ない。とかね
1データを1行に詰め込めればパイプ経由でのデータ受け渡しは可能だが
それができないデータだと難しい
他の言語でやれって? それをシェルスクリプトでやらなきゃいけないというのが個人的な特殊な状況下というわけ
もうちょっと説明すると
foo() {
output | bar | baz
}
fooで見えてる変数を、bar, bazに見せるのは簡単なんだよ。
exportしなくても見せられる。
outputが出力する1行をbarが解析して変数に入れたとして、その変数を
bazで見ることはできない(barでexportしても無理)
bazが複数行の入力を集計した結果の変数をfooで見ることが出来ない。とかね
1データを1行に詰め込めればパイプ経由でのデータ受け渡しは可能だが
それができないデータだと難しい
他の言語でやれって? それをシェルスクリプトでやらなきゃいけないというのが個人的な特殊な状況下というわけ
577デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/09(金) 17:10:16.74ID:3ZHBVzZ50 シェルスクリプトでそのコマンドが実行された行数を取得する方法ってあるかな。
#!/usr/bin/env bashにすれば${LINENO}変数にその位置が格納されてるので簡単なんだけど
やっぱりもうすこし汎用的な方法で実現したい。
#!/usr/bin/env bashにすれば${LINENO}変数にその位置が格納されてるので簡単なんだけど
やっぱりもうすこし汎用的な方法で実現したい。
578デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 19:41:43.60ID:UVRb8J0Z0 >>577
LINENOしかないよ。ただしご存知の通りLINENOは使えないシェルがある。
dashなんか機能的には搭載されてるがdebianなどでは無効にされてるというw
更にシェルによっては関数呼び出しを行った時にソースコードの行数ではなく
関数の頭からの行数になっていて、それも0から始まるものと1から始まるものがある
まともに使えるのはbashだけかな
LINENOしかないよ。ただしご存知の通りLINENOは使えないシェルがある。
dashなんか機能的には搭載されてるがdebianなどでは無効にされてるというw
更にシェルによっては関数呼び出しを行った時にソースコードの行数ではなく
関数の頭からの行数になっていて、それも0から始まるものと1から始まるものがある
まともに使えるのはbashだけかな
579デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/09(金) 20:27:42.80ID:3ZHBVzZ50 >>578
だよね〜。ファイルの中での自分の位置を調べるのはシェルスクリプトでは無理っぽいね。
Cのassert()関数みたいなのを自作したかったんだけど 機能が落ちるのは嫌だな(もういいけど)
ああ ちなみに
> 関数呼び出しを行った時にソースコードの行数ではなく
> 関数の頭からの行数になっていて
これGNU Bashのことを言ってるのなら関数じゃなくて別名にすればO.K.だよ
だよね〜。ファイルの中での自分の位置を調べるのはシェルスクリプトでは無理っぽいね。
Cのassert()関数みたいなのを自作したかったんだけど 機能が落ちるのは嫌だな(もういいけど)
ああ ちなみに
> 関数呼び出しを行った時にソースコードの行数ではなく
> 関数の頭からの行数になっていて
これGNU Bashのことを言ってるのなら関数じゃなくて別名にすればO.K.だよ
580デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/09(金) 21:02:47.30ID:UVRb8J0Z0 >>579
シェルスクリプトの世界にJavaScriptのトランスパイラ技術が導入されて
ソースコードの一行一行にLINENOを設定するコードを埋め込めば
解決できると思うんだが、流石にそれをやろうとする人はいないかなw
> これGNU Bashのことを言ってるのなら関数じゃなくて別名にすればO.K.だよ
alias?うーん、なんか別の問題がでそう。
でもbashじゃなかったと思う。
前に調べたときのコードを見てみたが、
関数の頭からの行数になるのはzsh, dash, busybox ashで
zshは0から始まる。他は1から始まる。bashとkshはソースコードの行数で取れる。
バージョンは詳しく調べてないから多分古いやつは使えなかったりすると思う
なので他のシェルでエラーが起きたら、bashで実行してエラーの行番号を調べたりしているw
シェルスクリプトの世界にJavaScriptのトランスパイラ技術が導入されて
ソースコードの一行一行にLINENOを設定するコードを埋め込めば
解決できると思うんだが、流石にそれをやろうとする人はいないかなw
> これGNU Bashのことを言ってるのなら関数じゃなくて別名にすればO.K.だよ
alias?うーん、なんか別の問題がでそう。
でもbashじゃなかったと思う。
前に調べたときのコードを見てみたが、
関数の頭からの行数になるのはzsh, dash, busybox ashで
zshは0から始まる。他は1から始まる。bashとkshはソースコードの行数で取れる。
バージョンは詳しく調べてないから多分古いやつは使えなかったりすると思う
なので他のシェルでエラーが起きたら、bashで実行してエラーの行番号を調べたりしているw
581デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/10(土) 09:07:56.28ID:lBOHSSIo0 たとえばシェルアーカイブってPOSIXシェルでも可能だよね。
ああいう感じで自分が含まれるファイルを自分で走査できるんなら
行位置も取得できないかなぁと思ったんだよね……。
しつこいけどシェルスクリプト版のassert()関数が欲しい っていうか作りたいんだよねぇ
ああいう感じで自分が含まれるファイルを自分で走査できるんなら
行位置も取得できないかなぁと思ったんだよね……。
しつこいけどシェルスクリプト版のassert()関数が欲しい っていうか作りたいんだよねぇ
582デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 09:34:29.76ID:8OkJCHKT0 >>581
assertだけなら簡単かもしれないな。
assert関数の中で全てを処理するのは難しいと思う。自分のスクリプト名でさえ取得できない場合があるから
仮に取得できたとしても、何かしらのマーカーがないとどのassertかが区別できない。
(全ててのassertに区別できるマーカーを入れるっていうのなら可能だけどw)
前提としてLINENOが取得できないのはどうしようもないのでコード変換を行なう
foo() {
asesrt [ i -gt 0 ]
}
みたいなコードがあったら以下みたいに、行番号を埋め込むプログラムを作る
(ファイル名もあったほうが良いかもしれない)
foo() {
asesrt 2 [ i -gt 0 ]
}
これはPOSIXシェルスクリプトの範囲でもできる。一行づつ読んでパターンにマッチしたら変換するだけ
(複数行文字列やヒアドキュメントがあったら面倒だけど、対応してませんでもいいと思う)
あとは以上の変換処理を行って実行するラッパースクリプトを作って実行する
変換したコードはevalもしくはシェルにパイプで流し込むことで実行できる。
assertだけなら簡単かもしれないな。
assert関数の中で全てを処理するのは難しいと思う。自分のスクリプト名でさえ取得できない場合があるから
仮に取得できたとしても、何かしらのマーカーがないとどのassertかが区別できない。
(全ててのassertに区別できるマーカーを入れるっていうのなら可能だけどw)
前提としてLINENOが取得できないのはどうしようもないのでコード変換を行なう
foo() {
asesrt [ i -gt 0 ]
}
みたいなコードがあったら以下みたいに、行番号を埋め込むプログラムを作る
(ファイル名もあったほうが良いかもしれない)
foo() {
asesrt 2 [ i -gt 0 ]
}
これはPOSIXシェルスクリプトの範囲でもできる。一行づつ読んでパターンにマッチしたら変換するだけ
(複数行文字列やヒアドキュメントがあったら面倒だけど、対応してませんでもいいと思う)
あとは以上の変換処理を行って実行するラッパースクリプトを作って実行する
変換したコードはevalもしくはシェルにパイプで流し込むことで実行できる。
583デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 09:39:54.31ID:8OkJCHKT0 あー、そうか、assertか、ならデバッグ時のみしか有効じゃなくていいな。
なら、普通にスクリプトを実行したときは、
何もしないassert関数になって、
debug.sh script.sh みたいにしたら、
コード変換を行ってから実行すれば良いのか
意外と自然な感じで作れそうw
なら、普通にスクリプトを実行したときは、
何もしないassert関数になって、
debug.sh script.sh みたいにしたら、
コード変換を行ってから実行すれば良いのか
意外と自然な感じで作れそうw
584デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 09:49:06.14ID:8OkJCHKT0 assert失敗時に強制的に停止させるのはkill $$で行けるかな?
サブシェル内でも一応停止できるようだけど
サブシェル内でも一応停止できるようだけど
585デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/10(土) 16:43:37.38ID:lBOHSSIo0 色々考えてくれてマジでありがたい
確かにassert()関数はデバッグの時だけ有効になればいいから外部からスクリプトファイルを操作するという方法も
なんら不自然ではないな。
C言語のようにNDEBUG変数の有無によって処理を分けようとしてたけど
そっちのほうが柔軟な処理ができるのでいいね。
ていうかC言語と違ってシェルスクリプトのなかで安全・確実に変数を取り扱うのは厄介だから
寧ろNDEBUG変数は害悪ですらあるなw
確かにassert()関数はデバッグの時だけ有効になればいいから外部からスクリプトファイルを操作するという方法も
なんら不自然ではないな。
C言語のようにNDEBUG変数の有無によって処理を分けようとしてたけど
そっちのほうが柔軟な処理ができるのでいいね。
ていうかC言語と違ってシェルスクリプトのなかで安全・確実に変数を取り扱うのは厄介だから
寧ろNDEBUG変数は害悪ですらあるなw
586デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 19:36:31.81ID:8OkJCHKT0 >>585
何もしないassert関数と書いたが、コメントの形でassertを入れるのはどうだろう?
これなら関数呼び出しすらないので、(わずかな)パフォーマンス低下も発生しないし
仮にスクリプト内でassert関数を使っていても問題ない
assert有効時は、長い名前に変換すれば良い
何もしないassert関数と書いたが、コメントの形でassertを入れるのはどうだろう?
これなら関数呼び出しすらないので、(わずかな)パフォーマンス低下も発生しないし
仮にスクリプト内でassert関数を使っていても問題ない
assert有効時は、長い名前に変換すれば良い
587デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 19:38:01.66ID:8OkJCHKT0 あと、デバッグモード、assert関数有効時だけど、終了ステータスを変えてしまうことに注意な
foo() {
false
# assert [ なんちゃら ]
echo $?
}
という場合、本来はechoで1と表示されるけど、単純にこのように変換してしまうと、
assert有効時に$?がassertの結果になってしまう
だから変換後はこんな感じかな? ||:を使うことでset -e状態でも落ちなくできる
foo() {
false
assertooooo 3 [ なんちゃら ] ||:
echo $?
}
assertooooo() {
EXIT_STATUS_BACKUP=$?
LINE_NUMBER=$1
shift
if "$@"; then
return $EXIT_STATUS_BACKUP
else
echo "エラー $LINE_NUMBER" >&2
exit 1
fi
}
foo() {
false
# assert [ なんちゃら ]
echo $?
}
という場合、本来はechoで1と表示されるけど、単純にこのように変換してしまうと、
assert有効時に$?がassertの結果になってしまう
だから変換後はこんな感じかな? ||:を使うことでset -e状態でも落ちなくできる
foo() {
false
assertooooo 3 [ なんちゃら ] ||:
echo $?
}
assertooooo() {
EXIT_STATUS_BACKUP=$?
LINE_NUMBER=$1
shift
if "$@"; then
return $EXIT_STATUS_BACKUP
else
echo "エラー $LINE_NUMBER" >&2
exit 1
fi
}
588デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 19:42:53.17ID:8OkJCHKT0 > 仮にスクリプト内でassert関数を使っていても問題ない
ちょっとわかりづらかったな
スクリプトでassertという名前の関数を別の用途で使っていた場合ってことね
ちょっとわかりづらかったな
スクリプトでassertという名前の関数を別の用途で使っていた場合ってことね
589デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 19:44:37.42ID:8OkJCHKT0 うぬ、ここはkillにするんだった
else
echo "エラー $LINE_NUMBER" >&2
kill $$
fi
else
echo "エラー $LINE_NUMBER" >&2
kill $$
fi
590デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 19:49:50.91ID:8OkJCHKT0 (ま、あとは . ドットコマンド で読み込んだ外部スクリプトはどうするか問題があるんだがなw)
591デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 20:03:55.71ID:8OkJCHKT0 あー、バカだ
assertooooo 3 [ なんちゃら ] ||:
じゃなくて
assertooooo 3 [ なんちゃら ] &&:
だった
上はset -eでも落ちなくし、かつ終了ステータスを問答無用で0にする方法(エラーの時 : を実行する)
下がset -eでも落ちなくし、かつ終了ステータスはそのまま保つ方法
assertooooo 3 [ なんちゃら ] ||:
じゃなくて
assertooooo 3 [ なんちゃら ] &&:
だった
上はset -eでも落ちなくし、かつ終了ステータスを問答無用で0にする方法(エラーの時 : を実行する)
下がset -eでも落ちなくし、かつ終了ステータスはそのまま保つ方法
592デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/10(土) 20:17:00.01ID:lBOHSSIo0 >>590
例えば
ファイルの名前がwhizprog.shだったとして
test "$( ps -p $$ -o 'comm=')" = 'whizprog.sh'
↑これが失敗・失敗しないで判定できるんじゃね?
尤もこれはシバン#!/bin/shというPOSIX未定義の構文を使ったばあいで
シバンを書いてないと使えない手だけど。
例えば
ファイルの名前がwhizprog.shだったとして
test "$( ps -p $$ -o 'comm=')" = 'whizprog.sh'
↑これが失敗・失敗しないで判定できるんじゃね?
尤もこれはシバン#!/bin/shというPOSIX未定義の構文を使ったばあいで
シバンを書いてないと使えない手だけど。
593デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 20:22:22.65ID:8OkJCHKT0 >>592
ん? assert実行するためのソースコード書き換えの話だよ
debug.sh script.sh で読み込んだ、script.shの書き換えは簡単だけど、
その script.sh から . コマンドで読み込まれるコードまでは書き換えられない
だから . コマンドを検出して再帰的に・・・面倒なんだよなw
余談だが、
> test "$( ps -p $$ -o 'comm=')" = 'whizprog.sh'
これはPOSIX準拠なのだろうが、busyboxではpsはwしか使えないw
ps w
ん? assert実行するためのソースコード書き換えの話だよ
debug.sh script.sh で読み込んだ、script.shの書き換えは簡単だけど、
その script.sh から . コマンドで読み込まれるコードまでは書き換えられない
だから . コマンドを検出して再帰的に・・・面倒なんだよなw
余談だが、
> test "$( ps -p $$ -o 'comm=')" = 'whizprog.sh'
これはPOSIX準拠なのだろうが、busyboxではpsはwしか使えないw
ps w
594デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/10(土) 20:50:01.93ID:lBOHSSIo0 >>593
ああなるほど そんなことまでは考えてなかった。
正直,あなたに教えてもらった方法で大満足です。ありがとう。(欲を言えば行番号を自分で……しつこいねw)
とりあえずこんな感じに落ち着きました↓
#!/bin/sh
assert()
{
exec >&2
eval "test ${2}" || {
printf '%s: %d: %s\n' "${0}" ${1} "${3-"Assertion ${2} failed."}"
exit 1
}
}
main()
{
set -eu
umask 0022
export PATH="$( command -p getconf PATH ):${PATH}"
assert 18 '"a" = "b"' && :
exit $?
}
main "$@"
ああなるほど そんなことまでは考えてなかった。
正直,あなたに教えてもらった方法で大満足です。ありがとう。(欲を言えば行番号を自分で……しつこいねw)
とりあえずこんな感じに落ち着きました↓
#!/bin/sh
assert()
{
exec >&2
eval "test ${2}" || {
printf '%s: %d: %s\n' "${0}" ${1} "${3-"Assertion ${2} failed."}"
exit 1
}
}
main()
{
set -eu
umask 0022
export PATH="$( command -p getconf PATH ):${PATH}"
assert 18 '"a" = "b"' && :
exit $?
}
main "$@"
595デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 21:06:21.14ID:8OkJCHKT0 update.sh script.sh でassert行の行番号を更新して上書き保存するってのもありかもw
それなら.コマンドの先も対応できる。いちいち更新しないといけないのが面倒だけど
それなら.コマンドの先も対応できる。いちいち更新しないといけないのが面倒だけど
596デフォルトの名無しさん (ワッチョイ 9164-30bX)
2018/11/10(土) 21:44:08.29ID:lBOHSSIo0 更新するコマンドを別に作るんじゃなくてデバッグ時に更新も行うようにすれば(結局 手間は同じだけど)
だってデバッグする時ってその直前に必ず行番号やらを更新したいでしょう。
だってデバッグする時ってその直前に必ず行番号やらを更新したいでしょう。
597デフォルトの名無しさん (アウアウカー Sa9d-f/7Y)
2018/11/10(土) 21:51:38.21ID:wKJLu9V5a だんだんそもそもやりたかったことから離れてる雰囲気だけは感じた
598デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/10(土) 22:33:00.25ID:8OkJCHKT0599デフォルトの名無しさん (ワッチョイ 93b3-Mdza)
2018/11/10(土) 23:15:08.44ID:hLxIIZfE0 もうシェル自体に手を入れてデバッグモードみたいなのを実装した方がいいんじゃね?
600デフォルトの名無しさん (ワッチョイ b903-wpdm)
2018/11/10(土) 23:18:28.98ID:7gTt1pZ+0 もうシェルでなにしたいんやおまえ
601デフォルトの名無しさん (アウアウカー Sa9d-f/7Y)
2018/11/10(土) 23:41:45.94ID:wKJLu9V5a シェルブリットバーストを撃ちたい
602デフォルトの名無しさん (ワッチョイ 9164-TRt+)
2018/11/10(土) 23:58:52.52ID:lBOHSSIo0 >>599
一応POSIXでsh -xは定められてる
一応POSIXでsh -xは定められてる
603デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/11(日) 00:03:09.99ID:Tyd11AGx0 sh -xまじ使えねぇ
なぜ行番号を出すようにしなかったのか
なぜ行番号を出すようにしなかったのか
604デフォルトの名無しさん (ワッチョイ 9398-Nrm4)
2018/11/11(日) 00:16:53.30ID:Tyd11AGx0 >>600
assertじゃないの?
assertじゃないの?
605デフォルトの名無しさん (ワッチョイ 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
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 高市内閣、支持率横ばい75% (日経・テレ東 世論調査) ★3 [少考さん★]
- 【窪田順生氏】「高市政権人気の裏には多数の“弱者感を抱えた男”の存在がある」弱者感を抱えた男は人知れずマイルド右翼に… [おっさん友の会★]
- 【調査】クレジットカード、1人何枚持つのが「平均的」?★3 [ひぃぃ★]
- 【テレビ】池上彰氏 報道の自由度が高い国の特徴「どんどん政府を批判する。政治家は受け入れる」 一方独裁国家は… [冬月記者★]
- 【国防】防空ミサイル(中SAM) 輸出検討へ 政府、フィリピンと非公式協議 [シャチ★]
- 「ヘイトスピーチをやめろ」 各地の「移民反対デモ」に抗議活動 [蚤の市★]
- 現役JKのお茶会スレ( ¨̮ )︎︎𖠚ᐝ174
- 悲報】福山雅治さん逮捕
- (*´ω`*)( ・᷄ὢ・᷅ )壁際だ
- 高市がマクロンを無視してる動画がなぜか外人によって「マクロンざまぁ」的な論調で大拡散中、マクロンはそんなに嫌われてるのかよw [469534301]
- 【画像】彼女「目玉焼きハンバーグを作ったよ♥」ケンモメンならどうする? [242521385]
- フィフィ「「歌唱強制中断」騒動、この時期に中国でライブ公演しようとするアーティストの方にも問題があるのでは?」 [377482965]
