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

レス数が900を超えています。1000を超えると表示できなくなるよ。
2019/10/25(金) 00:08:45.53ID:6btPTvif
シェルスクリプトに関する総合スレッドです。

全般
・荒しは無視しましょう。
・丁寧な姿勢を心掛けましょう。
・ネチケット(死語)を意識しましょう。
・「○○(他の言語)でいいやん」は禁止。他のスレに行ってください。

シェルスクリプト総合 その31
https://mevius.5ch.net/test/read.cgi/tech/1565446670/
2020/03/10(火) 08:08:24.53ID:oWfapBN9
>>827
勉強中でどうすればいいかわからなくて色々試してる最中です
if [[ $filepath = *.txt ]]; then
[[]]としたら出来ました
files="/Users/aaa/Documents/*.txt"
こうしたらcaseもifも不要でシンプルに出来ました
>>828
勉強になります。ありがとうございます
2020/03/10(火) 10:13:09.27ID:KDNpqv0e
>>828
なんでそんなにifにこだわるんだろうかね

if [ "${filepath##*.}" = "txt" ]; then
case $filepath in *.txt)
if [[ $filepath = *.txt ]]; then

どれがシンプルかは比べてみれば明らかだろうに

caseはcase一つで実現しているが、ifは別途 [ または [[ を
組み合わせてるから無駄な処理を行ってるんだが
文字数も長いし、[[はbash依存

パターンマッチングをcaseからifに置き換えても
文字を長くして無駄な処理を行って動くシェルを減らしているだけで
メリットが一つもない
2020/03/10(火) 16:38:10.67ID:HVuW4BfF
一つだけなのにcaseを使うのが気持ち悪い、判断パターンをcaseの後に書くのが気持ち悪いという感性の問題だな
どの感性が良い悪いというのではく。コーディング規約が一つにならないのと同じような
お前は俺のコーディング規約が絶対と言って譲らないのと同じ
2020/03/10(火) 22:41:26.01ID:DGocRqod
コーディング規約と漠然にいってるけどその内容には二種類あって、
一つは「理由がある良いやり方」と
もう一つは「どちらでも良いけど統一しましょう」というだけのもの

理由があるものはどちらが良いか明確に言うことができる。
明確に言えないものはインデントのスペースを2にするか4にするかという
統一だけするもの。コーディング規約にはこの二つが混じっているから、
良いか悪いかの話ができるものまで、好みの話だと勘違いしてる。

感性が邪魔して良い方法を採用することが出来ないという気持ちはわかるが
今回は明らかにcaseを使ったほうが良い。他にifの方がいい理由があれば
トレードオフの話に持っていけるが
2020/03/11(水) 02:59:38.62ID:nI7VA1ob
しつこい
2020/03/11(水) 03:56:24.84ID:arwb9WsV
俺様が決めたコーディング規約に従えねぇってかごるぁ
ということを言いたいんだろうな。caseは正義なんだと。
2020/03/11(水) 04:45:38.32ID:ZeFz9OTM
承認欲求のひとつだろな
2020/03/11(水) 09:22:15.60ID:FWSDJbu9
>>834
コーディング規約の話なんかしてないだろ?
この場合は、caseの方が優れてるのに
ifを使いたいという"感性"を持ち出してきたアホが居るだけ
そのアホがコーディング規約がーとか意味不明なことを言ってるだけ
2020/03/11(水) 09:32:31.50ID:FWSDJbu9
この場合はcaseが優れてるね

case使えって言った!こいつどんなときでもcase使えって言った!
理由はコーディング規約だからそれに従えだって!


誰もそんなこと言ってないんだよなぁ(笑)
なんで優れてるかどうかの話をすり替えたんだろうね
2020/03/11(水) 09:35:24.46ID:arwb9WsV
>>836-837
>>833読んだ?
2020/03/11(水) 10:04:34.79ID:FWSDJbu9
>>838
自分がしつこいから、レスが来てるって思わない?w
2020/03/11(水) 10:35:05.80ID:9AoZOnAU
>>829を読むとcaseもifも使わないでシンプルに出来たと言っていて、本人はifになんか全然拘っていないんだよな。何故か勝手にしつこく敵視してる笑。
2020/03/11(水) 10:40:57.60ID:FWSDJbu9
敵視してるのは>>831だぞw
2020/03/11(水) 15:58:19.41ID:6PQL09wH
これがアスベというのだな
2020/03/11(水) 18:51:36.11ID:6kL2fYSe
無駄なcat的な何か
2020/03/14(土) 09:40:09.35ID:H7XbSJpX
知らんかったけど、こんな書き方できるんやな

cat << HERE |
abc
HERE
sed s/a/b/g

cat <<HERE &&
abc
HERE
echo abc

謎な書き方多すぎw
2020/03/14(土) 09:44:21.77ID:H7XbSJpX
cat <<HERE && cat<<HERE
aaa
HERE
bbb
HERE

わろたw
これも動くんだ
2020/03/14(土) 11:50:07.06ID:9+oeBXql
zshだとOKだけどbashだけど文法エラーになるものってあるかな?

例えばbashだとOKだけど、shでは文法エラーになるものに配列がある。

$ bash -cn 'a=()'
$ sh -cn 'a=()'
sh: 1: Syntax error: "(" unexpected

これのzsh版
2020/03/14(土) 11:52:32.93ID:9+oeBXql
ただしこれは除く

$ bash -cn 'foo() :'
bash: -c: 行 0: 予期しないトークン `:' 周辺に構文エラーがあります
bash: -c: 行 0: `foo() :'

これはshでは通る。POSIX準拠の構文なはず。だけどbashが通らない珍しい例
$ sh -cn 'foo() :'
848デフォルトの名無しさん
垢版 |
2020/03/14(土) 15:19:53.15ID:4q4RZYWz
環境はMac mojave、lsとecho $(ls)とで挙動が違うのってなんででしょうか
前者はスペースや改行がしっかりされてるんですが後者は整形されませんでした
2020/03/14(土) 15:51:10.82ID:ILPzjwAA
lsは出力先によってオプションを指定しない場合のdefault formatが変わる
そういう仕様
2020/03/14(土) 16:50:55.95ID:cW1wo+Y7
>>848
echoなんぞに引数で渡す場合は、引数として渡すために分割されてるからじゃね。逆に整形されてるとも言える
echo "$(ls)"
(IFS=''; echo $(ls))
だと同じくならなくね?
2020/03/14(土) 17:16:06.25ID:aw8SOrjK
>>848
echoは複数の引数を(IFSの値とは関係なく)
スペースで区切ってくっつけるという仕様だから
2020/03/14(土) 17:30:36.50ID:ILPzjwAA
$ echo "$(export COLUMNS=159; export CLICOLOR_FORCE=1; ls -C)"
これでlsだけの時と同じ出力になった
2020/03/14(土) 17:34:32.34ID:aw8SOrjK
それは一つの引数の中に改行があるからな

別の問題として最後に複数の改行があっても一つにまとまるから
厳密には同じではない
2020/03/14(土) 17:48:52.56ID:Qg6b8RMl
なにいってるの
2020/03/14(土) 17:52:54.94ID:aw8SOrjK
正しいことを言ってる
2020/03/14(土) 17:55:17.78ID:Qg6b8RMl
変わったやつなのはわかった
2020/03/14(土) 17:56:25.94ID:aw8SOrjK
教えてほしいなら、何を教えればいいか具体的に言おうねw
質問者のくせに
2020/03/14(土) 17:58:01.23ID:Qg6b8RMl
おかしなやつだったか
2020/03/14(土) 18:01:56.55ID:aw8SOrjK
まーた始まった
2020/03/14(土) 18:20:00.64ID:tUDMKnWI
お前がな
2020/03/14(土) 21:45:32.98ID:fgvgQcum
>>844
その仕様は Perl にも受け継がれてるよ。
2020/03/14(土) 23:56:32.86ID:9VuyfYoc
echo は、連続した空白を、1つにまとめる
2020/03/15(日) 00:05:16.78ID:7lggs81n
$ echo " foo bar " " baz qux"
__foo__bar_____baz__qux

空白まとまらないけど、なんの話をしてるの?
2020/03/15(日) 00:13:30.80ID:1+6iz56B
$ echo " foo bar " " baz qux"
_foo_bar___baz_qux

って事を言ってるんじゃないかな
2020/03/15(日) 00:16:12.28ID:1+6iz56B
あららw "_" をスペースに読み換えて頂戴

$ echo " foo bar "_____________" baz qux"
_foo_bar___baz_qux
2020/03/15(日) 01:09:56.98ID:7lggs81n
マジか!?
それechoとは関係ないよね
2020/03/15(日) 03:22:11.24ID:DhvkTO6y
やってるのはシェルだよな
2020/03/15(日) 09:50:54.32ID:4Gm4pJRZ
せっかく俺が、複数の引数をっていってんのに
2020/03/15(日) 10:12:42.77ID:IC7rc7YS
>>862はいつものRuby君だろ。相変わらずデタラメを垂れ流してるな。
2020/03/15(日) 12:24:19.50ID:ekOFLY9+
exprの正規表現関連の機能って便利だな。
恥かしながらPOSIXで定義されているとは思わず,
ずっとBash拡張だと思って利用を避けてきてたわw

sedだと変数の値に対しての操作が一発でできない(printf '%s' "$var"なんかを噛ませないといけない)
から、「変数に対して,指定した位置の文字を抜きだす」くらいの単純作業なら,
sedよりexprで処理した方がコマンドの個数も少なくなるし,よさげ。
2020/03/15(日) 13:45:49.67ID:4Gm4pJRZ
>>870
exprは外部コマンド、bashとは無関係
sedで変数もうさも、sedの代わりにexprも意味がわからない。
使い方が違うコマンド
2020/03/15(日) 17:46:54.09ID:ekOFLY9+
>>871
Bashとは無関係とはいっても
echoみたいにPOSIXでは「外部コマンド」とされてるけど
Bashでは組み込みコマンドで,かつ独自の拡張機能が備わっている。
みたいな場合も考えられる。
2020/03/15(日) 20:32:36.11ID:LgQopvr+
>>872
/bin/exprで使えばええ
2020/03/15(日) 21:16:13.77ID:ekOFLY9+
>>873
いや,別に「外部コマンドとしてのexprが使いたい」なんて言ってない。
2020/03/15(日) 21:39:15.64ID:UEcfE5Ac
伝わらなくてもどかしそうw
2020/03/15(日) 22:09:22.92ID:7377Zo4Z
>>872
exprがビルトインになってるシェルは存在しない
2020/03/15(日) 22:19:50.83ID:GTp/Qp/S
exprぐらいシェルのビルトインになっていてもおかしくない。ある意味思い込み
exprの正規表現関連はbashの拡張だと思っていた。exprがbashのビルトインしくはbashのオマケ外部コマンドなのが必須=完全な思い込み
というだけだろ。言いたいことはそこじゃないだろに、読み取ってやれよw
2020/03/15(日) 22:24:16.72ID:GTp/Qp/S
「Bash拡張」ではなく「GNU拡張」なんぞに置き換えればいいだけだな
2020/03/15(日) 22:30:33.87ID:7377Zo4Z
>>877
だからbashの拡張だと思っていたと言ってるから
そもそも外部コマンドだ。と言ってるだけなんだが
2020/03/15(日) 22:35:36.36ID:GTp/Qp/S
>>879
>>878

そこは蛇足
exprの正規表現関連はPOSIXじゃないと利用を避けてきたわ
で済むだけ。外部コマンドとか蛇足もいいとこな話だろう
2020/03/15(日) 22:42:53.24ID:7377Zo4Z
蛇足って話をするのなら、外部コマンドに反論すること自体が蛇足

そんなどうでもいいことじゃなくて、
sedでprintf '%s' "$var"とか言う意味不明な点を説明しろよ
変数の値に対しての操作が一発でできないのは「外部コマンド」ならどれも一緒だろ
2020/03/15(日) 22:48:02.29ID:GTp/Qp/S
思い込みの理由を述べただけと読んでやれよ。なんでそうも噛み付いているの?

sedにネタ元渡すためにはとかじゃないの?echoでもいいんじゃないの?ソコは
exprは対象を引数として渡せるぐらいの意味、動作及び返り値が単純だから変数をちょっとイジるくらいならsedよりもって話じゃないの。俺はそう読み取ったけど

なんでそうも強く噛み付いているの?
2020/03/15(日) 22:50:35.45ID:7377Zo4Z
> なんでそうも強く噛み付いているの?

噛み付いてないけど?俺はexprは外部コマンドと言っただけ
それ以外のことを言ってない。
過剰に反応してるのはお前では?
2020/03/15(日) 22:53:20.23ID:GTp/Qp/S
蛇足なことが続くなと思ったからだけど。蛇足な理由を言っただけだけど?
>>881なんて明らかに噛み付いているだろうにw 特に後半とか。よく言うよ
2020/03/15(日) 22:59:01.24ID:7377Zo4Z
後半?これ?蛇足(bash拡張かどうか)じゃなくて本筋の話をしろとしか書いてないが?

> sedでprintf '%s' "$var"とか言う意味不明な点を説明しろよ
> 変数の値に対しての操作が一発でできないのは「外部コマンド」ならどれも一緒だろ
2020/03/15(日) 23:07:40.57ID:9BnnGhWf
無茶苦茶だなとしか言いようがない
で、その応えは>>882で納得したのかね?合っているのか知らんけど、俺は一応そうは読めたからなあ、「意味不明な点を[説明しろよ]」とか何様なんだか何噛み付いているのかとしか思えない
2020/03/15(日) 23:29:41.29ID:ekOFLY9+
えぇ……なんでそうも喧嘩腰なんですかね……。
2020/03/15(日) 23:42:33.62ID:9BnnGhWf
わからん...性かなww
2020/03/15(日) 23:47:47.62ID:LgQopvr+
こんな所でしか他人に相手にして貰えないからでしょ?
2020/03/15(日) 23:50:43.81ID:9BnnGhWf
読めなさそうな人はそうかもねw
2020/03/15(日) 23:52:26.22ID:Uvpryj8C
>>870 を読んだ限りでは
「そうか、誤解してたのか。でもその誤解はもう解けたんだな。」
くらいにしか思わないけどなあ。
知らないみたいだから教えてやろうみたいな考えにはならないけどなあ。
2020/03/16(月) 05:03:15.13ID:OSNWgEHh
シンタックスエラーになるのに、問題なく実行できる例

shopt -s expand_aliases
alias loop=for
loop i; do
 echo "$i"
done

だからなんだって言われても困るけどwww
2020/03/16(月) 05:05:37.60ID:OSNWgEHh
キーワードを全部置き換えれば対象可能かな?

shopt -s expand_aliases

alias loop=for
alias begin=do
alias end=done

loop i; begin
 echo "$i"
end
2020/03/17(火) 01:19:59.84ID:tnhbC/l2
まだ初歩的なシェルスクリプトしか書けないがbashで一番変態的な記法ってなによ
空白を入れないfoo=barの時点で妙だし配列が括弧だらけでマンドクセとは思うが
2020/03/17(火) 02:44:04.56ID:DZYZalLc
さあなぁ、シェルスクリプトのコマンド=外部コマンド
だからファイル名につけられる文字や名前はすべて外部コマンド名として許されるべきだろうから
そうすると、やたらとコマンドを増やすわけにはいかないんだよね。

ABC = 123 とか書くと、ABCコマンドがあったらどうするんだ!?ってなるわけで、
ABC=123という風にファイル名にイコール使わないんじゃね?という前提にした
という理由があるから、そうなってるのわかるしなぁ。

ABC[123]とかいう外部コマンドだって作ろうと思えば作れるし

${aaaなんとか}シリーズが多いのも、既存の文法の拡張だけでやりたいからだろうし、
理由がわかれば、なっとくできるからなぁ。

んで、シェルスクリプトではそれ以外の拡張はしづらい運命にあるから、
逆に変態的な記法ってないで。変態な記法を作ろうと思っても作れない。
2020/03/17(火) 02:51:08.61ID:DZYZalLc
シェルスクリプトの欠点?というわけでもないが、
仕様としてコマンド置換は最後に連続する改行が消えるから
var=$(func 1 2 3) みたいな形で、便利な関数を追加するのが
難しいんだよね。最後の改行が消えるから

いろんな機能が${varなんとか}の形で提供されてるのは、
これなら変数の代入だから最後の改行が消ないから

変態的な記法というならこれかなぁ、配列もそうだし
何でもかんでも${varなんとか}という形で機能拡張が行われてる
最近の ${parameter@operator} とかね
2020/03/17(火) 14:49:49.69ID:+LpQdzFa
>>896
連続する改行が消えるのは、個人的には寧ろありがたい(整形しなくて済む)のだけれど
正確な出力が要求される場合には(例えば元のデータを可能な限り復元するとか)
面倒な仕様かもね。
2020/03/17(火) 20:33:42.42ID:WZhpPu/2
>>894
かっこがコマンドであるという点かなあ
2020/03/18(水) 01:29:14.04ID:9x4eFjJt
>>894
関数を一行で書く時の空白と;が割と初見殺し
func(){ echo foo;}
波括弧が予約語なんで開き括弧の空白と閉じ括弧の;が必須
改行時は不要だから結構ハマったわ
900デフォルトの名無しさん
垢版 |
2020/03/19(木) 09:42:42.24ID:+0MAARlE
exprについて教えてください。
現在tarで圧縮したファイルの末尾に数字をつける処理を使っています。
A=tarファイル名
B='expr = $A + 1'
tar czvf B 対象ファイル名
上の処理で実行すると、[整数でない引数]と表示されてしまい数字が付かないtarが出るのですが何故でしょうか。
2020/03/19(木) 09:47:58.88ID:YUAN2W2v
exprコマンドは廃止されました。
使ってはいけません。
2020/03/19(木) 10:02:09.16ID:QNV2kCYN
tarファイル名 が [整数でない引数] だからというその表示のまま
他にもツッコミどころがありすぎ
2020/03/19(木) 10:09:58.74ID:JDU05jIv
expr の四則演算は、整数しか使えないのかも。
こういう感じ

echo `expr 100 + 20`
#=> 120

まあ、expr で検索して!
2020/03/19(木) 10:25:57.68ID:YUAN2W2v
だからさぁ、整数の計算ごときで
expr使うなって
2020/03/19(木) 11:40:21.72ID:Ul0ojJdl
とりあえずでもいいだろ。俺は知ってるを押し付けすぎ
906デフォルトの名無しさん
垢版 |
2020/03/19(木) 12:30:37.63ID:awkeHjZR
>>902
数字じゃないとダメってことですか?
調べたのですが、普通に同じような書き方でテキストファイルに数字つけてる方がいたので参考にしたのですが…。
2020/03/19(木) 13:14:01.73ID:JDU05jIv
文字列の連結なら、普通に続けて書けばよい

a=xyz
b=${a}11

echo $b
#=> xyz11
908デフォルトの名無しさん
垢版 |
2020/03/19(木) 14:30:55.18ID:awkeHjZR
>>907
その例でいうと"11"が不明なのです。
tarを作成する際に同じ名前のtarがすでにあった場合は数字をつけたいんですよね。
すでに同一ファイル名があったら1をつける。
同一ファイル名1があったら2に変えるみたいな…。
名前の重複を避けたいのです
2020/03/19(木) 15:05:23.65ID:JDU05jIv
名前が重ならない、temp ファイルを使えば?
mktemp コマンドを利用して、ユニークな名前の一時ファイルを作成する

それか、ファイル名に、タイムスタンプを含めれば?

1 とか、2 を付けるのは難しい。
1があれば、2にして、
2もあれば、3にして、

こういうループは難しい
910909
垢版 |
2020/03/19(木) 15:12:34.38ID:JDU05jIv
mktemp【コマンド】とは

https://wa3.i-3-i.info/word12124.html
2020/03/19(木) 15:43:33.78ID:A3B3oNfE
>>908
プログラミング的なスクリプトを書かないとだめだろう
通番をつけるのは今何がつけられていて
その中での最大が何でそれにプラス1するって処理が必要で
複雑になるから通番なしのものがあれば
日時入れるのが妥当なのではないかな
912デフォルトの名無しさん
垢版 |
2020/03/19(木) 15:44:22.95ID:A3B3oNfE
ちなみにwgetであればオプションにもよるけど
ダウンロードしようとしてるファイルがすでにあれば
通番をつけるようになってるけどtarとかでは聞かない
2020/03/19(木) 16:37:23.68ID:Pzb6grX0
連番のH画像/動画を一気にダウンロードする7.5 [無断転載禁止]©2ch.net
http://mevius.5ch.net/test/read.cgi/unix/1459277070/
2020/03/19(木) 18:00:54.20ID:fgd/sgV0
ttps://qiita.com/tomiokario/items/a0b635d09995bb74503b

これを参考にしたのかな? まあ足してるの整数同士だけど。このまま試してみればいい
じゃん。ただ、機能するけどちょっと直さないと名前がおかしくなると思うたぶん。
2020/03/19(木) 18:26:31.73ID:A3B3oNfE
それとはちと違う
いや大幅に違う
2020/03/19(木) 18:49:11.91ID:CK8P50/C
ID:awkeHjZR が参考にしたのだろ
既存の最大の次でもない、単にあったら次だな、今までのレスからは
誰もが使うのだったら既存の最大の次の方が望ましいだろけど
2020/03/19(木) 19:05:06.03ID:CK8P50/C
ああ、最大にはなってるのか。いちおう
間に欠番があってはとか、というよりちょっとアレだなという、「大幅に違う」か(?)
2020/03/19(木) 19:11:21.47ID:CK8P50/C
あ、いや、やっぱ、あったら次なだけか
しつれい
919デフォルトの名無しさん
垢版 |
2020/03/19(木) 19:20:02.01ID:awkeHjZR
>>914
それを参考にしました。
よく見たら整数通しでしたね。
申し訳ありません…
2020/03/19(木) 22:46:59.86ID:0V5Z+nsf
A=tarファイル名
B="$A"
if [ -e "$B" ]; then
e="${B##*.}"; [ "$e" = "$B" ] && e='' || e=".$e"
B="${B%.*}"

x=0
for f in "$B"*$e; do
v="$(expr "${f%.*}" : '.*[^1-9]\([1-9][0-9]*$\)')"
[ "$v" -gt "$x" ] 2> /dev/null && x=$v
done
B="$B$((x+1))$e"
fi
echo tar czvf "$B" 対象ファイル名

Aが存在しない場合はそのまま、存在する場合は連番付きの最大+1
Aは拡張子付いていてもいい
風な
2020/03/19(木) 23:10:29.22ID:0V5Z+nsf
Aに拡張子ない場合、 for直下に
[ "$e" = '' ] && [ "${f##.*}" = "$f" ] && continue
とか必要か
拡張子抜きの名前の最大の場合はこれはいらず
for f in "$B"*; do
でいいはず
拡張子無いのだけを抽出するGLOBってあったかな?
2020/03/20(金) 01:41:19.99ID:3O1eG+VM
exprでの正規表現がよくわからない
何処かまとめてある所はありませんか?
2020/03/20(金) 06:24:37.20ID:v4UpLchp
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/expr.html#tag_20_42_13_01
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03

正規表現 BRE
などとググればたくさん。お好きなとこを
2020/03/20(金) 07:26:36.21ID:MAPSjPan
>>923
問題はそれに従ってないものが多いw
2020/03/20(金) 10:33:09.91ID:AIrE4YMP
BREで動かないってどこのexpr?
2020/03/20(金) 11:04:41.59ID:Cf4Df32C
ユーザ名パスワード受け取って、シェルスクリプト内でloginさせるような使い方って普通?

docker login -n ユーザ名 -p パスワード
docker run イメージ
みたいな
2020/03/20(金) 12:32:34.45ID:VFfjvmrc
windowsはtempでLinuxはtmp派だと思ってたがmktempなんてあるのか
2020/03/20(金) 15:01:17.57ID:b2ihZgLg
>>926
そういうのはCredential Storeを使う

シェルスクリプトのことだけで言えば
echoさせずにパスワード入力させてそれをreadするのが普通
コマンドに渡すやり方だと最低でも履歴に残らないような対処が必要
レス数が900を超えています。1000を超えると表示できなくなるよ。
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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