シェルスクリプト総合 その29
■ このスレッドは過去ログ倉庫に格納されています
!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 お約束 ・特記なき場合、Bourne ShellもしくはPOSIX準拠のsh可換シェルが既定です つまりシバンは#! /bin/shです。 他のシェル(bash, zsh, ksh, (d)ash, yash, posh, fish, (t)csh)などの専用機能に依存する場合は明示しましょう。 OS X, GNU/Linuxユーザーは/bin/shの実体がbashなので*特に*注意(自覚なきbashism---シバンが#!/bin/shなのにbashに依存する構文を使っていませんか?)。 ただしDebian, Ubuntuなどでは/bin/shの実体はPOSIX sh互換のdashですのであまり気にしないでも大丈夫です。 FreeBSDユーザーは/bin/shの実体がashなので注意。 Solaris, OpenBSDユーザーは/bin/shの実体がkshなので注意。 csh/tcshでのシェルスクリプトは*まったく推奨しません*。 (参考URL: http://www.speech-lab.org/ ~hiroki/csh-whynot.euc) ・POSIXに準拠しましょう 有用なリンクはhttps://en.wikipedia.org/wiki/POSIX にまとめられています。 最新の仕様はこちらへ: http://pubs.opengroup.org/onlinepubs/9699919799/ (左上の「Shell & Utilities」から各コマンドやファイルの仕様を参照することができます) ・Version 7 UNIXのsh(1)に一番近いのはOpenSolaris由来のHeirloom sh、次点でDebianなどに搭載されているDash shell Heirloom sh: http://heirloom.sourceforge.net/sh.html Dash shell: http://gondor.apana.org.au/ ~herbert/dash/ ・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります Manページや各種リンク(http://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html など)を見ましょう。 apropos(1)ないしはman(1)の-kオプションでそれらしい単語による簡単な検索もできます。 ・ワイルドカードは正規表現ではありません。 正規表現の話題はスレ違い(正規表現スレへ) ・シェルスクリプトのことをシェルってゆうな 初心者へのアドバイス ・適した道具を判断するのも頭の重要な使い方。 シェルスクリプトよりもPerlまたはPythonの方が適した処理にはそちらを使いましょう。 ・知らないコマンドが出てきたらman(1)を引きましょう。 ・思い通りに動かないときは、まずはsh(1)の-xオプションでトレースしましょう。 回答者への注意事項 ・相手がシェルスクリプトでの処理方法を質問しているのにもかかわらず、よく知りもせずに、「そういうのはPerl, Python使え」と回答するのはやめましょう。 安易にPerlやPythonに逃げずに小さなコマンドを組み合わせシェルスクリプトで処理するのが頭のいいやり方。 ・質問に対して問題が間違ってるといちゃもんをつけるのも避けましょう。 (補足:今スレのみ) 同名スレッドが乱立していますが、Unix版→ム版移行に伴い荒らしとミスが横行したためであり、実際に使用されるのはこのスレのみです。同名の他スレは利用しないように願います 早速役にたったな これでワッチョイをNGすればこいつは消える 前のスレでASCII US,RSを区切り文字にしたファイル形式について話してた者だけど エスケープ文字を\␟,\␞の二つにできないかな。 これで大分処理が楽になるんだけど,この規則で区別できない二種類以上の文字列があれば教えてほしい。 前スレも埋まらないうちから主張はじめんなや 前スレでやれ >>8 がいつもの荒らしやろ 確かスマホから書き込んで自作自演してるって どこかでみたし それだとな USとRSのasciiデータを含むことができないワケ やっぱりな低学歴知恵遅れは致命的に頭悪い >>11 だから前スレでやれ ついでに俺はスレ立てた本人だ > ついでに俺はスレ立てた本人だ 1デフォルトの名無しさん (ワッチョイ 3efb-m2E0)2018/09/22(土) 11:53:21.38ID:BBiLRgnj0 13デフォルトの名無しさん (アウアウカー Sae9-m2E0)2018/09/22(土) 21:19:04.63ID:SEEeyc/q ワッチョイ アウアウカー なるほどねw 何でも喧嘩越しだなんて… お前ら人生もっと楽に生きろよ >>14 スマホ回線だとスレ立て規制されてたからWi-Fi繋いだだけだぞ 恥ずかしい思いする前にワッチョイの右側読み取ろうな 無敵だなw無敵という表現は正しくはないが まあ、あんまカッカしないでw シュッ シュッ ∧∧ シュッ シュッ (`・ω・) シュッ シュッ みんな、ここは飲んで気を落ち着かせるんだ!! (つ と彡 / シュッ /// / /c□ / /旦 / //c□ ./ /旦 Y / | | 旦 | |旦 ガシャーン ガシャーン ガシャーン ガシャーン ワッチョイもついたようだし、スレ新しくなったので前スレのこれお願い bashでさ、typesetで関数の中身を出力できるじゃん? それをevalで評価したら同じ関数が出来上がるじゃん? これってどれくらい信用できるんだろう? 作成した関数のコードそのままの形で出力されるなら evalで評価して同じものができるだろうけど、 ぱっとみtypesetで出力するされたものをみると、 改行の位置とか変わって整形された状態になって 関数にはfunctionが頭に追加されてる。 元のコードをどれくらい書き換えるんだろうか? これ以外になにか変わる事知ってたりする人いない? >>19 つまりおまえは定義した関数とそれをtypesetで表示させた物が別もんやと思とるんか? そこまで疑っとって逆によくbash使えんなw おまえの頭の中はどおなっとるんやw ワッチョイでスレを立てたのは前スレを荒らしに荒らしまくった多数回線で自演するRubyアンチのPyキチだよ 自分だけが自演できるワッチョイスレを立てて工作したいんだと思う 次世代スレもワッチョイで立てようとしたけどあっちは失敗したみたいだし 前スレの終わらせ具合からそう見えないこともないなww スレ立てたのも前スレ終わらせたのも俺だがそれのこと言ってんのか? rubyもpythonも語ったことなんてないが妄想すごいですね うん、妄想は尽きないw ちょっと終わらせ方が強引だったからねえ、ヤツならやりそうだなと。反省してっwまた、すぐ怒ったり(?)しないでね 発端となった>>7 が全然続かないのな。もう続けてもええんやで じゃなきゃ、前スレでやれでしかなかった、および、無理やり終わらせた意味がゼロだなw 低学歴知恵遅れの戯言にだれも興味なんかない まずその自覚がない まず相当頭悪いこと書いてる自覚がない そこが問題だからな ワンパターンのフレーズを繰り返すしかできないのあったが、悔しくてそれでもしてしまう自称賢いはんかくであった としか見えないなw >>12 にも書いたとおり USとRSのasciiデータを含むことができない コレでおわりだからな 頭悪いことを自覚できないかぎり 頭悪いのは治らない コレは真理だからな なんでワッチョイつけた後になっても半角に構ってるんですかねぇ とっととNGしてどうぞ >>29 ,30 あんた自身ではわざわざ終わってるのに蒸し返すんだな。俺の蒸し返し(?)の意味は違うぞ おとなしく前スレでやればいいことだった、前スレを強制終了することもなかった だからな?あんたの主張なんて関係ない興味ない(自称賢いを言いたいがためのなんてw) >>31 んー、まあ、ノリでw まず勘違いしてるのは オレが賢いとかいってるところ オレが賢いのではなく 当事者が日常生活に支障をきたすであろうと考えられるぐらい頭悪いこと問題だからな そういう問題だ 軽度の知的障害があると推認できる よく言うよ。不特定に向けてもそういうフレーズ使ってるくせに。ほんと自称賢いだな 別人なんですアピール終わった? ほんとうざいわコイツ 大学生が課題貼り始めたあたりから何かがおかしくなっていったな 極めつけはCSVだったが >>39 おまえが出入りしだしたあたりからだいぶおかしいでwおまえのせいとは言わんけどw >>40 さてそれはいつ頃か正確に言ってくれませんかね? ドンピシャしたらROMってあげよう単芝君 なんでそうすぐにムキになるんだか。>>39 なんて俯瞰してもの言えないんじゃねと でもASCII区切り文字を使ったいいアイデアが出たので俺は嬉しいよ エクセルの出力結果みればわかるとおり もともとなにも問題ない 低学歴知恵遅れがその出力より劣化したアイデア()を ドヤ顔してだしてるだけだからな それはな世間一般ではアイデアとはいわない それは頭悪い寝言という わかった? >>41 ムキになっとるのは何か自覚でもあったんか?w Shell Scriptって国際化はできないの? 調べるとBashは$"text"→$"文"みたいなことができたらしいけどこれも今では使えないし(Bash 3.xで削除?)。 需要がないのかな やっぱり >>48 できるよ。gettext.shってのが用意されてる。 ライブラリになっていて、おそらくパスも通ってるはずだから . gettext.shで読み込めるはず。 そしてeval_gettext関数を使って翻訳するわけだが、 http://www.nofuture.tv/diary/20130329.html の記事を見ると > echo "$(eval_gettext "hello world")" と書いてあるな? eval_gettext "hello world" だけじゃだめなんだろうか? 一般的には等価だし、これだけでもメッセージの抜き出しはできるはず なにより"$(・・・)"を使うとforkが行われるから WSLで遅くなることが懸念される そのうち使うことになるとは思ってるが、まだ試してないのでよろしくw >>48 え?これできないの? http://www.unixuser.org/ ~ysjj/bash_script_i18n.html しかし Linux の bash の man ページには $"string" あるなあ。 https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html だからセキュリティの理由により非推奨になったって書いてあるやん 一つ上のレスぐらい読もうよ なんか俺は勘違いしたかもしれん、 >>52 は無視してくれ >>52 それで恥をかくのは読んでない人なわけで 自業自得だけどな >>51 今見た。元々リロード忘れて一つ上が見えない状態で書いてたのと、見えた後でリンク先見てなかったのでセキュリティの都合で非推奨になった事に気づかなかった。 でも非推奨ってことは使えないこともないのかな?だからmanページには残ってるとか?使わん方が良いことには変わりはないだろうが。 > この方法はセキュリティ上の問題(シフトJISや中国語のエンコーディングではダブルクォーテーションを無効にできてしまうなど。 というような、ASCIIと互換性がない文字コードによる問題だから そういう文字コード自体を非推奨として対応から外せたら良いのに Unicode以外の文字コードが絶滅するのはいつになるんだろうな shebangって書かないほうがいいのかもな。 > If the first line of a file of shell commands starts with the characters "#!", > the results are unspecified ---http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html だそうだし > One common historical implementation is that > the execl(), execv(), execle(), and execve() functions > return an [ENOEXEC] error for any file not recognizable as executable, including a shell script. > When the execlp() and execvp() functions encounter such a file, > they assume the file to be a shell script > and invoke a known command interpreter to interpret such files. > This is now required by POSIX.1-2017. ---http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html#tag_16_111_08 だし。 それは誤読だろ。 execveとかにシェルスクリプト渡したらどうなるか知らん、 execlpとか使えってことでしょ。 実装としてどっちで#!を解釈するかはOSに任せられている。 shebangって書かないほうがいいんじゃないかって話は どこかの誰かがまとめてただろ 書かなくて良いんじゃないかと思うが 書かないとshellcheckが警告出すんだよな。 パラメータじゃない方法でシェルを指定する方法があれば良いんだが >>60 > shebangって書かないほうがいいんじゃないかって話はどこかの誰かがまとめてただろ 読んでみたい ったく、そっちじゃねーよ https://togetter.com/li/1077808 簡単にまとめるとだな。Androidでは sh は /bin/sh に存在しない /system/bin/sh だから、どちらでも通じるシバンは書けない なら書かなくて良いのでは? → そのとおり。POSIXではシバンがなければshで起動されると明記されてる (注意 ログインシェルとしてcshを使用してる場合、先頭一文字目が# つまりコメント行だったらcshで起動されるので:コマンドなどで無効化する cshはファイルの先頭が#でなければPOSIX shで起動する) ちなみに bash$ cat ./sbtest.sh ps -o comm= $$ bash$ ./sbtest.sh bash ↑↑ Bashじゃねーか っていう罠もある。 ちょっと質問です。 プログラムが終了していたら再起動し、20秒以上動いていたら強制終了させて再起動したい。 どう書けばいいですか? >>65 そうだなあ。Linuxとかならkillでシグナル番号0を送ると指定のプロセスの生死を確認できるのでそれ利用して作るかな。 しかしその場合は動いているプロセスのPIDがわからないとダメだ。これがわからない状態でやらねばならない場合はpsの出力にgrepして探すかな。 > プログラムが終了していたら再起動し、 親シェルスクリプト(プログラム)作ってループ起動 例えばcronの5分間隔とかにすると隙間が開く可能性がある > 20秒以上動いていたら強制終了させて再起動したい。 監視シェルスクリプト(プログラム)作る 起動させた時間はpsコマンドで分かる 今の時刻はdateコマンドで分かる 強制終了はkillコマンドでできる 監視の間隔(チェックを何分おきにやるか)は自分で決める 例えば1分間隔で監視したら最悪60秒以上動く場合がある waitしないループは結構CPUに負荷をかけるから注意 こんな感じかねぇ プログラム名からプロセスIDを取得して変数に入れる while :; do psコマンドでプロセスID変数の起動時間取得 if 取得できたら; then if 20秒以上経過していたら; then kill プロセスID fi else # 取得できなかったら プログラム起動 & 新たなプロセスIDを変数に入れる fi sleep 1 done setコマンドで変数一覧が見れる機能の使い道にやっと気づいた man bashにはこうある > オプションなしの場合は、シェル変数全ての名前と値の組が表示されます。 > 表示は、現在設定されている変数を設定や再設定をする入力 として > 再利用できるフォーマットで行われます。 ようは変数のシリアライズとデシリアライズだよなーと思ってた でもそうだとすると普通は特定の変数のみシリアライズ&デシリアライズしたいわけで 全部だされても困る。指定された変数だけ表示できないのか? 変数の中には改行が含まれることもあるから、絞り込むのも大変だぞ ちなみになんのために俺がsetを調べていたかと言うと、サブシェルの中から 変数の値を返す方法はないものかと(再度)調べていた。 いわゆるwhile read の中で行数数えても、変数は元に戻る問題な i=0 cat /etc/hosts | while read line; do i=$((i+1)) done echo $i # whileがサブシェルで実行されるからもとに戻る この解決方法として、echoでevalできる形の文字列を返してサブシェルの外で evalするやり方。このテクニックは最近俺の中で常識となっていた。 でもな、setでevalできる文字を返せるのはわかる。だが欲しいのは変数 i だけなんだよ! set使えねーなって思ってた。 頭が硬かった。setで表示されたものすべてをevalすりゃいいんや。 サブシェルの中の変数は、サブシェルの外を引き継いてるんだから変えない限り同じ。 evalしても変わらない。いちいち必要なものだけechoする必要なかったんや 長文乙w つーわけで、サブシェルの中から変数を返す方法 汎用版 i=0 eval "$(cat /etc/hosts | { while read line; do i=$((i+1)) done set })" echo $i # 俺の環境では11だった set呼ぶだけで、簡単に変数返せるぞ ちなみにbashとかだとデフォルトでは関数まで返しちゃうので注意な シェルスクリプトじゃないんだけど Makefileのファイル名(例えばGNUMakefileだったりmakefileだったりするよね) を取得したりってできる? つまり $ cat ./Makefile all: >---echo $0 $ make Makefile みたいな。もちろんMakefileはshが解釈しないんで, $0を使うことはできないけど。 追記 GNU makeなら$(MAKEFILE_LIST)が使えるらしいがFreeBSDでも使いたいんだよね…… MAKEFILE_LIST https://www.freebsd.org/cgi/man.cgi?query=make& ;apropos=0&sektion=0&manpath=FreeBSD+6.2-RELEASE&format=html all: @echo $(lastword $(MAKEFILE_LIST)) とか。 ああ、>>74 はめっちゃ古いのか .MAKE.MAKEFILES https://www.freebsd.org/cgi/man.cgi?query=make& ;apropos=0&sektion=0&manpath=FreeBSD+11.2-RELEASE&arch=default&format=html 今度は試してみたが確かにっぽい >>70 なんでcatがいるの? catなくせば苦労しないんじゃないの? >>78 catはただの一例にすぎん。そこは本質ではない。 サブシェルの中の変数を、サブシェルの呼び出し元に 戻す方法の話をしてる もう少し見やすく、汎用的な書き方をするとこんな感じかな サブシェル(change_vars)内で追加や変更した変数を すべてサブシェルの親に返す方法 # もちろん例 change_vars() { i=123; } eval "$(somecommand | { change_vars; set; })" echo $i 実際には変更してないものすべてを再代入してるわけだが それを行った所で問題はない。 ただしreadonlyを使ってると代入できなくてエラーになる。 これはなにかいい回避策はないだろうか readonlyになってる変数一覧はreadonly -pで取得できる その結果をパースしてごにゃごにゃやればできるんだろうけど、 readonly -pの結果が、 bashだと declare -r a="1" dashだと readonly a='1' と異なるのでパースが面倒くさい上に、 変数名がわかったからといってどうするのだ?問題がある サブシェル内でもreadonlyだからunsetできない。 setをパースして消すのは改行文字とかの対応で面倒 エラーを無視しようにもうまくいかない 詰んだw "Field with Space" "Second Field" ... みたいなフィールの連続に対して一番初めのフィールドを取得したいんだけど なんかいい方法ない? ただしフィールドのなかに特殊な文字は含まれないし、「"」記号もフィールを区別する目的以外には使われてない。 これコマンドに渡す引数の形と似てるから$1とか上手く利用したらいい感じの処理ができそうなんだけど 思い付かん……。 ちゃんとフールって書けよw こんな感じだな line='"Field with Space" "Second Field"' echo $line # 関数呼び出し foo() { echo "foo1: $1" echo "foo2: $2" } eval fool $line # または eval set -- $line echo "set1: $1" echo "set2: $2" もちろんeval使ってるので、入力データが安全であることが前提 あとは1文字ずつパースして処理するとか あーやっぱり変数に代入する感じか。 (データが安全なのは保証されてるんだけど 長いんだよね) でもありがとう。とりあえずそれで行く。 変数というか、$1, $2, ... だけど 変数($1等含む)に入れないでどうやれとw 標準入力? いや 結局変数に入れることと一緒なんだけど $ echo '"Field with Space" "Second Field"' | { eval set -- "$(cat -)"; echo $1; } みたいにしてみた。というのは実際のデータは標準出力から流れてくるから できるだけパイプで処理したいなというのがあった。 いずれにせよeval setなんて思い付きもしなかったんで むちゃくちゃ感謝してる。 難癖を付けてる訳ではないよ。いやマジで。 >>87 別に気分悪くしたとかじゃなくて、 なにか処理するなら結局変数に入れるよなーってだけだよ 標準入力からでもreadで変数に入れるわけだし 最近eval多用してる。もちろんそれがどうしても必要だからだけど 特に速度が遅くなるわけでもないし色々と便利 丁寧な回答をもらっておいて「でも」「とりあえず」は失礼だろう 「お前の回答はイマイチだが時間もないし採用してやるか」という感じかな? >>70 それ set じゃなくて最後に echo i=$i だけで良いのでは? >>94 だから汎用的な解だってばw 変数が複数あっても対応できるし 変数の中にエスケープが必要な文字があっても対応できる あ、これに関して良いアイデアが浮かんできた。気がするw https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#compact こういうのとかもすっげえ便利だよね。 $ VAR=val; echo ${VAR@A} VAR='val' でも新しい機能なのか,日本語版のマニュアルに掲載されてない。 (まあ俺はPOSIXに準拠したほうがいいと思ってるので,こういう機能は それこそ一時的な使い捨てスクリプトにしか使わんけど) >>97 それCentOS7に入ってるbashではエラーになる。 新しい機能だな。 >>99 メディアタイプの種類自体は標準化されていたとしても、 あるファイルがどのメディアタイプかってのは決まらないでしょ? 拡張子cgiのスクリプトファイルだって、ソースコード配布サイトなら テキストファイル扱いにしたいだろうし ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる