シェルスクリプト総合 その20
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
2012/06/08(金) 00:35:51.19スクリプトのお勉強・自慢・腕試しなどにどうぞ。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
FreeBSDユーザは/bin/shの正体がashなので注意。
v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
http://heirloom.sourceforge.net/sh.html
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
前スレ
シェルスクリプト総合 その19
http://toro.2ch.net/test/read.cgi/unix/1323515200/
0172名無しさん@お腹いっぱい。
2012/06/26(火) 19:39:47.98そういう話はしてないだろ
0173名無しさん@お腹いっぱい。
2012/06/27(水) 20:34:48.42普通はどうやるものなのでしょうか?
例えば左シフトする演算をやるとすると、固定幅でない場合は面倒です。
計算後に一々固定幅に除算するのは速度的にどうかと思うし、
皆さんがどのような手段をとっているのか、おすすめの方法を教えて下さい。
0174名無しさん@お腹いっぱい。
2012/06/27(水) 20:35:48.090175名無しさん@お腹いっぱい。
2012/06/27(水) 20:56:11.44bashなら64bit(符号付)で固定幅だよ。
左シフトしてオーバーフローしたビットは自動的にカットされる。
$ echo $((0x7fffffffffffffff))
9223372036854775807
$ echo $((0x7fffffffffffffff<<1))
-2
$ echo $((0x7fffffffffffffff<<2))
-4
0176名無しさん@お腹いっぱい。
2012/06/27(水) 21:28:12.131.
bashが64bit幅(符号付)というのは、bashの仕様でしょうか?
それとも、事実上、それが基本になっている事が多いということでしょうか?
2.
32bit幅の固定幅bit演算、符号なしの論理演算をする時は、
やはり %0xFFFFFFFF 等と、演算を行った後に
適宜修正して計算するのが普通なのでしょうか?
0177名無しさん@お腹いっぱい。
2012/06/27(水) 23:10:24.880178名無しさん@お腹いっぱい。
2012/06/27(水) 23:11:20.590179名無しさん@お腹いっぱい。
2012/06/28(木) 07:54:55.060180名無しさん@お腹いっぱい。
2012/06/28(木) 10:56:16.200181名無しさん@お腹いっぱい。
2012/06/28(木) 10:59:29.130182名無しさん@お腹いっぱい。
2012/06/28(木) 11:03:12.480183名無しさん@お腹いっぱい。
2012/06/28(木) 11:27:39.660184名無しさん@お腹いっぱい。
2012/06/28(木) 11:28:26.830185名無しさん@お腹いっぱい。
2012/06/28(木) 13:34:47.48流れを読んでいないけど、
男なら黙ってmanだろ。
$ man -k loopback
lo(4) - software loopback network interface
0186名無しさん@お腹いっぱい。
2012/06/28(木) 13:37:43.27loopback: nothing appropriate.
$ man loopback
No manual entry for loopback
0187名無しさん@お腹いっぱい。
2012/06/28(木) 13:55:49.47シェルスクリプトとは別の話じゃないのか。
0188名無しさん@お腹いっぱい。
2012/06/28(木) 14:17:25.200189名無しさん@お腹いっぱい。
2012/06/28(木) 18:04:41.350190名無しさん@お腹いっぱい。
2012/06/28(木) 18:07:40.500191名無しさん@お腹いっぱい。
2012/06/29(金) 17:10:34.14それをコマンド引数に渡すってことをやってたんだけど
$ options="+profile '*'"
$ convert $options image1.jpg image2.jpg
bash 4.2でパラメータ中に*や'があると展開時にエスケープされるようになった
$ set -x
$ convert $options image1.jpg image2.jpg
+ convert +profile ''\''*'\''' image1.jpg image2.jpg
結局Arrayを使うことにしたんだけど
$ options=(+profile '*')
$ convert "${options[@]}" image1.jpg image2.jpg
これってbashのバグなんだろうか?それともANSIの仕様?
bashに特殊文字のエスケープやめさせる方法無いんだろうか?
こんなふうに複数のパラメーターを一気に渡そうって発想が横着なのかもしれないけど
だったらArray使わない移植性あって手軽な方法って無いのかな?
$ convert $(echo $options)
は思いついたけどなんか嫌だし、副作用もあるので
0192名無しさん@お腹いっぱい。
2012/06/30(土) 03:45:58.31$ ls
1.jpg 2.jpg
$ o="+p *"
$ echo $o
+p 1.jpg 2.jpg
$ echo "$o"
+p *
$ o="+p '*'"
$ echo $o
+p '*'
$ echo "$o"
+p '*'
$ bash --version
GNU bash, バージョン 4.2.10(1)-release (i686-pc-linux-gnu)
...
0193191
2012/06/30(土) 16:40:38.69bash --version
GNU bash, バージョン 4.2.28(1)-release (x86_64-redhat-linux-gnu)
4.2.10では起きてなかったと思う
0194名無しさん@お腹いっぱい。
2012/06/30(土) 16:43:18.580195名無しさん@お腹いっぱい。
2012/06/30(土) 16:54:47.17$ bash --version
GNU bash, バージョン 4.2.10(1)-release (x86_64-redhat-linux-gnu)
$ set -x
$ options="+profile '*'"
$ convert $options image1.jpg image2.jpg
+ convert +profile ''\''*'\''' image1.jpg image2.jpg
0196名無しさん@お腹いっぱい。
2012/06/30(土) 17:02:02.66>>192
echo が引用符が除去するからそれをやってもわからない
set -xで見ないと
0197名無しさん@お腹いっぱい。
2012/06/30(土) 17:10:30.740198名無しさん@お腹いっぱい。
2012/06/30(土) 17:11:54.01set -xで見て付いてるクォートは実際には除去されるから問題ない
0199名無しさん@お腹いっぱい。
2012/06/30(土) 17:49:22.14setでポジショナルパラメータに代入しても
結局ポジショナルパラメータの展開時にエスケープされちゃう
$*でも$@でも"$@"でも同じ
逆に*をあらかじめクォートしなければうまくいくようにも思えるが
クォートされていない*をそのままsetでポジショナルパラメータに代入する方法が無い
>>198
set -xでやたら'が増えるのはわかってるけど、そういう問題じゃないから
コマンド引数として「*」記号を渡したい
あらかじめ文字列中に裸の「*」を入れておくとglob展開される
「'*'」や「\*」を入れておくとパラメータ展開時に'や\までエスケープされてしまうって話
>>192の例でoが「'*'」の時
echo $oとecho "$o"、つまりecho '*'とecho "'*'"の結果が同じになるのは変だろ
記号「*」だけを表示して欲しいわけ
そのためにはoを「*」をにしてecho "$o"とやるしか方法がない
そういう仕様だからしかたないと納得した
つまり俺の
> パラメータに空白で区切って複数のオプション入れて、
> それをコマンド引数に渡すってことをやってたんだけど
がそもそも間違ってた。特殊記号が入る時はそういう事やっちゃいけないんだろう
0200名無しさん@お腹いっぱい。
2012/07/02(月) 13:20:07.03options=(+profile '*')
convert "${options[@]}" image1.jpg image2.jpg
これでも出来のではないですか?パス名展開させたければ、ダブルクォートを外す。
options='+profile *'
convert "${options}" image1.jpg image2.jpg
>>199 のこの辺がとても気になりますが、長くなるので省略。
> クォートされていない*をそのままsetでポジショナルパラメータに代入する方法が無い
> >>192の例でoが「'*'」の時
> echo $oとecho "$o"、つまりecho '*'とecho "'*'"の結果が同じになるのは変だろ
0201200
2012/07/02(月) 13:38:21.36後ほど
0202200
2012/07/02(月) 13:57:02.19#!/bin/sh
for i; do echo "$i"; done
$ sample.sh
#!/bin/sh -x
options='"-a" "*" "-b" "file name"'
eval ./convert.sh "${options}" '"other file"'
eval set -- "+profile '*' 'file name'"
./convert.sh "$@" image1.jpg image2.jpg
これでまだ勘違いしていたら、夜にでも考えます
0203名無しさん@お腹いっぱい。
2012/07/02(月) 14:46:36.09特にデータが外部から来る場合は"${array[@]}"がセキュリティ面を考えると安心だし
0204200
2012/07/02(月) 19:47:27.73変な点はまだ有るかもしれませんが、まあ Array で動いていてそれで良いなら、
不要な様なのでこれ以上訂正しません。
0205名無しさん@お腹いっぱい。
2012/07/07(土) 04:32:03.14不要です。
以上。
↓はい次の方。
0206名無しさん@お腹いっぱい。
2012/07/07(土) 07:45:06.260207名無しさん@お腹いっぱい。
2012/07/07(土) 21:04:25.660208名無しさん@お腹いっぱい。
2012/07/07(土) 21:24:19.25↓
$ echo $((123==123))
1
算術式評価では 真で0
↓
$ ((123==123)); echo $?
0
・・・そういうものです
0209名無しさん@お腹いっぱい。
2012/07/08(日) 00:05:05.40echo false; echo $?
意味ねーだろ。
0210名無しさん@お腹いっぱい。
2012/07/08(日) 08:43:03.23>>209 は >>208 の意味を理解してない。たぶん、算術式評価を知らないと見た。
echo $((123==123)); echo $? じゃなくて、
((123==123)); echo $? を実行してるんだから。
0211名無しさん@お腹いっぱい。
2012/07/08(日) 08:58:09.05標準出力の1/0を持ち出すのは「echo false」と同じくらい意味ねーといっているのだ。
わかるか? バカ。
0212名無しさん@お腹いっぱい。
2012/07/08(日) 09:00:39.710213名無しさん@お腹いっぱい。
2012/07/08(日) 09:04:04.78>>208 が指摘してるのは、
戻り値では0が真だが、展開値を出力とする算術式展開では1が真だよという点。
で、その算術式展開と算術式評価もまた違うという点。
やっぱり >>209 は算術式理解してなかったんだね。
0214名無しさん@お腹いっぱい。
2012/07/08(日) 09:08:53.37$ ((0)); echo $?
1
↑結果は偽ね。
0215名無しさん@お腹いっぱい。
2012/07/08(日) 09:40:18.88コマンドの戻り値が0で真が気持ち悪いというのが>>207が言っている事。
それに対して、算術展開とか持ち出した>>208の間抜けさを指摘しているのだ。 バカには難しすぎかい?
>>214
バカすぎる。つーか意味不明。当たり前のように理解不能。
行頭の$は何だよプロンプトか? w
0216名無しさん@お腹いっぱい。
2012/07/08(日) 09:45:04.93>当たり前のように理解不能。
↑敗北宣言乙w
0217名無しさん@お腹いっぱい。
2012/07/08(日) 10:04:40.89> >>214
> 行頭の$は何だよプロンプトか? w
その通りだよw
0218名無しさん@お腹いっぱい。
2012/07/08(日) 10:12:49.26で、それが「戻り値が0で真は気持ち悪い」となんの関係があるんだ? マヌケ
0219名無しさん@お腹いっぱい。
2012/07/08(日) 13:35:39.830220名無しさん@お腹いっぱい。
2012/07/08(日) 15:01:13.590221名無しさん@お腹いっぱい。
2012/07/08(日) 19:16:09.740222名無しさん@お腹いっぱい。
2012/07/08(日) 19:58:11.85/usr/include/stdlib.h:#define EXIT_SUCCESS 0 /* Successful exit status. */
になっているのだからしょうがないでしょうよ。
0223名無しさん@お腹いっぱい。
2012/07/08(日) 21:08:41.46色々と勉強しなおせ
0224名無しさん@お腹いっぱい。
2012/07/08(日) 21:14:25.840225名無しさん@お腹いっぱい。
2012/07/08(日) 21:18:14.89しょうがないのはいいんだけど、こういうときに頭がこんがらがる
test -f hoge.txt が成功したら「真」だから
test -f hoge.txt && echo unko
のときにちゃんとunkoが出るんだけどさ、ここまでいいんだけど
test -f hoge.txt の結果、$?ってゼロじゃん? だからさっきのも
ゼロ && echo unko
みたいな感じで unko出ねぇ って一瞬思っちゃうんだよ
0226名無しさん@お腹いっぱい。
2012/07/08(日) 21:23:20.80という感覚に慣れていればどうってことない。
0227名無しさん@お腹いっぱい。
2012/07/09(月) 09:44:10.37Zフラグでもなんでもどういうたとえを使ってもいいけど、
そのたとえを当てはめるまでにタイムラグがおこる
0228名無しさん@お腹いっぱい。
2012/07/09(月) 10:56:32.710229名無しさん@お腹いっぱい
2012/07/10(火) 21:53:14.00QEMUOPTS="${VMCPU:+-cpu $VMCPU}"
この文の
VMCPU:+ ってのは何のためにあるんでしょうか?
0230名無しさん@お腹いっぱい。
2012/07/10(火) 21:56:15.24>>229
$VMCPU に値が設定されている時のみ -cpu $VMCPU に展開する。
$VMCPU が設定されていない時に -cpu のオプションだけが QEMUOPTS に代入されるのを防ぐ。
0231名無しさん@お腹いっぱい。
2012/07/10(火) 22:04:39.97だから、VMCPUには常に値を代入してるんですが、、
0232229
2012/07/10(火) 22:34:35.51:-
:+
:=
こんな使い方があったんですね。ありがとうございました
0233名無しさん@お腹いっぱい。
2012/07/12(木) 17:37:48.08シェルスクリプト学習中の初心者です。
evalを使うとセキュリティー上どのような事が、問題となるのでしょうか?
変数を展開する際に意図せぬ結果となり、エラーでスクリプトが止まったり、コマンドが起動される事はなんとなく分かります。
初心者の考える危険な例
: ; from_net_1='apple'; from_net_2='banana'; from_net_3='; uname -a'
: ; OPT="$from_net_1 $from_net_2 $from_net_3"
: ; eval echo "$OPT"
また、この点に気を付ければ良い等、機械的に安全を得るやり方は有りますか?
もしくは、皆さんが使用時に、気を付ける点などあればご教示下さい。
0234名無しさん@お腹いっぱい。
2012/07/12(木) 21:28:20.42無い。信頼できるソース以外からの文字列をevalしてはいけない。
0235名無しさん@お腹いっぱい。
2012/07/12(木) 21:57:05.58evalを頻繁に使うようなトリッキーなコードは読みにくくなりがちだしね。
0236名無しさん@お腹いっぱい。
2012/07/12(木) 22:14:43.030237名無しさん@お腹いっぱい。
2012/07/12(木) 22:18:43.100238名無しさん@お腹いっぱい。
2012/07/12(木) 22:20:16.410239名無しさん@お腹いっぱい
2012/07/13(金) 22:22:49.32アクセスを集計しようと
cat /var/log/auth.log | grep "Failed password" | awk '{if($9 == "invalid")print $1,$2,$3,$11,$13,$15; else print $1,$2$3,$9,$11,$13}' | uniq -f5 -w12 -c
と書いてみたんですが、思うようにuniqされませ。
どこがマズイでしょうか?
0240名無しさん@お腹いっぱい。
2012/07/13(金) 22:36:54.900241239
2012/07/13(金) 22:57:53.20カンマ抜けてました
でも、カンマいれると全てが1行表示になりました。
0242名無しさん@お腹いっぱい。
2012/07/13(金) 23:10:09.05ここが環境依存だから答えられん。
awkに対してどんな入力を期待してるの?
0243名無しさん@お腹いっぱい。
2012/07/13(金) 23:40:29.47ついついやりたくなるのは分かるがawkがかわいそうに思えてくる。
0244名無しさん@お腹いっぱい。
2012/07/13(金) 23:45:38.52かと言って全部awkでしちゃうとgrepとかsedの立場がなくなる。
0245名無しさん@お腹いっぱい。
2012/07/13(金) 23:49:01.380246名無しさん@お腹いっぱい。
2012/07/14(土) 00:33:02.570247名無しさん@お腹いっぱい。
2012/07/14(土) 00:45:52.23対象にするコマンドが混在することになるからな
出力はcat、処理はパイプ、と分けた方が、保守性は高まるんじゃないかな
0248名無しさん@お腹いっぱい。
2012/07/14(土) 01:19:38.100249名無しさん@お腹いっぱい。
2012/07/14(土) 06:53:20.810250名無しさん@お腹いっぱい。
2012/07/14(土) 07:15:53.03わかるわww
ただawkを使いこなせるようになるには時間がかかるし、若い奴にこんな時代遅れなものを今から全部学べとは言えないからな。
必要最小限な使い方だけ教えると、grepやsedやuniqなんかと組み合わせた使い方をしてくるんだよね。
0251239
2012/07/14(土) 07:55:25.81Failed password が
Jul 13 13:56:36 xxxxx sshd[17819]: Failed password for root from 59.175.218.166 port 49148 ssh2
Jul 13 13:56:40 xxxxx sshd[17821]: Failed password for invalid user oracle from 59.175.218.166 port 51025 ssh2
の2種類があるので、必要部分だけにして、form のアドレスでまとめたいだけなんです。
連続したアドレスをまとめて、カウントできれば
0252名無しさん@お腹いっぱい。
2012/07/14(土) 07:56:18.63あのcsh使わされてるんですけど標準入力のアスタリスクを文字として扱えないんですけどどうしたらいいんですか。
標準入力からsetした変数でいろいろ分岐したいんですけど*を入れた場合だけ構文エラーとかワイルドカード展開になってしまいます。
ちなみにUNIX環境は全くわかりません。
マジでお願いします。
0253名無しさん@お腹いっぱい。
2012/07/14(土) 08:37:53.40なら前半は
awk '/failure/{print $1,$2,$3,$(NF-5),$(NF-3),$(NF-1)}' /var/log/messages
で済みそう。時間的な連続性を気にしなければ数え上げもawk内でやりたいが。
0254251
2012/07/14(土) 09:00:52.31failureの行をつかうたんですね
思うように集計されないのは、uniqの使い方に問題があったみたいです。
sortが前提みたいですね。
ただ、時間的に連続したfailureのアドレスをまとめたい、できればカウントつきで
0255名無しさん@お腹いっぱい。
2012/07/14(土) 09:15:24.770256名無しさん@お腹いっぱい。
2012/07/14(土) 10:46:53.420257名無しさん@お腹いっぱい。
2012/07/14(土) 15:21:41.03こういう事か?
set hoge = "$<"
echo "$hoge"
0258名無しさん@お腹いっぱい。
2012/07/14(土) 15:28:23.55多分私が運用保守をまかされそうな雰囲気です。業務的にとある構造分析や
シミュレーションなど行う必要があり、制御コマンドとしてシェルスクリプトを
使用するのは聞いていたのですが、そのファイルを開いて1行目に書かれていたのは
#!/bin/tcshという文字列でした。
「うへぇ〜、よりによってtcshかよ」
ファイル記述子のリダイレクト不可、クオートのネスティング等に無理あり、
今の奴でさえシェル関数は使えないし、パイプラインの終了ステータスもおかしいし、
今時の担当者が扱ってセキュリティは大丈夫なのか不安はつきませんし、
スクリプトとしてのcshは嫌われるのでネット上の情報も少なく調べるのも大変です。
おそらく導入に際して、大学など教育機関で最初にcshに触れて刷りこまれた人間が
強気の知ったかぶりをして発言権を得て「俺流」をつらぬき紛れ込ませたのでしょう。
昔、当時、シェルで唯一aliasやhistoryやジョブコントロールの機能が使えた
cshは大学など教育機関に浸透していて、日本のシェル界に多くのバカが輩出しました。
これから私は、おそらくそういうバカが、$*でスペース入りファイル名が扱えないとか
$<でファイルから読めないのかとか、変数に*を入れた場合だけ構文エラーになって
実行できないなどと、シェル通気取りの偏ったどうでもいい我侭を言い出し
(だからcshスクリプト書くんじゃねーよ)それと戦わなければならないのでしょう。
そして時代によって決着している、過去25年のシェル界隈のくだらないそれらの議論が
再現され、それに巻き込まれるのでしょう。もう今からうんざりです。
だからお願いです。教育現場ではbashでもzshでもkshでもashでも
Bourne shでもなんでもいいですがBシェル系のシェルにしてください。
教育機関で懐古趣味のバカを量産されると現場が非常に苦労するのです。
0259名無しさん@お腹いっぱい。
2012/07/14(土) 15:32:28.730260名無しさん@お腹いっぱい。
2012/07/14(土) 16:52:49.190261名無しさん@お腹いっぱい。
2012/07/14(土) 16:56:34.370262名無しさん@お腹いっぱい。
2012/07/14(土) 18:01:11.450263名無しさん@お腹いっぱい。
2012/07/14(土) 19:39:52.83サルにマスかき覚えさせると血が出るまでやめないのと同じだよ
覚えたてで嬉しいんだろう
0264名無しさん@お腹いっぱい。
2012/07/14(土) 19:52:41.06今時csh使ってるところなんかあるわけねーだろ。
0265名無しさん@お腹いっぱい。
2012/07/14(土) 20:00:46.430266名無しさん@お腹いっぱい。
2012/07/14(土) 22:00:42.21tcshが一番手っ取り早い時期があった
bashでの、カーソルキーによるヒストリ機能の正式サポートと実装は、
netnewsでは結構祭レベルで好評だったのに対し、fj界隈では
カーソルキーなんて使わないじゃんSVR4とかwwwみたいに
ガラパゴスってた事が、tcshユーザが大量生産したことと
因果関係は有ると思うね
0267名無しさん@お腹いっぱい。
2012/07/14(土) 23:13:13.33BSD界隈では csh 系にそれなりの人気があり
FreeBSD なんかデフォルトのshellは未だにcshだ(実体はtcsh)
0268名無しさん@お腹いっぱい。
2012/07/14(土) 23:16:17.420269名無しさん@お腹いっぱい。
2012/07/15(日) 03:26:56.35ashじゃなかったっけ
0270名無しさん@お腹いっぱい。
2012/07/15(日) 04:05:13.03http://svnweb.freebsd.org/base/head/etc/master.passwd?revision=218047&view=markup
root::0:0::0:0:Charlie &:/root:/bin/csh
0271名無しさん@お腹いっぱい。
2012/07/15(日) 07:21:31.450272名無しさん@お腹いっぱい。
2012/07/15(日) 12:20:29.92■ このスレッドは過去ログ倉庫に格納されています