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

0001名無しさん@お腹いっぱい。2018/08/02(木) 05:22:16.82
シェルスクリプトの総合スレです。
□お約束
・特記なき場合は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/

0570名無しさん@お腹いっぱい。2022/08/02(火) 17:31:23.07
POSIX準拠が当たり前、
POSIXにはない/POSIXで足らない勝手に拡張部分で独自が当たり前
って当たり前がわからないんだろな

拡張するにしてもPOSIXをベース+αって馬鹿でもわかりそうなもんだが
機能的に必要最低限のPOSIXを無視する利益なんてないだろに

0571名無しさん@お腹いっぱい。2022/08/02(火) 19:09:16.74
POSIXを無視する利益は互換性でしょ?
今までの動きを変えたらだめ

0572名無しさん@お腹いっぱい。2022/08/02(火) 20:31:00.79
>POSIXを無視する利益は互換性
www
>今までの動きを変えたらだめ
前段からそれになるとか無茶苦茶
POSIXの経緯、POSIXは何をベースに作られたか勉強してきてから寝言言うんだよ

0573名無しさん@お腹いっぱい。2022/08/03(水) 09:45:22.85
皆様ありがとうございました。シェルはbashです。
名前順的に最後のファイル名を得るには
for filename in * ; do
:
done
とするしかないようですね。
でもKDEのDolphineの自然なソート(ゼロパディング分の0を無視)のようなオプションは欲しいかも

0574名無しさん@お腹いっぱい。2022/08/03(水) 14:26:27.63
>>573
> 名前順的に最後のファイル名を得るには
普通に
ls -r | head -1
でよくね?

0575名無しさん@お腹いっぱい。2022/08/03(水) 20:32:58.41
>>572
何をベースにってBSDベースでしょ?
SolarisとかはSystemVベースだからtrコマンドの挙動が違う
互換性を重視してPOSIXを無視してる

0576名無しさん@お腹いっぱい。2022/08/03(水) 20:34:34.24
https://qiita.com/richmikan@github/items/bd4b21cf1fe503ab2e5c#tr%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89

> POSIXに準拠してないSystem V実装が悪いと言ってしまえばそれまでなのだが、
> 歴史の上ではPOSIXよりも早いのでそれをいうのもまた理不尽というもの。ではどうすればいいか。

0577名無しさん@お腹いっぱい。2022/08/04(木) 09:47:52.75
>>572
おら。ちゃんとPOSIXの経緯調べてきたか?
黙ってないでなんとかいえや

0578名無しさん@お腹いっぱい。2022/08/05(金) 10:23:52.72
>>573
sh ではできるだけパイプで処理することを考えるんだ
もちろん for, while などが必要な局面はあるが
パイプで済むなら速くて簡潔でフィルターとして組み合わせられる

0579名無しさん@お腹いっぱい。2022/08/05(金) 10:46:42.12
>>578
ファイル名に改行が入る場合はどうすればいいのでしょうか?

0580名無しさん@お腹いっぱい。2022/08/08(月) 18:30:05.02
自分ならまずそういうアホなファイル名を変更するが
権限がなければまあ
find -print0 | xargs -0
くらいだな

0581名無しさん@お腹いっぱい。2022/08/08(月) 21:06:49.38
>>580
POSIX準拠じゃないので
FreeBSDで動きませんw

0582名無しさん@お腹いっぱい。2022/08/14(日) 20:39:40.32
POSIX準拠じゃなくてもFreeBSDで動くけどな
POSIXにないのでも、ツール間で合わせ合う、どっちかがどっちかに似せるというのは普通にあるしな

0583名無しさん@お腹いっぱい。2022/08/14(日) 21:19:42.49
POSIXにないオプションは使用禁止だ
そんなものを使うと持続性がなくなる
なんらかの理由で別のOSに変更になった時
システムは動かなくなってデータはただのゴミになる
何度言えば理解できるのか

0584名無しさん@お腹いっぱい。2022/08/15(月) 12:57:39.48
はいはい、原理主義ごくろうさん
使ってる本人次第でしかないのに押し付けとかホント原理主義者は

