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

■ このスレッドは過去ログ倉庫に格納されています
2021/10/05(火) 22:49:30.91ID:KsbWuyFp
シェルスクリプトに関する総合スレッドです。

全般
・荒しは無視しましょう。
・丁寧な姿勢を心掛けましょう。
・ネチケット(死語)を意識しましょう。
・「○○(他の言語)でいいやん」は禁止。他のスレに行ってください。
・「POSIX原理主義」「ユニケージ」「USP研究所」はPOSIXとUnixを曲解し
間違ったシェルスクリプトを広めている宗教です。洗脳されないようにしてください。

前スレ: シェルスクリプト総合 その36
https://mevius.5ch.net/test/read.cgi/tech/1614212414/

関連スレ
・【Bash】Windows Subsystem for Linux【WSL】11
https://mao.5ch.net/test/read.cgi/linux/1627507889/
・Bashでプログラミング [転載禁止](c)2ch.net
https://mao.5ch.net/test/read.cgi/linux/1443885102/
・シェルスクリプト総合 その28
https://mevius.5ch.net/test/read.cgi/unix/1533154936/
・zsh その7
https://mevius.5ch.net/test/read.cgi/unix/1337844883/
・過去UNIXで使われていた ksh というシェルについて
https://mevius.5ch.net/test/read.cgi/unix/1582358403/
・【POSIX】UNIXプログラミング【BSD】 [転載禁止](c)2ch.net
https://mevius.5ch.net/test/read.cgi/unix/1443103705/
・おまえら! shell は何を使っているんですか?
https://mevius.5ch.net/test/read.cgi/unix/1012330865/
2021/12/26(日) 02:10:55.11ID:7bx5KWMB
>>370
できた。perl だ。

$ perl -ne 'chomp;push(@s,$_);if($l<length){$l=length} END{$m=int($l/8)+1;for(@s){print$_.("\t" x ($m-int(length($_)/8)))."IN A localhostのIP\n"}}' test.lst
abc.c0м IN A localhostのIP
defghijk.c0.jρ IN A localhostのIP
123456.nёt IN A localhostのIP
zzz.i0 IN A localhostのIP
$
2021/12/26(日) 02:14:02.08ID:7bx5KWMB
ただし、UTF-8で複数バイト文字混ざりだと画面上の幅とバイト数が一致しなくて失敗する行が出てくるだろうな。
2021/12/26(日) 02:30:31.24ID:Opbh/M6O
スレタイ読めよ
378デフォルトの名無しさん
垢版 |
2021/12/26(日) 06:24:53.12ID:7bx5KWMB
>>377
シェルだけでワンライナーにしろってか?可能な感じはするが、長くなりそうだな。ちょっと君試しに作ってみなよ。
2021/12/26(日) 06:55:50.56ID:Guj/6jti
いいかげんワンライナーなんてものからは卒業すべき
あれは実用的ではない
2021/12/26(日) 07:00:58.21ID:Guj/6jti
だいたい位置揃えならcolumnコマンドを使えばすむ
cat /etc/hosts | column -t
381デフォルトの名無しさん
垢版 |
2021/12/26(日) 08:08:53.29ID:7ywlyW9o
columnコマンドなんてあったのな
これしゅごい
382デフォルトの名無しさん
垢版 |
2021/12/26(日) 09:30:37.45ID:JgxQVN1x
>>378
スレタイ読めよ
383デフォルトの名無しさん
垢版 |
2021/12/26(日) 12:47:31.30ID:N3NYq5+A
プログラム技術。
384デフォルトの名無しさん
垢版 |
2021/12/26(日) 12:59:08.59ID:VAEhq19p
すれたい
2021/12/26(日) 13:59:45.22ID:0AMzbiZh
第一フィールドは20文字の決め打ちで

awk '{printf "%-20s %s", $1, "IN A 127.0.0.1\n"}' test.lst
386デフォルトの名無しさん
垢版 |
2021/12/26(日) 17:10:00.49ID:NwCcamJz
シェルではないね
2021/12/26(日) 17:57:01.68ID:FJp/KqIP
>>375
酷すぎるwww

