シェルスクリプト総合 その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
0444名無しさん@お腹いっぱい。
2010/05/15(土) 14:57:21> bashではなく、Linuxカーネルのコンパイルのことと勘違いしていた。
と妄想した>>443が粘着して妄想を書き散らした。
キチガイやバカは妄想するのが仕事なので、お前が妄想しても何の痛痒も感じない。
0445名無しさん@お腹いっぱい。
2010/05/15(土) 16:02:210446名無しさん@お腹いっぱい。
2010/05/15(土) 16:04:580447名無しさん@お腹いっぱい。
2010/05/15(土) 16:11:080448名無しさん@お腹いっぱい。
2010/05/15(土) 19:18:350449名無しさん@お腹いっぱい。
2010/05/15(土) 21:27:10正解。
0450名無しさん@お腹いっぱい。
2010/05/15(土) 21:32:21でもCygwinじゃ使えなかったぜ!
0451名無しさん@お腹いっぱい。
2010/05/15(土) 22:03:46>>450 が言うように、Cygwinでも/dev/tcpがdisableでインストールされてることもある。
>>285 がLinux板に誘導したのは間違い。
0453名無しさん@お腹いっぱい。
2010/05/15(土) 22:18:20よくよめ。
たとえ「妄想」だったとしても、お前のプライドは潰れてる。
実際には「妄想」ではなく事実だから、お前は100%論破されてる。
という、2段階の主張。
とりあえず、お前のプライドが潰れればそれでいいから、
「妄想」でもいいならそのままにしとけ。
たとえ「妄想」でも、「/dev/tcpを知らなかった人」と思われるのは
さぞかし悔しいだろうな。
0454名無しさん@お腹いっぱい。
2010/05/16(日) 00:30:52foo='/hoge/spa ce.txt'
というようにスペースが含まれるファイルがあったとして、このファイルのbasenameをクォートするにはどうしたらよいのでしょうか?
echo "$(basename $foo)" だと spa になってしまうし、
echo $(basename "$foo") だと spa ce.txt (スペース1つ)となって、やはり spa と ce.txt が別トークンとして扱われてしまいます。
要するにダブルクォートをネストしたいということなのですが…
0455名無しさん@お腹いっぱい。
2010/05/16(日) 00:32:54本当は
foo='/hoge/spa___ce.txt' # _ はスペース
のように、スペースが複数入っていると考えてください
0456名無しさん@お腹いっぱい。
2010/05/16(日) 01:29:45お前は「妄想」していると明言している。これが100%の証拠って奴だよ。www
その言い訳、惨め過ぎるぞ。www
アク禁らしいから、解除されたらまたからかってやるよ。www
15分以上あるから足りないオツムで必死に考えてろ。www
>>438
> 「妄想」してるのはおそらく俺だけではない。
>
> おまえは「/dev/tcpを知らない人」と「妄想」されてても平気なのかw
> それで十分だ。お前のプライドは潰れたな。
0457名無しさん@お腹いっぱい。
2010/05/16(日) 01:36:20期待値がわからん。これじゃダメってこと?
$ cat a.sh
#!/bin/sh
foo='/home/spa ce.txt'
bar=$(basename "$foo")
echo "$bar"
$ sh a.sh
spa ce.txt
0458名無しさん@お腹いっぱい。
2010/05/16(日) 01:53:40あ、変数を経由すればいけるんですね!
bar=$(basename "$foo")
ここでも外側にダブルクォートが必要だと思い込んでました。ありがとうございます。
アホな質問してすみません><
0459名無しさん@お腹いっぱい。
2010/05/16(日) 09:05:29変数を経由しなくても行ける。
echo "$(basename "$foo")"
0460名無しさん@お腹いっぱい。
2010/05/16(日) 09:12:28変数に直接代入する場合は外側のダブルクォートは不要。
変数を使わずに直接 echoなどの引数にする場合は、
外側にもダブルクォートが必要(>>459 の方法)
ダブルクォートのネスティングみたいになるけど、
$( ) によって別の階層に分かれてるから、
エスケープとかなしにそのままダブルクォートを付けてOK。
もちろん、複数のスペースとかもそのまま保存される。
0461名無しさん@お腹いっぱい。
2010/05/16(日) 09:25:57なん・・・だと・・・
ネストできるわけないと思ってました。何でも試してみないとだめですね。
これができるんだったら色々楽になりそうです。ありがとうございます!
0462名無しさん@お腹いっぱい。
2010/05/17(月) 21:53:46へ〜、shのパーザー以外と頭良いな。 勉強になったわ。 bash限定という
事はないかな?
0463名無しさん@お腹いっぱい。
2010/05/17(月) 21:57:03bash限定じゃねーよ。
ちなみに、$( ) の代わりに ` ` でもOK。
0464名無しさん@お腹いっぱい。
2010/05/17(月) 22:31:26foo='/home/spa ce.txt'
で no space って言われるんだが、移植ミスなのか?
他の手段で入れれば"`"のネスト自体はできるけど
0465名無しさん@お腹いっぱい。
2010/05/26(水) 00:18:56$ cd //
$ pwd
//
どういう意味だろう? 3つ以上だと1つになる
$ cd ///
$ pwd
/
0466名無しさん@お腹いっぱい。
2010/05/26(水) 01:15:22emacsも同様に//を知っている。
0467名無しさん@お腹いっぱい。
2010/06/03(木) 23:00:02キーボードからの入力待ちの際、tab保管を有効にするにはどうしたらよいでしょうか?
#!/bin/csh
set file = $<
echo "ファイルは $file だよ"
上記のようなとき、filec+autolistのような挙動をしてくれることを望んでいます。
今日はじめてcshが駄目な事を知ったので、/bin/shでないことは御容赦ください・・・。
よろしくお願いします。
0468名無しさん@お腹いっぱい。
2010/06/03(木) 23:43:52#!/bin/bash
read -e file
echo "ファイルは $file だよ"
0469466
2010/06/04(金) 00:34:58bashならできるのですね(ググったらdash、zshとかいうのでもおkなのかな)。
人から貰ったcshスクリプトと組み合わせて使うため、
最初はbashスクを使ってasciiファイルに書き出してから、cshスクで読むとかになりそうですが
ゆくゆくは貰ったcshも全部bashに書き換えたいと思います。
ありがとうございました。
0471名無しさん@お腹いっぱい。
2010/06/04(金) 07:46:38簡単なものならcshの方がいい場合もある
0472名無しさん@お腹いっぱい。
2010/06/04(金) 10:06:00http://tiswww.case.edu/php/chet/bash/FAQ
のE10
0473名無しさん@お腹いっぱい。
2010/06/05(土) 01:33:35以下のソースでは入力がhogeかそれ以外の文字列の場合は期待通りに動くんですが、文字列を入力しなかった場合は
line 6: [: =: unary operator expected
とエラーが出ます。これはどうやれば防げますか?
#! /bin/sh
echo "input? "
read i
if [ $i = "hoge" ];
then
echo "input is 'hoge'"
else
echo "other"
fi
0474名無しさん@お腹いっぱい。
2010/06/05(土) 01:37:470475名無しさん@お腹いっぱい。
2010/06/05(土) 01:51:39なんという…ありがとうございます。
0476名無しさん@お腹いっぱい。
2010/06/15(火) 23:04:34なんかいいコマンドありますか?
find /var/www/data -name hoge を毎月1回最初の日曜日に実行して
インデックス作りたいんす
0477名無しさん@お腹いっぱい。
2010/06/15(火) 23:16:56逆でもいいけど。
0478名無しさん@お腹いっぱい。
2010/06/15(火) 23:32:49こうですか?
0479名無しさん@お腹いっぱい。
2010/06/15(火) 23:41:12date -d `date +%d`' days ago 1 day next sunday'
>>477
それをやりたくないから質問してるんだろ
0480名無しさん@お腹いっぱい。
2010/06/15(火) 23:43:36>>479 days ago ですか!date は奥が深いですね
いろいろとありがとうございますたー!
0481名無しさん@お腹いっぱい。
2010/06/15(火) 23:49:22これじゃだめ?
cal ${month} ${year} | awk '/^ ?[0-9]+{print $1}' | head -1
0482名無しさん@お腹いっぱい。
2010/06/15(火) 23:56:07cal って便利なんだけど awkで整形して使うのは面白い技ですね
みなさんいろいろ技があるんですね、勉強になります
そろそろCも覚えなきゃなぁ
やることいっぱいですorz
0483名無しさん@お腹いっぱい。
2010/06/16(水) 00:06:52こんな環境もある
% date -d `date +%d`' days ago 1 day next sunday'
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[[[cc]yy]mm]dd]HH]MM[.ss]] [+format]
%
0484名無しさん@お腹いっぱい。
2010/06/16(水) 00:19:06>>483 これ空鼠?
0485名無しさん@お腹いっぱい。
2010/06/16(水) 00:28:20いあ FreeBSD. つか, *BSD 全部だと思う.
つか, GNU 拡張 date じゃないと通らへんちゃう?
0486名無しさん@お腹いっぱい。
2010/06/16(水) 00:34:31うちのCentOSでは動いてしまったので気付かなかったw
あとで会社のFreeBSDで試して見ます(ヲ
0487名無しさん@お腹いっぱい。
2010/06/17(木) 03:26:50シェルスクリプトでOAuth認証できるクライアントを書いたw
Perlとか入れなくても標準環境にopensslとcurl入れるだけで動くからいいわ
0488名無しさん@お腹いっぱい。
2010/06/18(金) 00:25:21試せないけど。
0489名無しさん@お腹いっぱい。
2010/06/18(金) 18:29:26http://livedoor.2.blogimg.jp/agomesu/imgs/5/8/58ff257e.jpg
ばらまこうぜ!
0490名無しさん@お腹いっぱい。
2010/06/20(日) 04:42:59初歩的な質問で申し訳ありません。
0491名無しさん@お腹いっぱい。
2010/06/20(日) 07:14:26シェルスクリプト総合@LINUX Part5
http://pc11.2ch.net/test/read.cgi/linux/1238764663/
怒られる前に早く逃げろ
0492名無しさん@お腹いっぱい。
2010/06/20(日) 10:03:33ifconfig eth0 | sed -n '/.*HWaddr /{s///; s/:/-/gp}'
0493名無しさん@お腹いっぱい。
2010/06/20(日) 14:58:13Linux板で聞くよりこっちで聞く方が早いですね。
0494名無しさん@お腹いっぱい。
2010/06/20(日) 23:49:41> おいちゃんこれお願い
>
> http://pc12.2ch.net/test/read.cgi/unix/1266642605/489 2010/06/18 18:29:26
>
> 422 :名無しの報告 :2010/06/18(金) 18:39:13 ID:9cXOXF/h0
> >>421
> 100618 危険!!外国人参政権画像マルチポスト報告 3
> http://qb5.2ch.net/test/read.cgi/sec2chd/1276851966/
>
> これだろここに直接持ってくるなよ
>
> 423 :名無しの報告 :2010/06/18(金) 18:39:51 ID:DZt17tze0
> >>421
> 削除人?じゃないならやめなさい
>
> 424 :名無しの報告 :2010/06/18(金) 18:40:07 ID:wsULoapS0
> はーい
> ごめんなさい
0495名無しさん@お腹いっぱい。
2010/06/21(月) 21:28:31nc辺りで書こうかと思うのだけど
0496名無しさん@お腹いっぱい。
2010/06/21(月) 22:30:52根性試しでないならcurlとか使えばいいんじゃね?
0497名無しさん@お腹いっぱい。
2010/06/21(月) 22:34:180498名無しさん@お腹いっぱい。
2010/06/21(月) 22:56:57Age2ch Part14
http://pc12.2ch.net/test/read.cgi/software/1118219419/
0499名無しさん@お腹いっぱい。
2010/06/27(日) 01:04:50おかげで、-eqで比較しようとしてもちゃんと比較できなかったりして困るんだよね。
0500名無しさん@お腹いっぱい。
2010/06/27(日) 01:29:20awk '{print $1}' とかで切り出せば余分な空白は無くなる。
0501名無しさん@お腹いっぱい。
2010/06/27(日) 01:57:41EQ
0502名無しさん@お腹いっぱい。
2010/06/27(日) 08:45:20GNU wc は、wc -l とか wc -c とかの時、余分な行頭スペースは入らない。
0503名無しさん@お腹いっぱい。
2010/06/27(日) 09:17:16awkなんか使わなくても、
[ `wc -l < file` -eq 123 ]
でいいだろ。
"`wc -l .. `" じゃなくて単に `wc -l ...` にする。
>>501
シェル依存。
$ test ' 0' -eq 0 && echo EQ
test: 0: bad number
0504名無しさん@お腹いっぱい。
2010/06/27(日) 18:16:27bashでテキストファイルで空欄があるところを改行に変換するシェルスクリプトを作りたいんですが
どうすればよいでしょうか?
0505名無しさん@お腹いっぱい。
2010/06/27(日) 19:18:380506名無しさん@お腹いっぱい。
2010/06/27(日) 19:26:54man tr
0507名無しさん@お腹いっぱい。
2010/06/27(日) 19:57:24man tr < file.txt
ってやってみましたが、動作が変です。
0508名無しさん@お腹いっぱい。
2010/06/27(日) 20:23:380509名無しさん@お腹いっぱい。
2010/06/27(日) 20:25:31↓
----
#!/bin/bash
いいから man tr < file.txt
----
0510名無しさん@お腹いっぱい。
2010/06/27(日) 20:34:580511名無しさん@お腹いっぱい。
2010/06/27(日) 23:28:390513名無しさん@お腹いっぱい。
2010/07/27(火) 03:09:25#!/bin/bash
hostname
$hostname = `hostname`
echo $hostname
上記のシェルスクリプトを実行すると
hostnameだけの行はしっかり標準出力にホスト名が表示されるのですが、
$hostname = `hostname`で command not foundと怒られてしまいます。
なぜでしょうか・・・?
0514名無しさん@お腹いっぱい。
2010/07/27(火) 03:19:29#!/bin/bash
hostname
hostname = `hostname`
echo $hostname
でした。結果が
=
とだけ表示されてしまいます。標準出力の結果が変数に入っていないのでしょうか
0515名無しさん@お腹いっぱい。
2010/07/27(火) 03:23:090516名無しさん@お腹いっぱい。
2010/07/27(火) 03:27:38ありがとうございます。解決しました。
いろいろやってたら、間違ってhostnameに=を設定してしまっていたことも重なっておりました。
0517名無しさん@お腹いっぱい。
2010/07/27(火) 13:02:180518名無しさん@お腹いっぱい。
2010/07/28(水) 21:03:26マルチコアの上で動かすときに重宝しています。
しかし、例えば
for i in *.jpeg
do
convert $i `basename $i .jpeg`.png
done
のような多少複雑な操作をxargs -Pのような形で簡単に並列実行することはできるでしょうか?
"args"だけでなくてリダイレクトにも使用できることを望んでいます。
# 普段はzsh使ってるので for i in *.jpeg; convert $i $i:r.png とか書いてますが
zargsのような、zshに依存するやり方でも構いません。
ご存知でしたら教えていただければ幸いです。
0519名無しさん@お腹いっぱい。
2010/07/28(水) 21:09:45単純にバックグラウンドで、
for i in *.jpeg
do
convert $i `basename $i .jpeg`.png &
done
wait
でいいんじゃないの。
それよりスペースや特殊記号入りファイル名の対応の方が気になる。
0520名無しさん@お腹いっぱい。
2010/07/28(水) 21:28:090521名無しさん@お腹いっぱい。
2010/07/28(水) 21:42:38ありがとうございます。
変換する元のファイルも基本的に自分で作成するつもりなので、
ファイル名は「行儀のいい」ものと仮定して、スペースや特殊記号は特に意識していませんでした。
その代わり、ファイル数は100?のオーダーを考えているので、
バックグラウンドに全部一気に詰め込むのではなく、
最大並列プロセス数を与えて、その数だけ常に動かしつづけてくれる仕組みが欲しいのです。
0522名無しさん@お腹いっぱい。
2010/07/28(水) 21:43:44すみません、文字化けしてます。
×ファイル数は100?のオーダー
○、ファイル数は100 - 10000のオーダー
です。
0523518
2010/07/29(木) 13:56:52zsh依存ですが、例えば
function jpeg2png(); convert $1 $1:r.png
zargs -P4 -n1 -- $(echo *.jpeg|sed -e 's/ /\n/g') -- jpeg2png
とか。
ワンライナーで書きたかったのですが、これ以上にいいやり方ありますかね。
あと、$()の中が若干不細工ですが。
0524名無しさん@お腹いっぱい。
2010/07/31(土) 10:29:17複数文字のオプションの処理はどのようにやるのが一般的なのでしょうか?
0525名無しさん@お腹いっぱい。
2010/07/31(土) 11:28:10プログラムで質問があります。
/hoge/test/
の中に
1filename1.gif
1filename2.gif
2filename1.gif
2filename2.gif
があるとします。
# sh /hoge/test/*filename*
という感じにコマンドを入力すると
それらの複数のファイルが
command /hoge/test/1filename1.gif -option /aaa/bbb/1filename1.jpg
command /hoge/test/1filename2.gif -option /aaa/bbb/1filename2.jpg
command /hoge/test/2filename1.gif -option /aaa/bbb/2filename1.jpg
command /hoge/test/2filename2.gif -option /aaa/bbb/2filename2.jpg
って感じにファイルが無くなるまで全て、コマンドを実行したいのですが
どうすればいいのでしょうか??
0526名無しさん@お腹いっぱい。
2010/07/31(土) 11:36:52for f in "$@"
do
echo command "$f" -option "${f%%.gif}".jpg
done
0527524
2010/07/31(土) 12:29:250528名無しさん@お腹いっぱい。
2010/07/31(土) 12:51:270529名無しさん@お腹いっぱい。
2010/07/31(土) 14:03:440530名無しさん@お腹いっぱい。
2010/07/31(土) 14:07:360531524
2010/07/31(土) 14:39:07これって常識でしたか(笑)。
0532名無しさん@お腹いっぱい。
2010/07/31(土) 14:42:340533524
2010/07/31(土) 14:48:53それと$@なんかは"で囲う必要あり。
0534名無しさん@お腹いっぱい。
2010/07/31(土) 14:52:31Arguments containing white space or embedded shell metacharacters
generally will not survive intact; this looks easy to fix but is not.
0535名無しさん@お腹いっぱい。
2010/08/08(日) 20:39:19リスト化したファイルを読み込んでfind検索の後、圧縮かけて削除
処理させるスクリプト書いているのですが、どう書いて良いのか??
1)/home/hoge配下に、sample.lstと言うファイルを作成
2)(1)のリストを読み込んで、最終アクセスが7日経過しているファイルを検索
3)(2)に該当したものを圧縮して、元ファイルを削除する。
/*リスト化ファイル内*/
/home/aaa/abc
/home/bbb/abc
/* バックアップスクリプト*/
#!/bin/sh
BACKUPLIST=/home/hoge/sample.lst
FIND=`find $BACKUPLIST -type f -daystart -atime +7 `
tar cvzf `date +%Y%m%d`.tar.gz $TARGET && rm $TARGET
もちろん、上記では色々と問題がありますがこう言う風な処理をしたいと。
http://centossrv.com/backup.shtml ここの処理に、find検索の処理を追加
出来れば解決なのですが・・・。
0536名無しさん@お腹いっぱい。
2010/08/08(日) 20:40:39FIND=`find $BACKUPLIST -type f -daystart -atime +7 `
tar cvzf `date +%Y%m%d`.tar.gz $FIND && rm $FIND
でした。
0537名無しさん@お腹いっぱい。
2010/08/08(日) 20:57:36find [パス] [検索条件] -exec tar -czf $(date +%Y%m%d).tar.gz {} + -delete -print
0538名無しさん@お腹いっぱい。
2010/08/08(日) 21:06:51rやuじゃなくcで作ってるとはじめのほうのは失われてしまわないかね?
0539名無しさん@お腹いっぱい。
2010/08/08(日) 21:14:59ごめん、全然ダメだった
>>537実行すると超危険なので実行しないで!
まじでゴメン><
0540>>535-536
2010/08/08(日) 21:17:11アドバイス有難う。
でも、パスにfind $BACKUPLIST ・・・と書くとリストのパスを参照して
中身を参照検索してくれない。
単純にパスを指定すれば、うまくいくのだが???
find /home/aaa/abc ・・・で
>>538
findの所はループ処理だ回さないと駄目なのでしょうかね??
>>539
危ない、まだ実行していないので大丈夫wwww
0541名無しさん@お腹いっぱい。
2010/08/08(日) 21:39:25find /home/hoge/sample.lst ...が実行されちゃう
find $(< $BACKUPLIST) ...しないとダメだね
0542>>535-536
2010/08/08(日) 21:52:07レス有難う。
試しに、実行させたらとりあえず動いたんだが
tarの処理でエラーが出た・・・。
tar: 処理中にエラーが起きましたが、最後まで処理してからエラー終了させました
一応、圧縮は出来ているようだけど。
後、可能であればで良いのですが圧縮元を/home配下からではなく
abcフォルダ配下から圧縮出来ればベストなのですが。
一旦cdで/home/abcフォルダに移動しないとやっぱり駄目なのかな??
0543>>535
2010/08/08(日) 22:09:46#!/bin/sh
BACKUPLIST=/home/genki/backup/sample.lst
FIND=`find $(<$BACKUPLIST) -type f -daystart -atime +7`
tar cvzf `date +%Y%m%d`.tar.gz $FIND && rm $FIND
tarの際、全角ペースが入っているファイルがエラーになってバックアップ
取れなかった以外は、ほぼ思っている処理が出来ました。
tar: ドキュメント.txt: stat 不能: そのようなファイルやディレクトリはありません
tar: 処理中にエラーが起きましたが、最後まで処理してからエラー終了させました
本来なら、新規 ドキュメント.txt と言うファイルがあるのだけど・・・。
■ このスレッドは過去ログ倉庫に格納されています