シェルスクリプト総合 その28
シェルスクリプトの総合スレです。 □お約束 ・特記なき場合はBourne Shell(/bin/sh)もしくはPOSIX準拠の互換シェルがデフォルトです。 bash/zsh/ksh/ash/dash/yash/poshなどの専用機能に依存する場合は明示しましょう。 Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。 FreeBSDユーザは/bin/shの正体がashなので注意。 ・POSIXについてのリンクは https://en.wikipedia.org/wiki/POSIX にまとめられています 最新の仕様はこちらへ http://pubs.opengroup.org/onlinepubs/9699919799/ (左上の「Shell & Utilities」 から参照することができます。) ・v7 shに一番近くて、現役(?)のshは、OpenSolaris由来のheirloom sh。 http://src.illumos.org/source/xref/illumos-gate/usr/src/cmd/sh/ http://heirloom.sourceforge.net/sh.html ・csh/tcshのシェルスクリプトは推奨されません。 (理由は「csh-whynot」でググれ) ・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。 manや参考リンクを見ましょう。 aproposないしはman -kでそれらしい単語による簡単な検索もできます。 ・シェルで使えるワイルドカード等は正規表現ではありません。 正規表現の話題はスレ違い(正規表現スレへ) ・シェルスクリプトのことをシェルってゆうな □初心者へのアドバイス: ・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも awkまたはperlの方が適した処理にはそちらを使いましょう。 ・知らないコマンドが出てきたらmanを引きましょう。 ・思い通りに動かないときは、まずは sh -x でトレースしましょう。 □回答者への注意事項: ・シェルスクリプトでの処理方法を質問しているのに、よくわからずに 「そういうのはperl使いましょう」と回答するのはやめましょう。 安易にperlに逃げずにシェルスクリプトで処理するのが頭のいいやり方。 質問に対して問題が間違ってるといちゃもんをつけるのもやめましょう シェルスクリプト総合 その27 https://mevius.5ch.net/test/read.cgi/unix/1525337663/ POSIX準拠が当たり前、 POSIXにはない/POSIXで足らない勝手に拡張部分で独自が当たり前 って当たり前がわからないんだろな 拡張するにしてもPOSIXをベース+αって馬鹿でもわかりそうなもんだが 機能的に必要最低限のPOSIXを無視する利益なんてないだろに POSIXを無視する利益は互換性でしょ? 今までの動きを変えたらだめ >POSIXを無視する利益は互換性 www >今までの動きを変えたらだめ 前段からそれになるとか無茶苦茶 POSIXの経緯、POSIXは何をベースに作られたか勉強してきてから寝言言うんだよ 皆様ありがとうございました。シェルはbashです。 名前順的に最後のファイル名を得るには for filename in * ; do : done とするしかないようですね。 でもKDEのDolphineの自然なソート(ゼロパディング分の0を無視)のようなオプションは欲しいかも >>573 > 名前順的に最後のファイル名を得るには 普通に ls -r | head -1 でよくね? >>572 何をベースにってBSDベースでしょ? SolarisとかはSystemVベースだからtrコマンドの挙動が違う 互換性を重視してPOSIXを無視してる >>572 おら。ちゃんとPOSIXの経緯調べてきたか? 黙ってないでなんとかいえや >>573 sh ではできるだけパイプで処理することを考えるんだ もちろん for, while などが必要な局面はあるが パイプで済むなら速くて簡潔でフィルターとして組み合わせられる >>578 ファイル名に改行が入る場合はどうすればいいのでしょうか? 自分ならまずそういうアホなファイル名を変更するが 権限がなければまあ find -print0 | xargs -0 くらいだな >>580 POSIX準拠じゃないので FreeBSDで動きませんw POSIX準拠じゃなくてもFreeBSDで動くけどな POSIXにないのでも、ツール間で合わせ合う、どっちかがどっちかに似せるというのは普通にあるしな POSIXにないオプションは使用禁止だ そんなものを使うと持続性がなくなる なんらかの理由で別のOSに変更になった時 システムは動かなくなってデータはただのゴミになる 何度言えば理解できるのか はいはい、原理主義ごくろうさん 使ってる本人次第でしかないのに押し付けとかホント原理主義者は 原理主義者は自惚れてるけど無知さがだだ漏れる 無知さを隠す誤魔化すためのマウント取りでしかない リッチー大佐はC言語も使える ただし分割コンパイルやmakeといった高度な機能は使わない そんなものはなくてもシェルスクリプトでmake.shを作れば良いからだ >>581 pkg install findutils それ入れなくてもFreeBSDのfindで可能だけどな がっつりGNU依存のにしても、それ入れる+ちょっとパス修正だけだわな BSDのfindなら find 場所 -print0 | xargs -0 持続性なら、もはやPOSIXよりも、Linuxのほうがいいのでは。 bashの関数で文字列を返したい場合、その関数名を文字列名称に使うことは仕様的に可能ですか? function kotae () { kotae=$1$2 } kotae ab cd echo $kotae >>593 関数と変数の名前空間は別なので別に構わない、そして宣言(declare)してなければ変数concはグローバル ややこしいのでそういう使い方のおすすめはしない concはkotaeの間違い 頭の中で勝手に命名しちゃった >>593 そのようなことをしたい場合はこうする function kotae () { printf -v $1 "%s" $2$3 } kotae ret ab cd echo $ret bash 5.2.2(1)で最初の!だけ全角の echo "abc!? xyz!" は通るのに、半角にすると echo "abcecho "abc!? xyz!" > になってしまいます。 一対の"で通すにはどうすればいいのでしょうか? >>594-596 ありがとうございます。 printfのvオプションは初めて知りました。 ヒストリ機能 知らない/活用してないならオフにしておくべき 対話モードでしか機能しないから切っても特に問題はない 恥を忍んで質問させて下さい: Larry Wallせんせーが書いたmetaconfigが普及せずに、同じ機能を果たす、 Autoconf/Autotoolsが普及した理由って何でしょう? 1)Perlよりm4の方が普及してた(どっちも文法はアレだけど) 2)というかPerl嫌いな人が少なくなかった 3)そのほか(開発モデルとか) ...imakeって何だっけ? Autoconf/AutotoolsはGNUだからじゃね?しらんけど rsync -avR -e ssh ... rsync -avR -e ssh ... このように6行以上書くとエラーになるんですがどうしてでしょう? ssh: connect to host xxxx: Connection refused rsync: connection unexpectedly closed (0 bytes received so far) [sender] rsync error: unexplained error (code 255) at io.c(228) [sender=3.2.3] >>602 クライアントからの接続要求の処理中に次の接続要求が来たら待たせるようになっててそのバッファが5個だからそれ以上に次々と接続要求きたらConnection refusedを返すようになってる 少し時間を空ければ大丈夫なはず てか、サーバーは何? >>604 ありがとうございます。そうでしたか。 コマンドの内容と関係無さそうだったので迷いました。 接続先のサーバーは自宅のraspiです。 もしかしてファイル転送を多重化しようとしてるのかな そういうオプションがあったような気がするけどね rsync はい、ぶたがみーるー まあ、ここにも俺がいるわけですけどねw function YesNo { local yn while true; do read -p " [Yes/No" "$1" "]: " yn case $yn in [Yy]*) return 0 ;; [Nn]*) return 1 ;; [Ee]*) if [ ! "$1" = "" ]; then return 2; fi ;; esac done } #main YesNo ":いいえ /Else:その他" echo $? exit 実行すると、read: `:いいえ /Else:その他': 有効な識別子ではありません とエラーになるのですが、どうすればいいでしょうか? -p に渡っているのは " [Yes/No" だけで、残りの "$1" と "]: " は yn と同じく変数名として解釈されている read -p " [Yes/No $1 ]: " yn readコマンドの引数にダブルクォートを使ってるからだぬ だから>>610 氏が指摘しているコトになってるぬ 先にBを算出することもなく変数の追加もなしで処理2を1箇所にすることは可能でしょうか? if [ A ]; then Bを算出 if [ B ]; then 処理1 else 処理2 fi 処理2 fi >>615 「処理2」は2度処理される必要があるのかもしれん。例えば、ステータスを1 upするような。 出題者はおそらくelse節を冗長処理として、1度きりの処理の意味で「1箇所にする」と要件を定義したのだろう。 が、現実にこんなアバウト野郎のかもす空気を読んでウカウカとelse節を削ると、分かりにくいバグになったりする。 なので、問題を正確に記述しろ糞ボケと回答すべきだと思う。 >>614 else 足りなくね 処理2を1度または2度実行するのに、1箇所にしたいとかイミフ !Aだったら処理2をする つもりなら、そのまま書けばいいだけだな。シェルスクリプトならw Bを前もって算出できるなら、[ A -a B ] って本人も分かってるだろうが、Bを算出することもなくでも、そのまま書こうと思えばかけるわな、 [ A -a { Bを算出; B; } ] 風に { ifを何重にもネストしたブロック } || 処理2 みたいなのでも while ...do 処理1 done <<=LIST= リスト1 =LIST= while ...do 処理2 done <<=LIST= リスト1 =LIST= てののリスト1を一つにできんべか。ただし、リスト1全てに対し処理1をし終えてから処理2を行なう必要があるので、 while ...do 処理1 処理2 done <<=LIST= ではあかん。 ヒアドキュメントの中で変数を展開できます。 LIST_CONTENT="リスト1 ... " while read s; do printf '%s\n' "${s}" done <<LIST ${LIST_CONTENT}" LIST read.cgi ver 07.4.7 2024/03/31 Walang Kapalit ★ | Donguri System Team 5ちゃんねる