0585名無しさん@お腹いっぱい。2022/08/15(月) 13:03:07.61
原理主義者は自惚れてるけど無知さがだだ漏れる
無知さを隠す誤魔化すためのマウント取りでしかない

0586名無しさん@お腹いっぱい。2022/08/15(月) 13:26:13.07
リッチー大佐はC言語も使える
ただし分割コンパイルやmakeといった高度な機能は使わない
そんなものはなくてもシェルスクリプトでmake.shを作れば良いからだ

0587名無しさん@お腹いっぱい。2022/08/15(月) 13:28:32.48
>>581
pkg install findutils

0588名無しさん@お腹いっぱい。2022/08/15(月) 14:25:12.28
それ入れなくてもFreeBSDのfindで可能だけどな
がっつりGNU依存のにしても、それ入れる+ちょっとパス修正だけだわな

0589名無しさん@お腹いっぱい。2022/08/15(月) 16:04:55.82
BSDのfindなら
find 場所 -print0 | xargs -0

0590名無しさん@お腹いっぱい。2022/08/15(月) 20:36:03.11
持続性なら、もはやPOSIXよりも、Linuxのほうがいいのでは。

0591名無しさん@お腹いっぱい。2022/08/16(火) 12:18:54.66
posixってソフトウェア規格でしょ?

0592名無しさん@お腹いっぱい。2022/08/16(火) 12:28:09.90
ソフトウェア規格って?
公式ページでも見れば?

0593名無しさん@お腹いっぱい。2022/09/19(月) 12:12:56.52
bashの関数で文字列を返したい場合、その関数名を文字列名称に使うことは仕様的に可能ですか?
function kotae () {
kotae=$1$2
}
kotae ab cd
echo $kotae

0594名無しさん@お腹いっぱい。2022/09/23(金) 09:54:01.90
>>593
関数と変数の名前空間は別なので別に構わない、そして宣言(declare)してなければ変数concはグローバル
ややこしいのでそういう使い方のおすすめはしない

0595名無しさん@お腹いっぱい。2022/09/23(金) 09:55:09.11
concはkotaeの間違い
頭の中で勝手に命名しちゃった

0596名無しさん@お腹いっぱい。2022/09/24(土) 14:46:59.72
>>593
そのようなことをしたい場合はこうする

function kotae () {
printf -v $1 "%s" $2$3
}
kotae ret ab cd
echo $ret

0597名無しさん@お腹いっぱい。2022/10/28(金) 02:25:37.28
bash 5.2.2(1)で最初の!だけ全角の
echo "abc!? xyz!"
は通るのに、半角にすると
echo "abcecho "abc!? xyz!"
>
になってしまいます。
一対の"で通すにはどうすればいいのでしょうか?

>>594-596
ありがとうございます。
printfのvオプションは初めて知りました。

0598名無しさん@お腹いっぱい。2022/10/28(金) 13:13:38.41
ヒストリ機能
知らない/活用してないならオフにしておくべき
対話モードでしか機能しないから切っても特に問題はない

0599名無しさん@お腹いっぱい。2022/10/29(土) 10:43:22.22
バックスラッシュをつけてエスケープ。

0600名無しさん@お腹いっぱい。2022/11/06(日) 16:47:34.57
恥を忍んで質問させて下さい:
Larry Wallせんせーが書いたmetaconfigが普及せずに、同じ機能を果たす、
Autoconf/Autotoolsが普及した理由って何でしょう?
1)Perlよりm4の方が普及してた(どっちも文法はアレだけど)
2)というかPerl嫌いな人が少なくなかった
3)そのほか(開発モデルとか)

...imakeって何だっけ?

0601名無しさん@お腹いっぱい。2022/11/06(日) 18:24:19.31
Autoconf/AutotoolsはGNUだからじゃね?しらんけど

0602名無しさん@お腹いっぱい。2022/11/07(月) 01:26:02.31
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]

0603名無しさん@お腹いっぱい。2022/11/07(月) 06:20:59.25
6行以上書いたからじゃね?

0604名無しさん@お腹いっぱい。2022/11/07(月) 07:38:39.12
>>602
クライアントからの接続要求の処理中に次の接続要求が来たら待たせるようになっててそのバッファが5個だからそれ以上に次々と接続要求きたらConnection refusedを返すようになってる
少し時間を空ければ大丈夫なはず
てか、サーバーは何?