>>380
>>385
既存のコマンドでスマートに解決できるのになw
2021/12/26(日) 20:01:39.02ID:nf0VENp6
columnはPOSIXじゃない!
よってawkで実装しなければいけない!
2021/12/26(日) 20:07:09.32ID:stZFhmVl
>>388
っスレタイ
2021/12/26(日) 21:01:43.80ID:NGc68XAG
フィルタープログラムはシェルスクリプトには必須だよ
391デフォルトの名無しさん
垢版 |
2021/12/26(日) 23:55:43.97ID:7bx5KWMB
>>380>>385
TABになってないじゃん。
392デフォルトの名無しさん
垢版 |
2021/12/26(日) 23:56:34.73ID:7bx5KWMB
>>387
既存のコマンドで丁度良くTAB入れるやつは何てコマンド?
2021/12/27(月) 01:45:10.81ID:t9d2fK6k
>>392
スペースをタブに置き換える unexpand ってコマンドがあるよ!

>>385をちょっと改造、第一フィールドを50文字にしてスペースをタブに変換してみよう

awk '{printf "%-50s %s", $1, "IN A 127.0.0.1\n"}' test.lst | unexpand -a


でタブをスペースに置き換えるのが expand ってコマンド
expand はたまに使うけど unexpand はあんまり使わないよね
2021/12/27(月) 01:51:55.20ID:4XXPAYbv
>>393
第一フィールだけやるな
50文字固定にするな
awkで実装したって劣化版になるだけやろ?
columnをインストールすればいいだけやん
395デフォルトの名無しさん
垢版 |
2021/12/27(月) 02:06:52.16ID:4gZrwhe1
>>393
unexpand -a だと全ての空白を対象にしてTABに置き換えようとするためにうまく行かなくなることがあるのでは?

>>394
column コマンドでは TAB は出力されないよね。
2021/12/27(月) 02:53:50.89ID:t9d2fK6k
>>394
何そんなに怒ってんの?
入学試験じゃないんだからさ〜、臨機応変、柔軟、適当にやればいいじゃん
それに column 使うのはいいとしてAレコードの追加しなきゃダメでしょう?

>>395
あんまり細かいことは突っ込まないでねw
2021/12/27(月) 05:01:52.38ID:4XXPAYbv
> column コマンドでは TAB は出力されないよね。
スペースをタブに変換すりゃいいだろ
2021/12/27(月) 05:02:55.30ID:4XXPAYbv
シェルスクリプトというのは既存のコマンドを使って
いかに楽をするかっていうのが重要
POSIXにこだわるのはアホ
399デフォルトの名無しさん
垢版 |
2021/12/27(月) 05:33:06.74ID:oI31DZmc
>>394
columnコマンド使って>>370やってみろよ
400デフォルトの名無しさん
垢版 |
2021/12/27(月) 11:39:49.78ID:4gZrwhe1
>>396
TABかスペースが関係ないならそれで良いんだよ。>>369, >>370 の求めているものとは違うものになるけどな。

>>397
それをするのに丁度良いコマンドはあるの?
unexpand -a では全スペースが対象になってしまって駄目かも知れないわけだが。
2021/12/27(月) 12:51:40.94ID:t9d2fK6k
ハイハイ、ご要望通りにいたしましたw

F="%-`wc -L test.lst|cut -f1 -d' '`s";awk '{printf"'$F'\t%s",$1,"IN A 127.0.0.1\n"}' test.lst|unexpand -a
402デフォルトの名無しさん
垢版 |
2021/12/27(月) 22:40:58.39ID:6GChlJ/6
>>401
ありがとう
2021/12/28(火) 01:16:53.28ID:JDHjDqJz
汚らしいパールのワンライナーに比べたら多少洗練されたようだな
2021/12/28(火) 12:30:02.74ID:IE5w4ImF
>>400
> unexpand -a では全スペースが対象になってしまって駄目かも知れないわけだが。

駄目だって事例提示してみ?
2021/12/28(火) 14:14:41.00ID:l3lJRmOp
columnは知ってたけど-Lオプションは知らなかった
2021/12/28(火) 14:39:23.17ID:GaScW5/W
columnに-Lオプションなんてあるの?
2021/12/28(火) 19:18:04.81ID:53pt8mb/
UNIX哲学
2021/12/28(火) 23:09:44.65ID:5lZUdhkB
POSIX原理主義者「POSIXにはないコマンドをawkで再実装した」

