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

■ このスレッドは過去ログ倉庫に格納されています
2019/07/01(月) 23:04:27.02ID:/rKj5XUf
シェルスクリプトに関する総合スレッドです。

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

前スレ:
シェルスクリプト総合 その29
https://mevius.5ch.net/test/read.cgi/tech/1537540487/
2019/07/11(木) 12:28:30.89ID:pY8YHtW/
PowerShellなら動きます(白目)
183デフォルトの名無しさん
垢版 |
2019/07/11(木) 12:29:45.46ID:W9yQmyPF
Windowsに最初から入ってるのは vbs とか js とか、あとバッチファイルとかパワーシェルかな。よく知らんけど。
HTAってのもあったっけ。
2019/07/11(木) 12:34:10.09ID:CgGarxi7
powershell考えた奴は頭おかしいんじゃね
なんでいちいちコマンドとかあんな長いんだよ
無能にもほどがある
185デフォルトの名無しさん
垢版 |
2019/07/11(木) 12:50:53.46ID:At9Pc1xn
adduserとuseraddどっちがどっちかたまに使うとき毎回調べるみたいなクソ下らないことしたくないからじゃない?
2019/07/11(木) 12:57:39.35ID:oBmxbhd/
それをいうなら、Windows、Macで、どの言語でも構わないが
ユーザーを追加する方法を調べないでわかるっていうの?
2019/07/11(木) 12:58:48.61ID:l57S3jiM
POSIXってUNIX系OSの規格なのに
なんでWindowsの話になってんだよw
2019/07/11(木) 13:00:17.64ID:A1tpN7ls
>>181
インストールしないで動くのか?
2019/07/11(木) 13:01:52.25ID:PMWvbDa1
>>188
>Javaなら一度書けばどこでも動くのに
とあったから
Windows は標準でいれてるのかなと
190デフォルトの名無しさん
垢版 |
2019/07/11(木) 13:23:31.79ID:W9yQmyPF
>>189
入れたかったんだけどね・・・
2019/07/11(木) 14:01:00.83ID:l57S3jiM
Javaはオワコン
2019/07/11(木) 14:06:11.17ID:oQkLsXMb
javaのコンセプト
write ones, test everywhere
2019/07/11(木) 14:16:47.27ID:5J3UX5Vb
debug anywhereやろ
2019/07/11(木) 14:20:46.71ID:xCkJ5LaR
Windows, WSL, Ubuntu16.04 では、Python, Perl は最初から入っている。
Ruby は、apt でインストールした

ls −l /usr/bin/python
/usr/bin/python −> python2.7

ls −l /usr/bin/python3
/usr/bin/python3 −> python3.5

ls −l /usr/bin/perl
/usr/bin/perl

ls −l /usr/bin/ruby
/usr/bin/ruby −> ruby2.3

注意。サーバーエラーになるので、全角に変換した
2019/07/11(木) 14:59:54.89ID:3GvBtncU
そういえば IBM の z/OS ではどうなっているんだろうと
思ったら z/OS シェルってのがデフォルトでインストール
されてて、こいつは POSIX compliant らしい
2019/07/11(木) 15:48:04.71ID:PMWvbDa1
それだ WSL が標準で最初から入っているようになると
昔のニュースで見たが、どうなっているの?
標準は取りやめ? Windows の最新情報追ってないからわからない
197194
垢版 |
2019/07/11(木) 16:19:18.53ID:xCkJ5LaR
Windows10 を普通にアップデートしていれば、WSL は、最初から入っている。
ストアから、Ubuntu18.04 (長期サポート版)などをインストールして、日本語化すればよい