06056022022/11/07(月) 11:40:12.51
>>604
ありがとうございます。そうでしたか。
コマンドの内容と関係無さそうだったので迷いました。
接続先のサーバーは自宅のraspiです。

0606名無しさん@お腹いっぱい。2022/11/08(火) 09:01:57.74
もしかしてファイル転送を多重化しようとしてるのかな そういうオプションがあったような気がするけどね rsync

0607名無しさん@お腹いっぱい。2022/11/08(火) 23:15:42.53
はい、ぶたがみーるー
まあ、ここにも俺がいるわけですけどねw

0608名無しさん@お腹いっぱい。2023/03/27(月) 06:41:34.11
バックしまーす

0609名無しさん@お腹いっぱい。2023/06/18(日) 23:35:36.05
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:その他': 有効な識別子ではありません
とエラーになるのですが、どうすればいいでしょうか?

0610名無しさん@お腹いっぱい。2023/06/19(月) 06:14:08.74
-p に渡っているのは " [Yes/No" だけで、残りの "$1" と "]: " は yn と同じく変数名として解釈されている

read -p " [Yes/No $1 ]: " yn

0611名無しさん@お腹いっぱい。2023/06/23(金) 17:18:03.40
テスト

0612名無しさん@お腹いっぱい。2023/08/23(水) 21:31:25.96
これってどうしてそうなのだろう?

0613名無しさん@お腹いっぱい。2023/08/27(日) 18:57:22.73
readコマンドの引数にダブルクォートを使ってるからだぬ
だから>>610氏が指摘しているコトになってるぬ

0614名無しさん@お腹いっぱい。2024/02/20(火) 08:47:58.81
先にBを算出することもなく変数の追加もなしで処理2を1箇所にすることは可能でしょうか?
if [ A ]; then
Bを算出
if [ B ]; then
 処理1
else
 処理2
fi
処理2
fi

0615名無しさん@お腹いっぱい。2024/02/20(火) 14:15:04.07
2度目のエルスを書かなければいいだけじゃなくて?

0616名無しさん@お腹いっぱい。2024/02/20(火) 17:32:39.42
>>615
「処理2」は2度処理される必要があるのかもしれん。例えば、ステータスを1 upするような。

出題者はおそらくelse節を冗長処理として、1度きりの処理の意味で「1箇所にする」と要件を定義したのだろう。
が、現実にこんなアバウト野郎のかもす空気を読んでウカウカとelse節を削ると、分かりにくいバグになったりする。

なので、問題を正確に記述しろ糞ボケと回答すべきだと思う。

0617名無しさん@お腹いっぱい。2024/02/22(木) 06:05:52.23
>>614
else 足りなくね
処理2を1度または2度実行するのに、1箇所にしたいとかイミフ

!Aだったら処理2をする つもりなら、そのまま書けばいいだけだな。シェルスクリプトならw
Bを前もって算出できるなら、[ A -a B ] って本人も分かってるだろうが、Bを算出することもなくでも、そのまま書こうと思えばかけるわな、 [ A -a { Bを算出; B; } ] 風に

0618名無しさん@お腹いっぱい。2024/02/22(木) 18:42:19.24
{ ifを何重にもネストしたブロック } || 処理2
みたいなのでも

0619名無しさん@お腹いっぱい。2024/03/14(木) 17:20:13.74
while ...do
処理1
done <<=LIST=
リスト1
=LIST=

while ...do
処理2
done <<=LIST=
リスト1
=LIST=

てののリスト1を一つにできんべか。ただし、リスト1全てに対し処理1をし終えてから処理2を行なう必要があるので、

while ...do
処理1
処理2
done <<=LIST=

ではあかん。

0620名無しさん@お腹いっぱい。2024/03/14(木) 18:05:33.59
ヒアドキュメントの中で変数を展開できます。

LIST_CONTENT="リスト1
...
"

while read s; do
printf '%s\n' "${s}"
done <<LIST
${LIST_CONTENT}"
LIST

新着レスの表示
レスを投稿する