UNIX哲学「車輪の再発明をするな」

POSIX原理主義者「・・・」
2021/12/28(火) 23:13:32.40ID:l3lJRmOp
>>406
wcの-Lだよ
-lしか使ってなかった
2021/12/29(水) 00:32:57.69ID:fFVPrxR2
debianのcolumnに比べてredhat系のcolumnのオプションが随分と充実してる
411デフォルトの名無しさん
垢版 |
2021/12/29(水) 01:12:38.97ID:Uqmbe8qT
2カラム目以降に何が来ようとも決してTAB変換されなくするには2カラム目以降を完全に後付けにすれば良い
それとawkの-vで事前に最大文字数入れておいて後でprintfのフォーマットに*使った方が見た目奇麗になるね

awk -v m=`wc -L < test.lst` '{printf "%-*s\t\n", m, $1}' test.lst | unexpand -a | xargs -i echo "{}IN A 127.0.0.1"
2021/12/29(水) 02:59:14.48ID:I8/QQkF4
スーパーコンピュータシステムのファイル消失のお詫び
https://www.iimc.kyoto-u.ac.jp/ja/whatsnew/information/detail/211228056999.html

2021年12月14日 17時32分 から 2021年12月16日 12時43分にかけて,
スーパーコンピュータシステムのストレージをバックアップするプログラム(日本ヒューレット・パッカード合同会社製)の
不具合により,スーパーコンピュータシステムの大容量ストレージ(/LARGE0) の一部データを意図せず削除する事故が発生しました.


Lustre ファイルシステムのファイル消失について
https://www.iimc.kyoto-u.ac.jp/services/comp/pdf/file_loss_insident_20211228.pdf

1 ファイル消失の影響範囲
対象ファイルシステム: /LARGE0
ファイル削除期間: 2021 年 12 月 14 日 17 時 32 分〜2021 年 12 月 16 日 12 時 43 分
消失対象ファイル: 2021 年 12 月 3 日 17 時 32 分以降、更新がなかったファイル
消失ファイル容量: 約 77TB
消失ファイル数: 34,011,293 ファイル
影響を受けたグループ: 14 グループ(4 グループが復元不能)

3 ファイル消失が発生した原因
バックアップスクリプトには、find コマンドにより 10 日以上古いログファイルを削除する処
理が含まれています。スクリプトの機能改善と合わせて、find コマンドの削除処理に渡す変数名
を視認性・可読性を高めるため変更いたしましたが、この修正したスクリプトのリリース手順に
考慮不足がありました。
bash は、シェルスクリプトの実行中に適時シェルスクリプトを読み込みます。この挙動によ
る副作用を認識できておらず、実行中のスクリプトが存在している状態でスクリプトの上書きに
よりリリースしてしまったことで、途中から修正したシェルスクリプトの再読み込みが発生し、
結果的に未定義の変数を含む find コマンドが実行されてしまいました。この結果、本来のログ
ディレクトリに保存されたファイルの削除をする処理ではなく、/LARGE0 のファイルを削除し
てしまいました。
2021/12/29(水) 03:16:45.01ID:gf7++b5l
あぁ、やはり Lustre はダメだなぁ…
2021/12/29(水) 03:21:51.59ID:9nMYZ2sv
機器の不具合かのように書いてるけど馬鹿による人災じゃねーか
2021/12/29(水) 04:05:13.87ID:DIjHY86S
シェルスクリプト以外ではほとんど見られない性質ではあるからなあ。
たしかに人災とも言えるけど。
416デフォルトの名無しさん
垢版 |
2021/12/29(水) 04:51:32.06ID:Uqmbe8qT
シンボリックリンクで新しいバージョンのプログラムにリンク先切り替える方式にしておけば被害は防げたかも知れないな
2021/12/29(水) 09:47:12.44ID:aqWkCMvZ
xargsは強力だよねー
全然使いこなせねーわ
2021/12/29(水) 10:35:20.64ID:HbjA8KL2
Linux の場合プログラムは起動時に全てメモリに読み込まれるから
稼働中にプログラムを差し替えても OK って考えて実際に差し替えたら
メモリ上の古いプログラムがファイルシステム上の新しいモジュール
ファイル読もうとして動作不良になったことがあったなあ
2021/12/29(水) 10:53:37.16ID:yFPIHMKS
この挙動ってinodeが同じまま書き換えたから起こったんだよね?
inode変わるファイル更新なら起こらないよね?
2021/12/29(水) 11:28:25.09ID:DIjHY86S
>>419
更新手順が更新されるんやろなあ。
既存ファイルに直コピーが禁止になって、新規ファイルを作成後に既存名に改名とか?
2021/12/29(水) 11:33:56.17ID:EOkSZQC4
リリース手順の考慮不足以前にfindを使った削除の運用自体に問題がある
ちゃんと金払ってまともなもの作ってもらわないと