漏れはまだ、古いUbuntu16.04 の方を使っているけど
2019/07/11(木) 18:15:20.64ID:8iBC56G3
>>184
あれは、普段使いのCUIではないからな
単なる開発用
2019/07/11(木) 18:16:22.72ID:8iBC56G3
>>189
XPは標準で入ってて問題になった
2019/07/11(木) 18:29:01.43ID:8iBC56G3
個人的には、*nixとWindowsの違いは、
シェルと馴染んだコマンド群の有無、シェルスクリプトの実行可否だけなので、
それさえできれば、どちらでもいいや。
Cygwinはややストレス溜まったけど、WSLはだいぶ快適になった。
2019/07/12(金) 00:13:06.93ID:Iwx9PgjW
cmdのオプションが/なのは当て付けなんだろうか
XENIXを売ってた頃のMS知らんけど
2019/07/12(金) 00:38:52.25ID:hw+u6C0G
階層がないファイルシステムだと - でも / でもどっちでも違和感が無いのだろう
単に好みでそれにしたってだけじゃないかな
階層があるようになって / を好みで選んで失敗したと思ったけどどうにもならななかったよう
手立ては用意したがサードパーティがそれを使わないとか
2019/07/12(金) 00:54:25.43ID:hw+u6C0G
ああ、どうにもならなかったのは、
オプションを/にしてしまったからとりあえずパス区切りはバックスラッシュにしたよ、でも、/ にもできるよ
だった。オプションを - に変えるのは今でも前のいつでもできるだろうな
コマンドによっては別の意味を持たせてとかありそうだが、なんの拘りなんだかよくわからんな
2019/07/12(金) 08:37:34.85ID:paORMduQ
https://packages.debian.org/ja/experimental/ksh
kshはずっと93uだったはずだが、2020なんてのがでるのか?
2019/07/12(金) 10:59:03.44ID:paORMduQ
同じPCで一つがWSL1上のUbuntu、もう一つがDocker上のUbuntuで
lsb_release -aしてどちらも同じUbuntu 18.04.2 LTSなのに

kshのシェルに入ってから以下のコマンドを実行すると違いがある

echo $((99999999999999999))
=> 100000000000000000 # WSL
=> 99999999999999999 # Docker

KSV_VERSIONは両方とも同じ Version AJM 93u+ 2012-08-01

カーネル関係なさそうなのに、なんでだろう?
2019/07/12(金) 11:04:55.32ID:OtxPhCkg
大きな数の取り扱いの限界が違うのかも
207デフォルトの名無しさん
垢版 |
2019/07/12(金) 12:04:33.46ID:uJ9G3Ton
ディレクトリごとの正確なファイル数が高速に知りたいです。
2019/07/12(金) 12:15:53.93ID:OtxPhCkg
ls より find が早い
再帰ディレクトリ探索とファイル名出力はそれに任せて
その出力をパイプで変換していったらいいんじゃないか?
2019/07/12(金) 12:22:05.68ID:gCudY7G9
なぜduでファイル数も調べられるようにしなかったのか?
2019/07/12(金) 12:22:27.56ID:gCudY7G9
duの作者に問い詰めたい
2019/07/12(金) 12:24:06.88ID:OtxPhCkg
やるべきことは最小限の1つ
UNIXの哲学でしょ

小さいから早い
小さいからパイプでつなげていろいろ実現できる
小さいから保守できる
2019/07/12(金) 12:27:18.37ID:gCudY7G9
その理屈だと、lsコマンドはファイルの名前だけじゃなくて
ファイルサイズまで表示している。

最小限になってない。findコマンドを見習え
って話になるんだがw
2019/07/12(金) 12:28:12.53ID:gpn1wbN7
>>209
ファイルを数えるのはduの仕事じゃないから
2019/07/12(金) 12:30:19.18ID:gCudY7G9
ファイルを数えるのは誰の仕事?

仕事は一番うまくできる人がするべきですよ
2019/07/12(金) 12:32:27.12ID:gCudY7G9
そういやファイル名に改行が含まれる場合、
POSIX準拠コマンド&オプションだけで数えられるの?
2019/07/12(金) 12:35:41.89ID:gCudY7G9
やるべきことは最小限っていったら
duコマンドなんていらんよな

findでファイル検索して、lsでファイルの情報出して
awkで加算すれば良い

