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

■ このスレッドは過去ログ倉庫に格納されています
2019/08/10(土) 23:17:50.64ID:L+B8OP2P
シェルスクリプトに関する総合スレッドです。

全般
・荒しは無視しましょう。
・丁寧な姿勢を心掛けましょう。
・ネチケット(死語)を意識しましょう。
・「○○(他の言語)でいいやん」は禁止。他のスレに行ってください。

シェルスクリプト総合 その30
https://mevius.5ch.net/test/read.cgi/tech/1561989867/
2019/09/15(日) 17:40:54.01ID:h836vV7+
https://sechiro.hatenablog.com/entry/2013/08/15/bash%E3%81%AE%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E7%BD%AE%E6%8F%9B%E6%A9%9F%E8%83%BD%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%81%A6%E3%80%81%E3%82%B7%E3%82%A7%E3%83%AB%E4%BD%9C%E6%A5%AD%E3%82%84%E3%82%B9
2019/09/15(日) 18:39:06.79ID:QquDNTIJ
https://sechiro.%68atenablog.com/entry/2013/08/15/bash%E3%81%AE%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E7%BD%AE%E6%8F%9B%E6%A9%9F%E8%83%BD%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%81%A6%E3%80%81%E3%82%B7%E3%82%A7%E3%83%AB%E4%BD%9C%E6%A5%AD%E3%82%84%E3%82%B9
628デフォルトの名無しさん
垢版 |
2019/09/15(日) 20:14:01.28ID:riyG3w3b
>>619
スマホのChromeなんだけどね。おかしいのかね?よくわからんが。
629デフォルトの名無しさん
垢版 |
2019/09/15(日) 20:17:20.74ID:riyG3w3b
>>621
あ、そういうことか。
たしかに無事開いてしまったら何か違う世界を見てしまいそうで怖いアドレスだなw
2019/09/16(月) 19:53:43.50ID:vTAkg/qq
16進数(最大二桁 0xFF)から8進数に変換したいんですが
bcを使う以外にsedなどを使った方法とかありますかね…?
$ printf 'obase=8;ibase=16;%s\n' 'FA' | bc
もしあれば,bcは16進数のアルファベットが大文字じゃないといけないし,
POSIX標準とはいえUbuntuとかには既定で導入されてないしで,
あまり使いたいくないんです(わがままですいません)
2019/09/16(月) 20:12:04.01ID:Zn9wpmWA
printf '%o\n' 0xfa
2019/09/16(月) 21:17:46.43ID:U9mfWlHU
8進数にパーミッション以外の使いみちなんてあったのか…
2019/09/16(月) 23:39:17.58ID:LCUbae2V
>>630
hex=fa
oct=$(( ($hex >> 6) * 100 + ($hex >> 3 & 0x7) * 10 + ($hex & 0x7) ))
# oct=$((0x$hex >> 6))$((0x$hex >> 3 & 0x7))$((0x$hex & 0x7)) 3桁固定版
echo "$oct"

出力が必須でない場合(変数に入れて処理する場合)は
oct=$(printf '%o\n' 0xfa) よりも速いはず
2019/09/16(月) 23:43:56.37ID:LCUbae2V
他にも case を使って書けるはず
最大0xFFなら

case $value in
01) 〜
02) 〜

[fF][eE])
[fF][fF])
esac

とかねw

たかだか256+α行。頑張ればFF の一桁ずつ処理すれば行は減らせるだろう。
2019/09/16(月) 23:46:42.80ID:LCUbae2V
>>633訂正

× oct=$(( ($hex >> 6) * 100 + ($hex >> 3 & 0x7) * 10 + ($hex & 0x7) ))
○ oct=$(( (0x$hex >> 6) * 100 + (0x$hex >> 3 & 0x7) * 10 + (0x$hex & 0x7) ))
2019/09/17(火) 00:06:22.06ID:IA1rgq5F
>>632
posixの範囲ではprintfで16進数から文字に変換することが出来ない