未定義の変数を含むfindコマンドが実行すると
rootディレクトリのファイルが全削除される?
2021/12/29(水) 13:13:58.03ID:KOMId+4/
findとか関係ねーよ
例えばrmで終わるコマンドがあったとして

xxxxrm / が rm / と解釈されることだってある
423デフォルトの名無しさん
垢版 |
2021/12/29(水) 13:53:35.50ID:kCXooe0G
/LARGE0${undefined}ってこと?
2021/12/29(水) 15:06:25.94ID:W7/CHwWQ
>>418
>Linux の場合プログラムは起動時に全てメモリに読み込まれるから

誰に騙された?
2021/12/29(水) 15:11:30.51ID:1N8ukzHQ
https://zenn.dev/mattn/articles/5af86b61004bdc
やっぱりinodeが変わってればokだったみたい。
mvとか、installとか使って反映しておけば回避できてた模様
2021/12/29(水) 15:31:39.64ID:V1sEjw5U
門外漢なんで純粋に知りたいんだけどこのbashの実行中の書き換えも書き換えたとこから逐次実行する仕様って歴史的経緯によるもの?もしくは
有効に活用できるケースがたくさんあるから意図して実装している?
2021/12/29(水) 16:23:06.17ID:bBNK3YsU
Lustre の checkpoint 機能は使ってなかったのかな?
428デフォルトの名無しさん
垢版 |
2021/12/29(水) 17:29:01.73ID:wwN1RbRp
Linuxはホットパッチが売りなので。
2021/12/29(水) 17:40:55.16ID:I8/QQkF4
https://stackoverflow.com/questions/2285403/how-to-make-shell-scripts-robust-to-source-being-changed-as-they-run
2021/12/29(水) 17:43:56.77ID:Y+wm1ikU
>>422
今回のにそれ関係ある?
2021/12/29(水) 18:01:13.94ID:tast0kyj
規模は違えど今回の事例と同様の体験をした人・組織は少なくなさそう
2021/12/29(水) 18:01:34.74ID:o6aVS5Lj
inode云々は問題の表層でしかない
実行中のスクリプトが新しくなったからといって77TBものユーザーデータをサクッと削除しちゃえるのがおかしい
何重にもガードできているのが当たり前の案件
2021/12/29(水) 19:12:14.86ID:DIjHY86S
>>426
あくまで「シェル」なんやし、入力を逐次実行するのが仕様やろ?
2021/12/29(水) 19:12:44.47ID:DIjHY86S
>>432
コストとのバランス。
2021/12/29(水) 21:10:55.07ID:t8aruUm+
スパコン系の人達は運用周りのリテラシーすごく低い
シェルスクリプトしか知らない人達よりもひどいくらい
2021/12/30(木) 00:46:59.13ID:IL1LVlOR
>>434
ファイルの削除処理はJavaで作ればいいんちゃいます?
ログもしっかり残してさ
2021/12/30(木) 01:04:22.58ID:v9gi5gW5
Javaが出てくる意味が分からん
2021/12/30(木) 01:12:51.79ID:IL1LVlOR
Javaで作れば安全だからです!
439デフォルトの名無しさん
垢版 |
2021/12/30(木) 01:25:09.88ID:TO85sxcb
log4jで消そう
440デフォルトの名無しさん
垢版 |
2021/12/30(木) 01:49:09.54ID:wfs2tbs7
perlのワンライナーでやるべき
2021/12/30(木) 02:02:44.37ID:bPzpLvLZ
>>425
installコマンドを使わないバカが多いからなあ
2021/12/30(木) 02:05:00.83ID:bPzpLvLZ
>>426
bashそのものじゃなくてスクリプトの方だぞ
2021/12/30(木) 02:15:01.93ID:IL1LVlOR
>>441
installコマンドでも同じなんだが
こういう本物の馬鹿が多いからなあ
2021/12/30(木) 02:25:12.29ID:IL1LVlOR
>>426
bashに限らずevalが使えるスクリプト言語はどれも似たようなもの
その方が効率がいいから