パイプでつなげていろいろ実現できる
2019/07/12(金) 12:53:26.46ID:433S/V3Z
>>205
>>206
long doubleを使っているんだと思う。long doubleは昔のx87 fpuで計算されることになるが、これは精度を設定できて、確かデフォルトがlinuxでは80bit、windowsでは64bitになっていたと思う。
2019/07/12(金) 13:00:19.57ID:WQ2UtQMj
>>217
でもWSL版Ubuntuと通常のUbuntuでバイナリは同じはずでしょ?
FPUモードの設定とかあるってこと?
同じ命令でもモードによって精度が違うとか
2019/07/12(金) 13:39:06.41ID:uwyqXnfJ
元々、浮動小数点は誤差があるから、どっちでも良い

誤差無しなら、プログラミング言語で、Decimal などのライブラリを使わないといけない
2019/07/12(金) 13:49:24.26ID:OtxPhCkg
>>212
ls 凄いよね
呼びだした端末の表示限界まで調査して
整列してくれる

最小限だけではものたりないから Emacs とかできたんじゃない?
2019/07/12(金) 13:57:13.80ID:q8HbeEfz
>>207
$ find 〈対象ディレクトリ〉 -type f | wc -l
2019/07/12(金) 13:59:45.00ID:q8HbeEfz
bcコマンド使いなよ。POSIXで定められたほとんど唯一といっていい任意精度演算ができるコマンドだぜ。
残念ながらなぜかUbuntuには初期状態で入っていない……。
2019/07/12(金) 14:11:11.28ID:OtxPhCkg
>>207
find ~/web -type f | perl -pe 's{[^/]+$}{\n}m'|uniq -c
27 /home/web/
11 /home/web/elona/
5 /home/web/elona/.git/
9 /home/web/elona/.git/hooks/
1 /home/web/elona/.git/info/
...
2019/07/12(金) 14:17:11.58ID:OtxPhCkg
やっぱりシェルスクリプトのパイプやばい
たった1行の短いのでそこそこ早いのが書きあがっちゃう
2019/07/12(金) 17:35:59.38ID:greuAEFm
>>220
emacsは出自がUnixじゃないから
2019/07/12(金) 18:42:09.14ID:q8HbeEfz
ちなみにPlan 9(Unixの後釜)のlsはもっと洗練された体系になってる。
あとPlan 9のEmacsの手引書がおもしろい
2019/07/12(金) 19:16:50.62ID:13weq3zY
Plan 9の今後のプランは!?
2019/07/12(金) 19:39:49.25ID:gpn1wbN7
Plan 9も最初からGPLで公開していればLinuxと肩を並べてたかもね
2019/07/12(金) 20:39:39.59ID:fylm51D9
>>218
FPU制御レジスタをFLDCW命令で変更すると計算精度や丸め方向が設定でき、同じ命令でも動作が変わる
プログラムが明示的に設定しなければ、当然OSが設定した値になる
230デフォルトの名無しさん
垢版 |
2019/07/13(土) 10:28:41.44ID:H4ToI7wx
>>223
こういうの見るといつも思うんだけど、全部Perl(など)で全部完結して書くのとどっちがいいのかな?
殊に「高速で」条件があるなら。
2019/07/13(土) 10:36:29.63ID:006l8Xk5
>>230
パイプ有利でしょ
なぜなら perl は C の 10% 程の速度
シェルスクリプトの基本ツールは C で書かれているから早い
そしてパイプは並列プログラミングだ
2019/07/13(土) 10:51:01.49ID:Q8eoyE6C
並列「プログラミング」ではないな
単に仕組みとしてプロセスが同時並行しているだけで
2019/07/13(土) 13:12:58.10ID:PcwCdG6p
>>230
どうでもいいけど
>>223は基本的なコマンドで完結してるシェルスクリプトなので
Perlで「全部完結する」というのは対比する表現としてはちょっとおかしく思えるな
2019/07/13(土) 14:39:07.51ID:4CNtNVmB
単機能のコマンドを組み合わせて処理するのがシェルスクリプトだからな
それで速度が遅いだの言うならシェルスクリプトなんか使わなければいい
235デフォルトの名無しさん
垢版 |
2019/07/13(土) 16:01:43.14ID:Lat3oh38
>>223
uniq -cの前にsortしなくていいの?
2019/07/13(土) 16:32:06.44ID:006l8Xk5
>>235
別のところで動かしたらだめだったよ
sort 必要
2019/07/13(土) 16:34:17.14ID:006l8Xk5
ソートはたぶん早くないから
つまりコストが高いから
たぶん定番のあれやったほうがいい

