シェルスクリプト総合 その16
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
2010/02/20(土) 14:10:05スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。
□お約束
・特記なき場合は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 でトレースしましょう。
前スレ
シェルスクリプト総合 その15
http://pc12.2ch.net/test/read.cgi/unix/1246408968/l50
0727名無しさん@お腹いっぱい。
2010/09/14(火) 23:12:17>>723 は date自体を使わずに、日付の数値を自分で計算しろと言ってるのでは?
0728名無しさん@お腹いっぱい。
2010/09/14(火) 23:54:360729名無しさん@お腹いっぱい。
2010/09/15(水) 00:04:20set `cal 8 2010`; shift `expr $# - 1`; echo $1
0730名無しさん@お腹いっぱい。
2010/09/15(水) 01:02:19おもしろいやり方してるな。
俺は普通にgrepとtailとsedあたりでやることを考えてしまうんで、ちょっと新鮮だ。
0731名無しさん@お腹いっぱい。
2010/09/15(水) 01:07:27cal 8 2010 | tr -s ' ' '¥012' | sed -n '$p'
0732名無しさん@お腹いっぱい。
2010/09/15(水) 01:23:18Solaris 10, Ubuntu 10.04はokだった。
0733名無しさん@お腹いっぱい。
2010/09/15(水) 02:32:21arg配列のそんな使い方があったのか。 自分が思いつくのは普通の
配列だな。
$ DAYS=(`cal 8 2010`); echo ${DAYS[`expr ${#DAYS[*]} - 1`]}
0734名無しさん@お腹いっぱい。
2010/09/15(水) 16:35:01./example | while read x
do
なんか処理して変数代入とか
done
変数を利用して後処理
というのをパイプ(サブシェル)を使わずにできない?
変数相当の値を一旦外部ファイルに書き出さないと駄目かな
exampleの出力を自身の入力にできるといいんだけど
0735名無しさん@お腹いっぱい。
2010/09/15(水) 16:51:27RESULT=`./example | while read x
do
なんか処理して echo 処理結果
done`
"$RESULT" を利用して後処理
0736名無しさん@お腹いっぱい。
2010/09/15(水) 17:44:06のようにすれば、while の外に出ても {} の内側にいるかぎりは変数の値が見える。
以下のようにすればそもそもサブシェルが生成されないが、
何やってるのかひじょーにわかりにくいのでオススメはしない。
while read x; do ... done <<_EOF_
`./example`
_EOF_
bash 限定。
while read x; do ... done <<<"`./example`"
0737名無しさん@お腹いっぱい。
2010/09/15(水) 19:46:27[ -z "$HOGE" ] && { ./example | HOGE=hage exec $0; }
while read x; do
なんか処理して echo 処理結果
done
0738716
2010/09/16(木) 01:30:00UNIXを初めて触ったころには使っていましたが、
それ以来一切関わることなく脳内から完全に抜け落ちていました。
cal出力の最後を月末とすることでうまくいきそうです。
レスくれた方ありがとうございました!
0739名無しさん@お腹いっぱい。
2010/09/16(木) 19:10:11斯界のおっさんたちは皆一度は試してるんだぞぉ
0741名無しさん@お腹いっぱい。
2010/09/16(木) 19:23:19ネタで書いてると思ったよ。
0742名無しさん@お腹いっぱい。
2010/09/17(金) 07:42:060743名無しさん@お腹いっぱい。
2010/09/17(金) 08:09:55FreeBSDの/bin/shで、>>737 動かないよ。
たしかにFreeBSDはヘボだな。
0744名無しさん@お腹いっぱい。
2010/09/17(金) 08:31:55[ -z "$HOGE" ] && { ./example | HOGE=hage $0; exit; }
0745名無しさん@お腹いっぱい。
2010/09/17(金) 08:41:25わざわざこんなことしなくても、
command | while ... がサブシェルにならないから、
最初から command | while ... と書けばいいんだな。
よって、>>737 は全然解決になってない。
0746名無しさん@お腹いっぱい。
2010/09/17(金) 08:51:570747名無しさん@お腹いっぱい。
2010/09/17(金) 09:09:000748名無しさん@お腹いっぱい。
2010/09/17(金) 09:15:550749名無しさん@お腹いっぱい。
2010/09/17(金) 09:18:43同じサブシェル問題だと、後付けで気付いたのはお前の方だろw
俺は最初からわかってたよ。
0750名無しさん@お腹いっぱい。
2010/09/17(金) 09:22:05> 俺は最初からわかってたよ。
> 俺は最初からわかってたよ。
> 俺は最初からわかってたよ。
> 俺は最初からわかってたよ。
0751名無しさん@お腹いっぱい。
2010/09/17(金) 09:36:12>>742 >どんなヘボシェルだよ。ww
↑って書いてる時点で 742 はサブシェル問題だと気付いてないよね。
FreeBSDだけじゃなく、フツーのbourne shでは動かないことに
この時点でまだ気づいてないww
0752名無しさん@お腹いっぱい。
2010/09/17(金) 09:38:58> 俺は最初からわかってたよ。
と言いたいのだったら最初から書くべきだったな。ww
0753名無しさん@お腹いっぱい。
2010/09/17(金) 09:43:14最初からわかってたのは本当だ。
でも答を書いてしまうと面白くないから >>737 他の反応を見るために書かなかった。
「ネタで書いてると思ったよ」という言葉に、
「サブシェル問題の解決なのにサブシェル問題に引っかかってるという笑いネタかw」
というニュアンスを含ませたつもりだが、読みとれなかったかい?
0754名無しさん@お腹いっぱい。
2010/09/17(金) 09:45:100755名無しさん@お腹いっぱい。
2010/09/17(金) 09:48:05>>737 自身が 737 を書いた時点で、
「全然問題の解決になってない」ということを理解していなかったということだ。
これだけは紛れもない事実。
0756名無しさん@お腹いっぱい。
2010/09/17(金) 09:52:19> 俺は最初からわかってたよ。
と、>>741が後付けで必死に言い張っている事。
0757名無しさん@お腹いっぱい。
2010/09/17(金) 09:54:04741 をいくら叩いても >>737 の恥ずかしさを弁解できないことは理解してますか?
0758名無しさん@お腹いっぱい。
2010/09/17(金) 09:56:580759名無しさん@お腹いっぱい。
2010/09/17(金) 10:10:47バグはそんなに恥ずかしくない。後付けで↓と言い張るよりは。
> 俺は最初からわかってたよ。
> 俺は最初からわかってたよ。
> 俺は最初からわかってたよ。
> 俺は最初からわかってたよ。
0760名無しさん@お腹いっぱい。
2010/09/17(金) 10:20:59じゃあ、バグを認めずに(バグの原因を理解せずに)
>>742 「どんなヘボシェルだよ。ww」
って言うのはどれくらい恥ずかしいですか?
0761名無しさん@お腹いっぱい。
2010/09/17(金) 10:39:200762名無しさん@お腹いっぱい。
2010/09/17(金) 10:42:05それとも、/bin/sh -> zsh みたいにリンクされたOS使ってたのか?
0763名無しさん@お腹いっぱい。
2010/09/17(金) 11:51:220764名無しさん@お腹いっぱい。
2010/09/17(金) 11:59:58で、762の質問への回答は?
(1)動作確認してなかったのか、(2)/bin/sh -> zsh にしてたのか?(その場合はOS名も)
0766名無しさん@お腹いっぱい。
2010/09/17(金) 17:57:23>確認してないが何か?
>確認してないが何か?
>確認してないが何か?
>確認してないが何か?
あーあ。自爆、敗北宣言乙w
0767名無しさん@お腹いっぱい。
2010/09/17(金) 18:01:20どこが敗北宣言なんだろう。ww
0768名無しさん@お腹いっぱい。
2010/09/18(土) 00:37:33シェルスクリプトの練習の為、練習用のシェルスクリプトを作成しており、
Cygwin上にて
#!/bin/sh
var1=100
var2=0
num1=`expr 10 + 30`
num2=`expr $var1 - 30`
num3=`expr 100 % 30`
num4=`expr $var2 && 1000`
echo $num1 $num2 $num3 $num4
という、上記内容のシェルを実行しました。
下記のような結果が出力される予定でした。
$./script2
40 70 10 0
ところが、
expr: non-integer argument
test02.sh: line 7: 1000: command not found
00
という内容が出力されてしまいました。
$var1、$var2が認識されていないようなのですが、原因が分かりません。
シェルはbash、OSはWindowsXPSP3です。
何卒、御教授お願い致します。
0769名無しさん@お腹いっぱい。
2010/09/18(土) 00:43:05dash on Debian だと
40 70 10 0
てなったよ。
set -x
してみたらどう?
0770名無しさん@お腹いっぱい。
2010/09/18(土) 00:58:52改行コードが CR+LF になってるだろ。LFのみにしろ。
var1=100^M とかになって実行されるから、正しく数値として実行されない。
0771名無しさん@お腹いっぱい。
2010/09/18(土) 01:17:44御回答、ありがとうございます。
set -x var1=100
set -x var2=0
としましたところ、今度は下記の結果が出力されました。
$ sh test02.sh
+ set -x $'var2=0\r'
++ expr 10 + 30
+ num1=$'40\r'
++ expr - 30
expr: syntax error
+ num2=$'\r'
++ expr 100 % 30
+ num3=$'10\r'
++ expr
expr: missing operand
Try `expr --help' for more information.
+ num4=$'\r'
+ echo $'40\r' $'\r' $'10\r' $'\r\r'
10
>>769
御回答、ありがとうございます。
Meadowにて改行コードをLFのみにしようとしたのですが、メニューが英語で、
どこを触ればいいのか分かりませんでした…
メニューを日本語化できないかと検索してみたのですが、403エラーでサイトに
入ることが出来ませんでした。
質問ばかりで恐縮ですが、LFのみにする為、どこを触ればよいか教えていただけないでしょうか?
0772名無しさん@お腹いっぱい。
2010/09/18(土) 01:28:30改行コードの問題ということがはっきりして、
このスレ的には問題解決したので、
次の方どうぞ
↓
0773名無しさん@お腹いっぱい。
2010/09/18(土) 01:33:31$ tr -d '\r' < in > out
あと、 set の使い方が違うよ。man 見てね。
0774名無しさん@お腹いっぱい。
2010/09/18(土) 01:37:53C-x RET f
で, sjis-unix とか指定すればいい。
分からなかったら禿丸とかでも改行コード変更できるだろ。
0775名無しさん@お腹いっぱい。
2010/09/18(土) 01:52:090776名無しさん@お腹いっぱい。
2010/09/18(土) 08:28:48Don't say "shell", idiot !
あ、こっちは日本語スレだった、、
0777名無しさん@お腹いっぱい。
2010/09/21(火) 17:22:43起動したアプリケーションの終了を待たずに、次のステップを実行するにはどう書けばいいのですか?
0778名無しさん@お腹いっぱい。
2010/09/21(火) 17:34:570779名無しさん@お腹いっぱい。
2010/09/21(火) 17:50:040780名無しさん@お腹いっぱい。
2010/09/25(土) 08:13:01・ findで見付かったファイルに対してそれぞれ複数のコマンドが必要な処理を行いたい
・ ディレクトリ名にスペースが含まれる可能性がある
・ 複数コマンドと言っても mv $f $f.org;sed -e '....' <$f.org >$f;rm $f.org みたいなワンライナーな処理で
汎用的に使いまわすようなものでも無い。
以上の条件をふまえると、思い付くやり方は
1. 複数のコマンド部分をシェルスクリプトにして、find -exec
2. 複数のコマンド部分をシェルスクリプトにして、find -print0 |xargs -0
3. 一時的にIFS='\n'にして、for f in `find ...`;do ....
という3つが思い付くんですが、1,2はわざわざスクリプトにするのは億劫で、3はちょっとトリッキーな感じで
どれもしっくり来ません。
割と良くある処理だと思うんですが、標準的なやり方って他に何かありませんかね?
0781名無しさん@お腹いっぱい。
2010/09/25(土) 09:14:000782名無しさん@お腹いっぱい。
2010/09/25(土) 10:01:27一列目に日付が二列目に数字が入っているのですが
fileAにない日付のデータがfileBにはあります。
fileAになければfileBのデータを補完して新たなfileを作成したいのですが、
簡単な方法ありますでしょうか?
file A
199901 10
199902 15
199903 16
199004 17
file B
199901 18
199902 13
199903 13
199004 13
199005 18
file NEW
199901 10
199902 15
199903 16
199004 17
199005 18
というようにしたいのですがどうすればよいでしょうか。
0783名無しさん@お腹いっぱい。
2010/09/25(土) 10:31:02$ sort -u -k 1,1 filea fileb
199004 17
199005 18
199901 10
199902 15
199903 16
0784名無しさん@お腹いっぱい。
2010/09/25(土) 12:01:48それはちょっと面倒だなぁ。
0785名無しさん@お腹いっぱい。
2010/09/25(土) 12:07:30-exec sh -c 'f="{}"; mv "$f" "$f.org";sed -e ... < "$f.org" > "$f";rm "$f.org"'
0786名無しさん@お腹いっぱい。
2010/09/25(土) 13:17:19それはもっと面倒だなぁ。
0787名無しさん@お腹いっぱい。
2010/09/25(土) 13:42:32タイプ数増やして応用力とはこれ如何にw
findで見つかったファイル名の中に $ を含むもの( $hoge という名前のファイルとか)
があったら、f="{}" のところで展開されちゃうから、エンバグしてるじゃん。
0788名無しさん@お腹いっぱい。
2010/09/25(土) 14:11:13そのバグは >>781 に既に含まれてるから、「エンバグ」ではない。
あと、$だけじゃなくて " ` とかがあってもコケるな。
0789名無しさん@お腹いっぱい。
2010/09/25(土) 14:27:21ありがとうございます!
試してみます!
0790名無しさん@お腹いっぱい。
2010/09/26(日) 19:42:22出力順を変えない方法もあるよ:
$ cat file_A file_B | awk '!a[$1]++'
0791名無しさん@お腹いっぱい。
2010/09/26(日) 20:09:55dpkg -x xxx.deb xxx
するスクリプトを作りたいんですが、
xxx.deb から .debを削除するには?
0792名無しさん@お腹いっぱい。
2010/09/26(日) 21:08:350793791
2010/09/26(日) 22:09:55sedを使うのかと思ってました。
basenameってこう言う使い方ができたんですね。
ありがとうございました。
0794名無しさん@お腹いっぱい。
2010/09/27(月) 00:00:54普通は、
for f in *.deb;do dpkg -x $f ${f%.deb};done
だけどな。
0795793
2010/09/27(月) 06:55:47おー スマートですね
0796名無しさん@お腹いっぱい
2010/09/29(水) 18:50:18PROC=`ps ax | grep "process"`
if [ -n "$PROC" ]
then
として見たら、grep processがあるからダメなのね
どうすりゃいいの?
0797名無しさん@お腹いっぱい。
2010/09/29(水) 18:54:03pgrepないの?
0798名無しさん@お腹いっぱい。
2010/09/29(水) 18:55:070799名無しさん@お腹いっぱい。
2010/09/29(水) 18:56:12見たいプロセスが logreport.sh とかだった場合に困る。
0800名無しさん@お腹いっぱい。
2010/09/29(水) 19:00:160801名無しさん@お腹いっぱい。
2010/09/29(水) 19:03:33ない環境ならしょうがないけど。
0802名無しさん@お腹いっぱい。
2010/09/29(水) 20:45:17そりゃ、PerlやRuby、Pythonなどが普及しても
「どこでも通じるからawkは覚えておいたほうがいい」なんてのがUNIX文化。
そこにおいて >801 は異質に見える。
0803名無しさん@お腹いっぱい。
2010/09/29(水) 20:48:450804名無しさん@お腹いっぱい。
2010/09/29(水) 20:52:30必死だな。
0805名無しさん@お腹いっぱい。
2010/09/29(水) 20:53:030806名無しさん@お腹いっぱい。
2010/09/29(水) 21:10:000807名無しさん@お腹いっぱい
2010/09/29(水) 21:15:56pgrepは使えませんでした
で、板が代わって、そういう小技こねくりまわした方法が見れない
もう一度、書いてもらえる雰囲気じゃない?
0808名無しさん@お腹いっぱい。
2010/09/29(水) 21:23:480809名無しさん@お腹いっぱい。
2010/09/29(水) 21:23:54いまいじっているシステムは全部で16Mぐらいの/
だけど、awkはある。pgrepはない。
perlもpythonもbashもない。
こういうシステム上でもinitスクリプト等にawkは必須。
0810名無しさん@お腹いっぱい。
2010/09/29(水) 21:24:54必死な屁理屈野郎にはなに言っても無駄だと思うよ。
0811名無しさん@お腹いっぱい。
2010/09/29(水) 21:59:51実際Perlとかで書いてみて、
シェルスクリプトと比べてみるといいよ。
0812名無しさん@お腹いっぱい。
2010/09/29(水) 22:03:17>>800が定石だと思う.
0813807
2010/09/29(水) 22:15:12ありがとう
0814名無しさん@お腹いっぱい。
2010/09/30(木) 00:48:340815名無しさん@お腹いっぱい。
2010/09/30(木) 10:48:540816名無しさん@お腹いっぱい。
2010/09/30(木) 18:11:46このスクリプトをcrondで1時間ごとに起動する
1度メールすると次は送らない
とするなると、メールを送ったかどうかの、何らかのフラグが必要でけど
一般的には、何をフラグとすればいいでしょうか?
ファイルの有無?
ファイルの中身の有無としたとき、ファイルのテキストを空にするコマンド
ってありました。?
0817名無しさん@お腹いっぱい。
2010/09/30(木) 18:16:590818名無しさん@お腹いっぱい。
2010/09/30(木) 18:18:11> 1度メールすると次は送らない
生涯で1回しかメール送らないってこと?
> ファイルの中身の有無としたとき、ファイルのテキストを空にするコマンド
> ってありました。?
:>file みたいな
0819名無しさん@お腹いっぱい。
2010/09/30(木) 18:37:44>>818
コロンが無駄です
0820名無しさん@お腹いっぱい。
2010/09/30(木) 18:53:06サンキュー
0821名無しさん@お腹いっぱい。
2010/09/30(木) 19:13:37どこでも動く :> の方が安心といえば安心。
まあ、sh と zsh をごっちゃにする人はあんまりいないと思うけど。
0822名無しさん@お腹いっぱい。
2010/09/30(木) 22:01:22':' って初めて知ったが他にどんな使い方があるのなか?
0823名無しさん@お腹いっぱい。
2010/09/30(木) 22:03:020824名無しさん@お腹いっぱい。
2010/09/30(木) 22:05:11: ${FOO:=bar} で変数のデフォルト値設定とかか?
0825名無しさん@お腹いっぱい。
2010/09/30(木) 22:44:52は俺だけか?
0826名無しさん@お腹いっぱい。
2010/09/30(木) 22:46:07■ このスレッドは過去ログ倉庫に格納されています