ファイルを全部メモリに読み込んでたらメモリの無駄遣い。必要になった時に読み込んで
コンパイルして中間コードをメモリに保存したほうが効率がいい

書き換えたところから実行する仕様とかじゃなくて
読み込み中にファイル内容が書き換わっただけ
445デフォルトの名無しさん
垢版 |
2021/12/30(木) 05:20:47.81ID:jspnt6Wc
#!/bin/sh
{
# Your stuff goes here
exit
}

って書くと、全部読み込んでから実行する…らしい。
2021/12/30(木) 05:51:55.73ID:W4YtctsR
>>444
> bashに限らずevalが使えるスクリプト言語はどれも似たようなもの

知らんけどJK、PerlもRubyも違うやろ。。。
447デフォルトの名無しさん
垢版 |
2021/12/30(木) 05:57:08.73ID:jspnt6Wc
>>446
REPL(Read-Eval-Print Loop)が使えるスクリプト言語あたりが妥当?
2021/12/30(木) 06:03:55.94ID:IL1LVlOR
>>446
検証してないけどPerlとPHPも同じらしい

それに厳密に言えばRubyでスクリプトを起動している途中で
gemsをアップデートしたらおかしくなる可能性があるやろ?
今から読み込もうとしたライブラリファイルが
中途半端に入れ替わってる可能性がある

シェルスクリプトは1ファイルの中で中途半端に
読み込まれて実行されてる可能性があるが
他のスクリプト言語は、それはないかもしれないけど
複数のファイルで構成されてる場合、中途半端に読み込まれて
実行されてる可能性がある

そしてバイナリでも動的にライブラリを読み込むようなものがあれば
同じようなことになる可能性がある
449デフォルトの名無しさん
垢版 |
2021/12/30(木) 06:43:40.02ID:QArx8wCq
動的なのがあれば、な・・・
2021/12/30(木) 09:02:46.96ID:InFuAQoQ
こういう面倒なことになるからWindowsはアップデートの時に再起動が必要な仕様にしたんだよね
2021/12/30(木) 09:39:47.43ID:rDu++FLs
ツッコミどころが多すぎるんだよなぁ

しいて他山の石とするなら
findの結果を直で削除せず
チェックしてから削除したほうがいいってことくらいかな
2021/12/30(木) 09:58:18.91ID:uV4Ti94h
>>448
よほど特殊なケースを除いて
RubyやPythonでは同じ問題は発生しないよ
かと言って実行中に上書きはしないけどな
2021/12/30(木) 10:30:47.99ID:IL1LVlOR
>>451
突っ込みどころが多いのはお前だろ
どうやってシェルスクリプトでfindの結果をチェックして削除済んだよ
しかもそのチェックコードすら書き換わるって話だろ
何が問題になってるのかわかってない
2021/12/30(木) 10:31:51.45ID:IL1LVlOR
>>452
特殊なケースで発生するって言ってんじゃんw
2021/12/30(木) 10:40:55.52ID:O8K8cDY/
必死すぎて草
2021/12/30(木) 11:23:36.83ID:IL1LVlOR
反論できてなくて草w
2021/12/30(木) 12:07:43.56ID:WfZiLBBo
>>448
>それに厳密に言えばRubyでスクリプトを起動している途中で
>gemsをアップデートしたらおかしくなる可能性があるやろ?