1行ずつ読みこんだそれでハッシュ作って インクリメントしてくあれ
2019/07/13(土) 18:44:37.37ID:Wy302ne8
実はPOSIX sortならsort -uでuniq | sortと同等ことができるのでuniqは実質要らない子
2019/07/13(土) 19:00:08.87ID:Q8eoyE6C
uniqは重複したのを抽出する目的での利用が多いな
純粋にuniqで使う機会の方が極端に少ない
2019/07/13(土) 19:23:10.38ID:56OavmE8
uniq | sortって使い方分かってない奴かよw
uniqくらいソース読んでみなよ
2019/07/13(土) 19:38:16.75ID:Wy302ne8
>>240
そんな揚げ足取らんでも。。。
sort | uniqの間違いです。
2019/07/13(土) 20:35:19.67ID:yaak8A3v
ls .-lのrwxに8進数表記も追加できないかな
2019/07/13(土) 22:25:11.39ID:h6vp2MpA
こんな感じかな

https://wandbox.org/permlink/O0PwxkOoTDVfsMQ9

# スクリプトを直接書いて投稿すると 403 エラーになるな…
2019/07/13(土) 22:28:56.59ID:h6vp2MpA
あ、setuid/setgid/sticky bit のこと忘れてたわ
245デフォルトの名無しさん
垢版 |
2019/07/13(土) 22:47:31.71ID:YCgasS9+
find ~TEST -type f -printf "%h\n" |sort |uniq -c
これは早いわ
2019/07/13(土) 23:30:54.16ID:yaak8A3v
duのファイル版は俺も作ったけど未熟なんでこんな出来に
find ./ -type d -printf "%p " -exec bash -c 'ls -b "{}" | wc -l' \; | sed -r 's/(.* )(\w+)/\2\t\1/g'
2019/07/13(土) 23:43:20.86ID:PcwCdG6p
>>246
見易くていいね!
2019/07/14(日) 00:22:33.01ID:KitiOp9Q
>>244
https://stackoverflow.com/questions/1795976/can-the-unix-list-command-ls-output-numerical-chmod-permissions
awkで頑張れば4桁表示できるらしい
2019/07/14(日) 02:01:57.73ID:ygf6VvPi
>>207
Ruby の、1-liner で、特定のディレクトリ以下を再帰的にたどりながら(find)、
ディレクトリ以外(reject)を表示する。
%Q("〜") は、" を、Windows のPowerShell に解釈させないために、クォートする

-r で、pathname モジュールを読み込む

ただし、途中で改行しているけど、実際には改行しないで下さい!

ruby -rpathname -e 'Pathname( %Q("C:/Users/Owner/Documents/Ruby/test") ).find
{ |path| if File.directory?( path ) then; puts path, path.children.reject( &:directory? ).length end; }'

出力
C:/Users/Owner/Documents/Ruby/test
11
C:/Users/Owner/Documents/Ruby/test/a
4
C:/Users/Owner/Documents/Ruby/test/a/b
0
2019/07/14(日) 06:45:35.11ID:GSQZGuhE
stat -c '%A %U %G %z %n' .*
↑こういうのどう? lsのパーミッション表示を8進数に
まあPOSIXに規定されてないけど
2019/07/14(日) 10:08:35.55ID:niuQOGKU
>>245
sort を差し替えた
~/ 対象にしたら倍速