printf '\101' # => A
printf '\x41' # bashは変換できるが、dashでは変換できない

バイナリデータの処理など、文字コードを使って処理する必要がある場合は
8進数を使うほうが良い
2019/09/17(火) 00:09:45.15ID:IA1rgq5F
8進数よりも16進数の方が使い勝手が良いのにパーミッションが8進数なのは、
当時はまだ16進数が発明されてなかったからだったりするのかな?
シェルスクリプトもそうだけど、なんか古い時代は8進数しかなかった感じがする
それとも単なるビット数を節約しただけなんだろうか?
2019/09/17(火) 00:18:14.43ID:kEXgFQM4
7ビット機だったような
2019/09/17(火) 02:12:04.50ID:sr4VPY0J
rwxで3ビットしか使ってない必要ないと思ったからだろう
2019/09/17(火) 04:55:24.40ID:KdPNzCQK
パーミッションの話じゃなくて
2019/09/17(火) 09:45:35.22ID:3tDP3W6T
>>634
ありがとうございます!
2019/09/17(火) 12:39:27.59ID:e1bW+EWq
>>637
>当時はまだ16進数が発明されてなかったからだったりするのかな?
どこでなにが「発明」を指して居るのかわからんが、コンピュータ業界コンピュータサイエンス(?)としては当時でも普通に16進数があっただろう。スイッチをパチパチしてマシン語を打ち込む当時のコンピュータでは打ち込むプログラムは16進数で書いてたようだから
Unix version 1 は 18ビットマシンの PDP-7 でから始まり、すぐに PDP-11 に移行したがその名残だろう、K&R C の文字リテラルでは8進数表現しかできないのとかは、また、K&R C の影響じゃね
PDP-7 は 18ビット= 3 3 3 3 3 3 で表した方書いた方がきりがいいからそれが普通のような感じだったんじゃね、今でもパーミッションは3ビットに収まっているので3ビット区切りで表した方が書いた方がわかりやすいのと同じように
2019/09/17(火) 12:48:38.39ID:N6BvjGdd
昔はなぜか 12bit 15bit 18bit 24bit 36bit あたりのマシンが多い
2019/09/17(火) 13:26:02.16ID:e1bW+EWq
そうなの。見物したスイッチをパチパチしてマシン語を打ち込む当時のコンピュータは16bitだったから、PDP-7(というかPDP-11の前までのDEC)が異端かと思ったw
2019/09/20(金) 09:32:25.18ID:pw3H64dJ
16進数から8進数への変換って↓
$ hex=fa; printf '%o' $((0x$hex))
↑こういうのだとPOSIX違反?
2019/09/20(金) 13:37:02.90ID:fQRmEVoK
POSIXは知らんが、 古いzsh? は $((0x$hex)) が使えなくて $((16#$hex)) だった気がする
もしくは $((011)) が zshでは8進数にならなくて $((8#11)) と書かないといけない
という問題だったかもしれない。まあ忘れたw
2019/09/20(金) 15:46:33.91ID:pw3H64dJ
ふむ。ということは今であればほぼ問題ないという訳か。
thx
2019/09/20(金) 18:40:57.99ID:YblgUZDU
>>644
基本的にメインフレームってカテゴリのコンピュータはCPUも自社設計だったので
8bit単位じゃなく自分たちの使いやすいbit数だった
ザイログとかモトローラのCPUを使っていると基本的に8bitの整数倍になる
2019/09/22(日) 22:42:51.90ID:UP8ZY9Jm
symlnkのフォルダからファイルをmvすると実体パスの方で移動するけどmvの仕様?
2019/09/22(日) 22:58:25.61ID:wuCdbk0L
移動なら実体を移動しなきゃ移動しないだろう、ファイルシステム的に
2019/09/22(日) 23:05:40.23ID:QKufl6gy
例えば/a/b/cがあって、/x/yが/a/bを指すとする。
cd /x/y; mv c ..したときにcが/x/cじゃなくて/a/cになるという話なら仕様。
実際はcd /x/yの時点でカーネル的には既に/a/bに移っている。
pwdして/x/yと表示されたり、プロンプトに/x/yと出たりすることがあるのは、シェルがそう見せているだけ。
外部コマンドを呼んだ時点で/x/yにいるという情報は伝わらない。
2019/09/22(日) 23:22:54.08ID:dHMqf7rP
シェルによっては今いるディレクトリをシンボリックリンクのままPWD環境変数に出力するから、外部コマンドでも>>651の場合に/a/bではなく/x/yにいると分かることもある
だからmvでもやろうと思えば環境変数によって動作をかえて/x/cに移すこともー応可能ではある
ただ普通はそういう危なっかしい動きはしない
2019/09/23(月) 00:58:42.07ID:XnqhgXWR
なるほど
~/dir/foo.txtがあって、dirのリンクを~/Desktop/dir_linkに作ったんだ
んでdir_linkからmv foo.txt ../したらDesktopになくてあれってね
シンボリックリンクはあくまで別名だって念頭に置かないといつかやらかしそうだなぁ
2019/09/23(月) 13:44:18.78ID:uT43KuRv
シンボリックリンク自体はカーネルっていうかファイルシステムの機能であって
シェルの機能じゃないよね?

シンボリックリンクされたディレクトリへの移動やその表示が、シェルの機能?
2019/09/23(月) 14:55:36.41ID:16gV8N0U
シンボリックリンクはただのファイルで、APIが機能を提供してるだけだろう
ハードリンクはファイルシステムの機能だろうが
2019/09/23(月) 15:20:14.51ID:0wgm+uqt
シンボリックリンクはPOSIXで決まっているが、
シェルスクリプトとは関係ない。
シェルとも関係ない。すれ違いだ。
シェルスクリプトの話をしろ。
2019/09/23(月) 15:43:16.78ID:PpvL3bdr
シンボリックリンクもハードリンクもファイルシステムの機能だ
2019/09/23(月) 15:44:56.02ID:mZE+d06B
ドヤァ
2019/09/23(月) 16:01:07.98ID:16gV8N0U
>>657
どこまでをファイルシステムかと言うのかだが、論理矛盾とかリンク切れとかあってもなんも関係ないのだから低レベル=どのファイルシステムでフォーマットする?というファイルシステムのファイルシステムではないな
そのレベルではファイルとフラグを提供しているにすぎない

APIも含めたOSがアプリケーションに対しての提供するファイルシステムといえばファイルシステムだろうが
2019/09/23(月) 16:41:43.41ID:aoth6Tve
まぁ、いずれにしても、ここではスレ違い
2019/09/23(月) 16:58:42.91ID:COQ8/G13
シンボリックリンクやハードリンクはOSの機能
ファイルシステムはそれを実装するだけ
(FATのように実装してないものもある)
2019/09/23(月) 17:01:20.42ID:PpvL3bdr
アホばっかw
2019/09/23(月) 17:09:58.15ID:fWeAQpZu
自戒か
2019/09/23(月) 17:22:55.59ID:qNyZUwSM
ファイルシステムはOSの提供する1つの機能だろ
2019/09/23(月) 20:09:09.12ID:uT43KuRv
いつからカーネルがOSに掏り替わった?
2019/09/25(水) 16:36:07.25ID:vuS5tsH7
カーネルってファイルシステム含まないでしょうが
2019/09/25(水) 17:26:48.60ID:Fy/ppuPa
子供がまだ食ってる途中でしょうが
668デフォルトの名無しさん
垢版 |
2019/09/29(日) 15:56:27.36ID:kt1IDkk5
誠意って何かね
669デフォルトの名無しさん
垢版 |
2019/09/29(日) 17:07:22.81ID:G1Omq4Sq
2019/09/29(日) 19:09:52.55ID:VaR9nylT
女だったらアレかもしれんが
2019/09/29(日) 19:22:34.45ID:CY5JaLwa
俺が定期的にお題を出してやらないとすぐクソスレ化するなw
2019/09/29(日) 19:31:49.84ID:cn7qdGIP
Oh, I like Japan.
Japanese are crazy. Ha ha ha.
Japanese are pigs, pigs, you know.
Moneys and they have small cocks you know short legs yellow monkeys.
Do you understand?
2019/09/29(日) 19:34:18.39ID:RIFVILY+
POSIXの話するから荒れて盛り上がるから誰かしてよ
2019/09/29(日) 19:34:36.19ID:RIFVILY+
POSIXの話すると荒れて盛り上がるから誰かしてよ
2019/09/29(日) 20:34:15.29ID:1ct4yMlj
POSIX準拠で固定小数点ライブラリほしいな
小数使うことは稀だけど、たまに無いとめんどくさい
exprは外部コマンドで遅いので却下w
2019/09/29(日) 20:53:22.53ID:UgGWrkoZ
bashって便利だけど計算部分だけマジでダサいな

1+1が
$((1+1))ってなんなんだよ
2019/09/29(日) 21:19:57.63ID:1ct4yMlj
どの言語にも言えることだけど、
ダサい部分ってのは互換性のためだよ

シェルスクリプトは外部コマンドを関数として呼び出せて、
そして外部コマンドに使える文字は、ファイルに使える文字と同じ
だから例えば@とか%とかいう文字でさえ、コマンド名として使える

だから、安易に記号を追加するわけにもいかないし予約語も増やせない。
$に関してはシェルスクリプト当初から特殊記号だったから
新たに特殊記号や予約語を増やすのではなく$を拡張するという方法を採用したのだろう

互換性は一番大事だからね
2019/09/29(日) 21:21:56.71ID:1ct4yMlj
補足

例えば「1 + 1」は、"1"コマンドを、+と1という引数で呼び出すという意味になるし
「1+1」だと"1+1"コマンドになる。

選択肢が限られるんだよね
2019/09/30(月) 06:57:25.74ID:Ceph+2oU
$ awk 'BEGIN {print 0.1+0.2}'
0.3
bcより使いやすい悲しみ
2019/09/30(月) 13:47:50.63ID:bgqbOy9v
POSIXの仕様書,
算術展開での(浮動)小数点演算は今度の2020年度改訂で一部解禁されるらしい。
ちなみに時を同じくして$'\n'←みたいな書式も解禁。
やったぜ。
2019/09/30(月) 14:14:05.05ID:gJLA2fQe
やったぜ。
682デフォルトの名無しさん
垢版 |
2019/09/30(月) 14:57:01.11ID:seE3nGDx
石器時代かよワロタw
2019/09/30(月) 14:59:09.67ID:1VQTT5dv
生理がこないんですけど
どうしたらいいですか?
2019/09/30(月) 15:14:42.58ID:g4qimp0d
俺も生理来たことないわー
2019/09/30(月) 15:24:33.48ID:g4qimp0d
>>680
どこ情報ですか?
2019/09/30(月) 17:46:55.62ID:zGRcNdYK
もしもし、先生!もしもし!
だけどもねー、実はあのー、子供つくらないようにしてるんですよね、わたくしも本当に辛くてですね、子供には遺伝しないでしょうか?
2019/09/30(月) 19:45:29.40ID:bgqbOy9v
>>685
http://austingroupbugs.net/view.php?id=249
こことか。
2019/09/30(月) 20:35:29.76ID:sHSicWZI
>>687
いや、小数の話
689デフォルトの名無しさん
垢版 |
2019/09/30(月) 21:58:43.29ID:M1BD3UNk
しょうっすか…
2019/09/30(月) 23:03:44.06ID:qRuhgEzP
無理にシェルスクリプトだけで小数対応しなくても、
perl -e "print 0.2*0.3"
とか、いろいろやりようはあるからあまり必要性を感じない。
2019/09/30(月) 23:20:20.33ID:nI7iDoAi
>>690
大量に計算をするとプロセス呼び出しになるから遅いんだよ

$ time ksh -c 'for i in $(seq 1000); do n=$(echo "0.2*0.3" | bc -l); done'
real 0m1.921s
user 0m1.762s
sys 0m0.715s

$ time ksh -c 'for i in $(seq 1000); do n=$((0.2*0.3)); done'
real 0m0.009s
user 0m0.009s
sys 0m0.000s

たったの1000回でここまで差が出るからね
2019/09/30(月) 23:28:35.91ID:qRuhgEzP
意図と違うと思うが、
time perl -e '$j=0; for($i=0;$i<1000;$i+=1) { $j+=0.2*0.3; }; print $j'
とか、別にシェルスクリプトだけに頼らんでもなんとかなってしまうというか・・・・
2019/09/30(月) 23:29:54.18ID:nI7iDoAi
だから出来るできないの話はして無くて
遅いって話をしてる
2019/09/30(月) 23:35:15.29ID:1VQTT5dv
>>692
これで事足りるな
2019/09/30(月) 23:58:52.54ID:nI7iDoAi
perlは入ってない環境も有るのでその点でも駄目だしね
2019/10/01(火) 00:02:33.23ID:cNB/gbgI
>>679
これで事足りるな
2019/10/01(火) 00:27:03.86ID:rxcb8vGn
必須すぎやろw
2019/10/01(火) 01:47:40.69ID:SPlRKvH8
なになに縛りが好きなマゾなんだろうw
2019/10/01(火) 02:00:19.69ID:rxcb8vGn
そんな事する必要がないなら縛りって言ってもいいけど、
perlが入ってない環境は実際に存在するからね
2019/10/01(火) 02:09:56.58ID:ESup7bfu
awkも使えない環境で何やるんだよw
2019/10/01(火) 02:09:58.85ID:PTA8MEY/
>>679
2019/10/01(火) 02:36:49.10ID:eGCx9XC9
>>700
awkはbusyboxに入ってるよw
2019/10/01(火) 09:01:32.62ID:O2y9FdCY
「可搬性が高い」を「POSIX縛り」と取り違えてるおバカさんがいますね…
2019/10/01(火) 09:11:30.09ID:ZA6pNaC0
POSIXで縛るだけではPOSIX未満のbusyboxで動かなかったりするからね
可搬性を高くするにはPOSIXで規定されたコマンドであっても
なるべく使わないほうが良い
2019/10/01(火) 10:51:02.41ID:CGhZJwfl
どういうことなの…
2019/10/01(火) 11:09:51.43ID:ZA6pNaC0
ここはシェルスクリプトのスレ
つまり可搬性とはシェルスクリプトの話をしてる。

シェルスクリプトではよく外部コマンドを呼び出す
しかし外部コマンドはOSによって違う。

特に基本的なコマンドは、各OSでバラバラに作っていたり
独自の修正を入れており複数の実装があり微妙に動きが異なっている。
例えば、LinuxのsedとMacのsedでは使える命令が違う。

POSIX準拠のコマンド(もちろんオプションなども含む)で規定されてるものだけを
使っていれば可搬性はそれなりにあるが、それでも完璧じゃない。
例えば組み込みで使われるbusyboxはPOSIX準拠コマンドのサブセットが実装されてる。

だから本気で可搬性を高くしようと思えばPOSIX縛りでも不十分。
POSIX準拠のコマンドが信じれない。という前提にたてば
思い切って外部コマンドすら呼び出さない、完全にシェルスクリプトだけで
実装するのがもっとも可搬性が高い。

もちろん限界は有るので実際には出来る限りシェルスクリプトで作って、
外部コマンドは必要最小限、必要に応じて互換性を吸収するようにラッパー関数を作る。
ということになる。
2019/10/01(火) 15:50:14.87ID:P1455Lxu
可搬性に異常に拘っているのは一人か二人しかいないけどな
可搬性に拘ってないというレスにも可搬性を押し付ける
708デフォルトの名無しさん
垢版 |
2019/10/01(火) 16:28:55.36ID:9fvqkmcJ
認めろよ。
シェルスクリプトに可搬性などない。
どこでも動くシェルスクリプトなど幻想。
2019/10/01(火) 16:40:08.47ID:8eIOCDAd
hoge () {
echo "Hello"
}

for i in $(seq 1000); do
hoge
a=$(hoge)
done

myfunc と a=$(myfunc) の実行時間の差はなんなん?標準出力を横取りするためだけにしてはコストが高いかな
簡単に思いつくのは横取りするためパイプでで別プロセスにしなきゃとかかな?
2019/10/01(火) 16:46:56.18ID:O2y9FdCY
それBashでやってない?
試しにKshでやってみて。(俺環かもしれんから,速度比較は晒さない)
711デフォルトの名無しさん
垢版 |
2019/10/01(火) 16:52:40.16ID:/6RuW8/Q
perlが入ってない環境ってそれは入れる必要ないんだろ
一から構築していくならそれでいいけど
2019/10/01(火) 16:54:32.38ID:8eIOCDAd
なるほど。ksh(だけが?)がなんか賢いかな。zsh他も差がある
2019/10/01(火) 17:07:00.59ID:cNB/gbgI
perlが無い環境があるからどうのこうの言うけど
kshが無い環境があるからは言わないんだなw
2019/10/01(火) 17:10:13.56ID:8eIOCDAd
違う人じゃね?同一人物だったらアレだけどw
2019/10/01(火) 18:59:48.82ID:8eIOCDAd
>>712
zsh他も差があるは、>>709で体感できる差があるが正しいか
kshでも差があるね。ループ数増やせば体感できるほどの差となるね
2019/10/01(火) 19:16:54.12ID:fust4gpU
>>709
forkだよ。$( ) の部分がサブシェルになってて
多くのシェルではサブシェル = 別プロセス生成で実装されてる。
そのおかげでサブシェルの中でcdを実行したり変数を使ったりしても
呼び出し元は汚染されたりしない

kshはサブシェルの実装が最適化されていて
全てではないが、サブシェルの部分を同一プロセスで実行する。
独自で状態の保存と復帰を実装してるのだろう。

https://codeday.me/jp/qa/20190810/1425430.html

kshは速いと言っちゃ速いんだが、その(複雑な?)仕組みのせいで
バグのもとになってたりする。ということを書いてあるページが
有ったんだがどこか忘れた。
2019/10/01(火) 19:25:21.59ID:fust4gpU
遅い原因の本質は標準出力のキャプチャじゃないから
この二つでも違いがでる

hoge () {
 :
}

for i in $(seq 1000); do
 hoge
 (hoge)
done

>>715
> kshでも差があるね。ループ数増やせば体感できるほどの差となるね
そうなんだよね。サブシェルのコストは以外と大きい。
だから変数に入れて使うことが目的とした関数は以下のように
グローバル変数を使って返したほうがずっと速いわけさ

hoge () {
RET=Hello
}

for i in $(seq 1000); do
hoge
a=$RET
done
2019/10/01(火) 19:26:55.18ID:8eIOCDAd
>>716
内部関数なのにってとこがね&普通の他の言語とはやはり違うな(まあ当然だが)という(内部汚染とかこれの本題ではないっすよ)

zshはkshを習ってだけど、ちょこちょこ習えてないなあ。kshの否定面のレスだけど、kshは人に優しいとこもあるとも思うw
a=0
ls | while read line; do
[ "$line" = 'hoge' ] && a=1
done
[ a -eq 1 ] && ...
っていう見た目他の言語的では当たり前のがちゃんと動くというwまあ、異端だけど

とりあえず、どうしようもないそういうものということでいいのね。どうも
2019/10/01(火) 19:30:13.87ID:8eIOCDAd
>>717
せっかくですが、ちょい本題とは違うかな。そりゃ () は...
なんで内部関数なのにサブシェルになんのかねん、他の言語的感覚ではという
まあ、内部関数だろうと、() と同じで $() もサブシェルになるということをおっしゃっりたいのでしょうけど
どうも
2019/10/01(火) 19:37:54.80ID:fust4gpU
>>719
> なんで内部関数なのにサブシェルになんのかねん、

考え方が違う。

コマンド置換$( ) は「サブシェルを使用して実行する」という"仕様"なんだよ
なんでサブシェルになるのか?ではなく仕様でサブシェルにすると決まってる。

ただし別プロセスにするとは決まっていない。だから子プロセスとかいう既存の
名前ではなく、新たにサブシェルという用語を作った。

サブシェルの仕様としては、「サブシェル内で行った変数などの変更は呼び出し元には伝わらない。」
などがあるが、それを実現してるなら別の別プロセスでなくてもよい。
だけど別プロセスにするほうが実装が簡単だから多くのシェルではサブシェル=別プロセスになってる。
2019/10/01(火) 19:41:25.43ID:8eIOCDAd
>>720
その続きなどを読んでよ。言われていることはすでに書いてあるんですけど

どうしようもないという結論が得られたのでw、
結局、こんなことにもそれなりの差があるんだから「常時それも無条件で」実行時間の差があるなんて気にするなんて無意味だなと
なにかそれが問題になったときに気にする対応すればいいだけだなという。のをそもそも言いたかったw
2019/10/01(火) 19:44:28.64ID:fust4gpU
>>718
> 内部関数なのにってとこがね
他の言語の場合、(基本的に)関数内の変数の変更は呼び出し元に反映されない。
つまりローカル変数になってるだろ?

それと同じなんだよ。POSIXの範囲ではlocalもtypesetもないから
シェルスクリプトにはローカル変数がない

ように思えるが、実はサブシェルを使うからローカル変数は必要ない。とも言える。
ローカル変数を実現するためのサブシェルと言える。
サブシェルの仕様としてローカル変数は必須の機能だが、別プロセスにするのは必須ではない。

サブシェル(別プロセス)と捉えるから仰々しくなってるが、
変数のローカル化と考えれば、内部関数内の変数をローカル化するってだけだから
「内部関数なのに」とは思わないだろ?
2019/10/01(火) 19:51:56.19ID:8eIOCDAd
>>722
なにを教えてくれてるのか教えたいのかわからないです
内部変数?内部変数環境のことは言ってないです。他の言語でもの(内部)関数を呼ぶその返り値を使うって話なんですけど
内部変数云々ならhogeもサブシェルにしなくちゃじゃないですか?内部関数という言葉が悪かったならすまんすですけど
2019/10/01(火) 19:52:05.05ID:fust4gpU
>>718
そのコードに関しては

ls | {
 a=0
 while read line; do
  [ "$line" = 'hoge' ] && a=1
 done
 [ a -eq 1 ] && ...
}

こう書けばいいって事がわかってから悩むことはなくなったなw

上記をさらに発展して、関数化すれば以下のようになる。

hoge() {
 a=0
 while read line; do
  [ "$line" = 'hoge' ] && a=1
 done
 [ a -eq 1 ] && ...
}

ls | hoge

そうするとa変数は実質ローカル変数として扱ってるんだから
スコープ的にはこっちのほうが適切だと気づくだろう
2019/10/01(火) 19:53:21.70ID:fust4gpU
>>723
> 内部変数云々ならhogeもサブシェルにしなくちゃじゃないですか?

使い分けるんだよ。

ローカル変数化したいならサブシェルを使う。
そうでないならサブシェルを使わないって。
2019/10/01(火) 19:56:56.36ID:8eIOCDAd
>>725
なんか教えたがりのようですけど、ちょっと無理があるかなと
あくまでも「他の言語的感覚では」が前提、それとは違うというのの確認でしかないんですけど
使い分けるとかそもそも内部変数の話はしてないんですよ
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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