そういう運用を前提にするなら起動途中にgemをアップデートしてもおかしくならないように作ればいい
2021/12/30(木) 12:09:53.89ID:IL1LVlOR
シェルスクリプトの場合{ } で全体をくくって作ればおかしくならない
2021/12/30(木) 12:59:41.27ID:W4YtctsR
>>448
それは>>444とほとんど関係のない話。
実行中とロード中は違う。
論点ずらしはやめろや。
2021/12/30(木) 13:01:44.37ID:W4YtctsR
>>447
要するに、シェル系だけなんちゃうの?w
2021/12/30(木) 13:07:53.94ID:W4YtctsR
>>450
Linuxは、実は再起動が必要なときでも、システムがそれを認知しないだけやったりするからな。。。
考えてみると、システムのsoファイルを更新しまくっても再起動不要なのはヤバいやろ。w
2021/12/30(木) 13:58:37.21ID:A3EHubzP
とりあえず手持ちの(Ubuntu20.04のデフォルト)環境だと

testと表示される
```
#!/bin/sh
echo echo test >> $0
```

testと表示される
```
#!/bin/sh
{
echo echo test >> $0
}
```

testと表示されない
```
#!/usr/bin/python3
import sys
with open(sys.argv[0], "a")as f:
f.write("print('test')")
```

/bin/sh はファイルを展開したまま参照してるけど、
/usr/bin/python3 は一度どっかにコピー(構文解析済みキャッシュ)してるから実行中の上書きが反映されない感じだと思う
2021/12/30(木) 16:24:30.20ID:W4YtctsR
>>458
いいや、閉じ括弧の後、EOFを検出する前(要はブロック実行中)に行が追加されるリスクがあるやろ。
リスクを心配したいんかしたないんか、どっちやねん?w
2021/12/30(木) 17:21:00.62ID:p57leh5q
>>453
君のところでは実行中に直接上書きするのが当たり前なの?
うちではそんなことしないから考慮する必要ないんだよね

削除に至るまでのセーフガードが他にもいくつかあるからあえて教訓を得るなら削除前のチェックかなって話
2021/12/30(木) 18:18:54.05ID:QArx8wCq
プログラム上書きで動作を変えられるというのは、ある意味脆弱性と言えるかな
権限奪われた後でしか起こせないけど
2021/12/30(木) 18:28:25.88ID:QArx8wCq
Perlとかはプログラム全部読んでから内部コードにコンパイルしてからそれを実行するので動的な部分以外は大丈夫だと思う
Perl で動的というと eval に文字列引き渡した場合と require でソース読んだ場合かな
シェルで言うと eval とドットや soure でのソース読み込み
2021/12/30(木) 22:04:38.94ID:vZc7D3zM
>>443
説明が足りないんじゃない?
単一のシェルスクリプトの場合は、更新時にinodeが変わってれば大丈夫。で終わり。

シェルスクリプトから、別のシェルスクリプトを読んでる場合は、
読み込む行でpathを評価するから、
読み込むシェルスクリプトだけが新しくなって、読み出し元シェルスクリプトが環境変数を持たない結果、同じ事象が発生する可能性はある。

だから、
installを使ったからと言って、すべてのトラブルを避けられるわけではない
と言うのであれば妥当
2021/12/30(木) 23:01:21.28ID:jmc3LnTL
そこは重大な障害に至った本質的な原因じゃないからな
2021/12/31(金) 00:01:34.88ID:tL7Nlh3I
>>459
スクリプト系は実行中にロードするんだよ
該当の行まで実行しないとgemsが読み込まれない
実行前に全てのライブラリを読み込むわけではない
2021/12/31(金) 00:02:22.53ID:tL7Nlh3I
>>463
> いいや、閉じ括弧の後、EOFを検出する前(要はブロック実行中)に行が追加されるリスクがあるやろ。
{
  exit
}

閉じカッコの後が実行されるとでも思ってんの?
2021/12/31(金) 00:03:22.20ID:tL7Nlh3I
>>467
installはcpと同じ挙動をするんだから
解決策になってないって言ってるんだが理解してるか?
2021/12/31(金) 00:03:51.43ID:tL7Nlh3I
>>466
> Perlとかはプログラム全部読んでから内部コードにコンパイルしてからそれを実行するので動的な部分以外は大丈夫だと思う
PerlとPHPはシェルと同じ問題がある
調べてから書き込め
2021/12/31(金) 00:05:13.58ID:tL7Nlh3I
>>464
お前何の話してんの?

> findの結果を直で削除せず
> チェックしてから削除したほうがいいってことくらいかな

が意味不明って言ってるだけやろ
2021/12/31(金) 00:05:43.76ID:tL7Nlh3I
>>460
PerlとPHPもおなじ
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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