find ~/ -type f -printf "%h\n" | perl -ne '$dirs{$_} += 1; END{for $key (keys %dirs) {printf "%5s %s", $dirs{$key}, $key } }'
2019/07/14(日) 10:11:35.12ID:niuQOGKU
途中だった
最後に | sort -k 2,2 入れても入れなくてもあまり変わらない
やはり指数関数的にsort に大量渡すと遅くなる
2019/07/14(日) 12:30:16.97ID:GSQZGuhE
LANG=Cでやってみ。
254デフォルトの名無しさん
垢版 |
2019/07/14(日) 13:29:14.61ID:VYOKuUQn
POSIX の find って -printf がないのな。
難しいことは -exec でなんとかしろということか。
255デフォルトの名無しさん
垢版 |
2019/07/14(日) 13:32:10.29ID:VYOKuUQn
>>252
perl の中で sort やれば良いのでは?
sort keys %dirs にして。
256デフォルトの名無しさん
垢版 |
2019/07/14(日) 14:08:00.15ID:Vo3Tn1vW
Perlようわからんけど、findのところもまとめていわゆるVisitorパターンでやると?
シェルだと時間掛かる。
#!/bin/bash
shopt -s dotglob
walk() {
local c=0
for p in "$1"/*; do
if [ -d "$p" ]; then
walk "$p" # recursive call
elif [ -f "$p" ]; then
((c++))
fi
done
echo "$1: $c"
}
start_dir=$(basename "$1")
walk "$start_dir"
2019/07/14(日) 14:15:10.09ID:niuQOGKU
>>255
そうだね
さらにちょっと早くなった
2019/07/14(日) 15:14:56.46ID:GSQZGuhE
どうせPerl使うんならPerlに用意されているfindコマンド的な関数使えばいいのに。
いや正直Perl書けないので外部コマンドのほうが効率いいのかも知れんけど
2019/07/14(日) 15:43:17.08ID:niuQOGKU
今回たまたま perl が早かったのは
>237
ということ
つまり C は10倍ぐらい早いけど
何十倍も無駄なことやってたら遅くなってしまう

高速な find の出力を |sort |uniq -c したら一応答えでるけど
そのsort がウルトラ処理多い
だったらperl で1行ずつ読んで正しいアルゴリズムで処理したほうが早いだけ
2019/07/14(日) 16:48:51.97ID:XOVWGW1L
perlでソートしてないから
2019/07/14(日) 19:10:07.29ID:BEvjoRaR
なんだperlでソートしたら遅いのか
262デフォルトの名無しさん
垢版 |
2019/07/14(日) 19:11:22.06ID:AAGaqnKC
>>227
Plan無いん
263227
垢版 |
2019/07/14(日) 20:00:20.57ID:QmWR+pGh
>>262
GJ!
2019/07/14(日) 20:02:48.24ID:XOVWGW1L
awk版。ディレクトリ名でソートするなら sort -k2

find . -type f -exec dirname {} + | awk '{c[$0]++}END{for(i in c){printf"%4d %s\n",c[i],i}}' | sort
2019/07/14(日) 20:08:54.86ID:XOVWGW1L
xargs使ったほうが良いかな

find . -type f | xargs dirname | awk '{c[$0]++}END{for(i in c){printf"%4d %s\n",c[i],i}}' | sort
2019/07/15(月) 08:12:50.57ID:jP+0UVPX
どうせなら計測結果も付記してくれよ
267デフォルトの名無しさん
垢版 |
2019/07/15(月) 10:56:15.79ID:Ww8nr7y5
やってることが同じなら、Perlとawkは比較するまでもないのでは?
2019/07/15(月) 12:22:56.47ID:E9YINa1F
数分で書けるのがシェルスクリプトの良いところなんだし
数百万のファイルを何分以内で処理せよとか性能要件があるなら
そもそもシェルスクリプトなんかで書かないわ
269デフォルトの名無しさん
垢版 |
2019/07/15(月) 15:08:49.68ID:3UWFYY1V
高速化するならC言語使うな。
2019/07/15(月) 16:42:34.21ID:jP+0UVPX
なんかシェルスクリプトを貶す人間ってシェルスクリプトを本来の目的とは違う方法で使った結果失敗して
その恨みを自分の無能さではなくシェルスクリプトにぶつけてる印象。
2019/07/15(月) 16:46:57.72ID:tvlJQJn9
このパーツは意外と頻度多いからCで書いておいてもいいかもね
| perl -ne '$dirs{$_} += 1; END{for $key (sort keys %dirs) {printf "%5s %s", $dirs{$key}, $key } }'
2019/07/15(月) 19:25:46.44ID:jP+0UVPX
端末の応答(例えば$ printf '\e]11;?\e\\'で返ってくる\e]11;rgb:〈赤〉/〈緑〉/〈青〉\e\\っていう文字列)を
sedやらなにやらで加工できるように標準出力に流したいんだど
そのままの状態だと端末そのものに文字列が渡ってしまって加工できない。
$ printf '\e]11;?\e\\' | od
みたいにすると(当然だけど)\e]11;?\e\\という文字列がパイプを通ってしまう。

個人的にはsttyとかをうまくやりくりしたらいけそうな気もするのだけど
そういう文書や記事がないのと俺があまり端末の処理に詳しくないのとで今のところ成功していない。
端末応答を標準出力として処理できる方法知らないですかね。
2019/07/15(月) 19:47:51.35ID:iDG/5azN
>>272
色というものが何者かわかってないんじゃね?

色を付けるためのエスケープシーケンスっていうのは、
エスケープ文字、ASCIIコード表でESC(0x1B)の文字8進数だと033
ESC文字から始まる一連の文字列の流れ(シーケンス)ってだけだよ
だから0x1Bで始まるその文字列を加工すりゃ良い。

\e]11;の ]11;は単なる文字だけど、\eは(シェルによりけりだが)
0x1Bの文字に置き換わる。だからsedなんかで\eを見つけようとしてもだめ
そんな文字列は流れてこないんだから
2019/07/15(月) 19:59:18.87ID:jP+0UVPX
>>273
あー。いやそうじゃなくて 端末の応答を取得したいんよ。
試しに
$ printf '\e]11;?\e\\'
ってやってみて。多分端末の上に
^[]11;rgb:0c0c/0c0c/0c0c^[\
みたいな文字列が表われる。
この文字列をtestコマンドの対象にしたりしたい。
でも普通の方法ではこの文字列は標準出力ではなく端末の上に直接出力されてるから
そういう加工ができない。
2019/07/15(月) 20:00:57.13ID:iDG/5azN
>>274
話の内容を単純化しよう。
文字の内容は今どうでもいい話だろ?

printf 'hogehoge' ってやってみたら
端末の上に、hogehoge って表示されるな?

それでこの文字列をどうしたいって?
2019/07/15(月) 20:20:16.67ID:f1G4msuO
わかってない奴が話に絡んでいくなよ
文字列なんか関係ない
奴はttyの出力(もしくは入力)を横取りしてパスワードを盗みたいという話をしてる
2019/07/15(月) 20:21:36.85ID:iDG/5azN
$ printf '\e]11;?\e\\' の話だろ?
2019/07/15(月) 21:13:36.27ID:f1G4msuO
ぜんぜん違う
2019/07/15(月) 21:15:41.25ID:iDG/5azN
>>278
試しに
$ printf '\e]11;?\e\\'
ってやってみて。
2019/07/15(月) 21:21:51.85ID:qldwvqW5
>>276
パスワードだとしたら、出力には返ってこないから横取りもできないんじゃね
パスワード生で出力するようなアレでなければ
2019/07/15(月) 21:35:01.81ID:f1G4msuO
>>280
だから入力って書いたじゃん
エコーバックやめるタイミングを捕まえて入力側をだな
まあいいや、俺も答え知らないしw
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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