1 :
名無しさん@お腹いっぱい。 :
2011/06/16(木) 12:38:47.74
職場での話しです。 シェルスクリプトが使える環境から一部別ネットワークで 作業をする羽目になった。 windoze環境なのは相変わらずだが、旧環境はかろうじてcygwinが使用できたが 新環境は「管理者が親切にrubyだけ入れてくれた」状態。 ま、多少高速に動きますけどね・・・ 構文の見た目が糞なのだが、 俺のポーティングが悪いのかなぁ? ファイルをsedで置換して別ファイルに書き込むとかは、 (裏でopenとかwriteとかいっぱいioctrlがcallされているか知らんが) 見た目はシェルスクリプトが百万倍スマートだと思う。
Rubyあるだけでも随分マシなほう 素のコマンドプロンプトはマジで何もできんからな…
質問です。 hoge="a b c d" for m in `echo $hoge` do echo $m done ↑これと同じようなことを、 hoe="a,b,c,d" ↑これみたいにカンマ区切りのデータでやりたいんですが、どうすればいいですか?
IFS=, hoe つまり、エミッタ接地時の出力アドミッタンスだな
7 :
>>4 :2011/06/16(木) 23:54:02.88
うーん、だめでした。。 ~$ cat hoge.sh #!/bin/sh IFS=, hoge="a,b,c,d" for m in `echo $hoge` do echo "m=$m" done ~$ ./hoge.sh m=a b c d
bashだと動いたが。環境は?
下のやつはshとbashは同じだな。 zshはなんか他と違う。 jshもまた違う。 #!/bin/sh IFS=, hoge="a,b,c,d" for m in a,b,c,d; do echo "m=$m"; done for m in $hoge; do echo "m=$m"; done for m in `echo a,b,c,d`; do echo "m=$m"; done for m in `echo $hoge`; do echo "m=$m"; done for m in "`echo a,b,c,d`"; do echo "m=$m"; done for m in "`echo $hoge`"; do echo "m=$m"; done
>for m in `echo $hoge` こんなことやって気にならないなら、 for m in `echo $hoge | tr , \ ' でいいんじゃないの? 俺はイヤだけど。
bashなら HOGE='a,b,c,d' IFS=', ' fuga=($HOGE) for m in ${fuga[@]}; do echo "m=$m" ; done でいいんじゃない。
>>7 > for m in `echo $hoge`
echoを使う必然性は? 単に for m in $hoge なら期待通りじゃないかと思うけど。
> for m in `echo $hoge`
この場合、
(1) バッククォート中の展開するとき IFS=,だから echo a b c d になる。
(2) その出力"a b c d"を受けた元のシェルが単語分割する際も
IFS=,なので空白で分割されず、単一の文字列のまま。
ということで for m in 'a b c d' と同じになってしまうわけ。
IFSを使うなら処理のステップを分解してIFSの影響範囲を最小限に限定すると安全。
output=`なにか,区切りの出力をするコマンド`
IFS=, set -- $output
for m; do
...
done
質問です。 solaris10のグローバルゾーンからローカルゾーンでループ処理を実行したいのですが、 zlogin zone コマンド のコマンドの部分に、 例えば for a in `cat a.log` do echo $a done のような処理を入れようとすると ローカルゾーンにログインしようとしてエラーになります。 関数とかにループ処理を格納して無理やり実行しようとしても駄目でした… 何か良い方法ありませんか? 使用シェルはbashです。
zloginのmanに↓と書いてあるから、manual読むのが一番の近道だと思うな。 Non-Interactive Mode If a utility is specified, zlogin operates in non-interactive mode. This mode can be useful for script authors since stdin, stdout, and stderr are preserved and the exit status of utility is returned upon termination.
>>14 早速の返事ありがとうございます。
まぬある見てみたけど対話型無理って書いてあったからグローバルゾーンから複雑なコマンド実行は無理そうですね
かなり面倒だが一行づつ実行するしかないのかorz
16 :
名無しさん@お腹いっぱい。 :2011/06/29(水) 00:59:14.86
bashで質問です。 ssh user@host echo $HOGE_PATH で、ローカルのHOGE_PATHではなく、ssh先のHOGE_PATHを参照することってできますか?
>>16 ssh user@host echo '$HOGE_PATH'
とか
ssh user@host 'echo $HOGE_PATH'
とか
>>17 おおお、そういう事ができるんですね。
確かにssh先のが参照できました。なるほどー
>>13 自己レスですが解決しました。
for a in `zlogin zone コマンド`
do
zlogin zone echo $a
done
みたいな感じにしてやれば
グローバルからルーブ処理実行できますね。
>>3 そりゃそうだけど。
shellscriptのテストをshellscriptで書くのは、
コマンド群の出力を別のコマンド群に食べさせて
おなかを壊さなければ安心みたいな感じだけど、
rubyのテストをrubyで書いたり、
perlのテストをperlで書いたりとかは、
なんか辻褄だけは合って当然ぽくて
安心できない。
素のコマプロしかない作業環境になったら
転職します。
俺JScript/CScript.exeでテキストフィルタ書いたことあるぞ…
転職すべき!
ls -l で 合計 100 とか total 100 とか表示されるけど、この意味は何ですか?
>>24 それは知ってるけど、それが ls -l の時に表示される意味は何ですか?
意味はあんまりないね。 気にしなくていいよ。
ubuntu10.10の標準状態です。 経験値は極めて低いです。 ZIPファイルを展開して処理して再圧縮させたいです。 展開したフォルダだけの名前を取得したいのですが、どうやればいいんですか? echo * と echo *.* 比べるぐらいしか思いつかないです。。。
>>28 zip ファイルの中身の確認は
unzip -l hoge.zip
unzip -tv hoge.zip
などで確認
手軽にやるなら、fuse-zip を利用するのもあり
$ fuse-zip hoge.zip mountdir
$ 必要な処理
$ fusermount -u mountdir
でできる
unzip/zip コマンドで一部ファイルのみ変更する方法はあるのかな?
>>28 unzip展開後、find . -type d
>>30 お前は誰に何を答えてるんだw
manで答える回答は外してる、の法則の成立例。
>>31 普通そこらへんにzip展開してファイルを産卵させることないから、
WORKDIRに展開するとして、こうしないかな?スクリプトから使うことも考えると。
find "$WORKDIR" -type d
うわ…zip卵産んじゃってるよ… s/産卵/散乱/
>>29-33 ありがと。
キーはfind -type d
だね。
ついでに聞きたいけど、
シェルスクリプトの入門書ってなにかいい本ある?
javaとかcgiの本は本屋でいっぱい見かけるけど。。。
どんなコマンドがあるか把握するだけでもちょっと大変。
面白いけど。
一応findがない環境を想定して、findを使わない例。 function findd() { for D in "$1"/*; do if [ -d "$D" ]; then echo "$D" findd "$D" fi done } findd dir dir以下に存在するディレクトリを表示。シェルスクリプトでゴリ押し。 ネットのどっかにチュートリアルなかったっけ。それじゃ足りないかい?
functionなんて使うなクズ。
じゃあfunction書かなきゃいいよ。
>>35 .(ドット)で始まるディレクトリを取りこぼすな、これ
>>38 もし必要なら事前に次を実行しとけばどうさ?
$ shopt -s dotglob
ディレクトリにはハードリンクできなかったと思うけど、ループしてても動くのかね?findは(確か)止まるが。
ま、元の質問はZIPを展開したものに対してだから、気にしなくていいって言えばいいのか。
>>35 -n という名前のディレクトリが有ったら表示されない。
>>40 それは無いだろ?必ず一番初めに関数に渡したディレクトリ名が頭に付くんだから。
>>40 いや、"$1"/* から開始してるから
-n があっても hoge/-n になるから、問題ないだろ。
centos5で質問です ↓のようなテキストファイルがあります 1 a.log root 2 a b.log apache 3 c.log mysql ここでlogファイル名だけを抜き出したいのですが良い方法は無いでしょうか? awk等で列を抜きだそうとすると間にスペースが入っている為、どうしても2行目がb.logと抜き出されてしまいます。
二行目は"a b.log"ってことなのか? 最後の単語には空白が含まれない前提で、 awk '{ $1 = ""; $NF = ""; print $0 }' | sed -e 's/^ //' -e 's/ $//'
>>45 >二行目は"a b.log"ってことなのか?
その通りです。
正確にはスペースが複数入っているようなファイル名を想定してますが…
出先で直ぐには確認出来ませんが試して見ます。
>>44 >>45 sedだけで出来る
sed 's/[^ ]* //; s/ [^ ]*$//'
>>47 それを書くなら、
sed 's/[^ ]* *//; s/ [^ ]*$//'
だろ。
>>48 それだと " a b.log" (頭にスペース)のファイル名が正しく取り出せないだろw
まあ、元の仕様が不明だから何とも言えないが。
51 :
名無しさん@お腹いっぱい。 :2011/07/13(水) 14:24:43.76
誰かわかる方、今週中にお願いします。 以下のバッシュをボーンで書き直せ #!/bin/bash color=(Red Green Blue) for ((i = 0; i < 10; i++)) { echo ${color[RANDOM*3/32768]} }
52 :
51 :2011/07/13(水) 16:59:52.85
早くしろ、おせーぞ 金曜の朝までだ。最低でも月曜の朝まで 俺の単位が掛かっている
こんな過疎板で釣りか? ご苦労なこった。
かまうなよ。
単位がかかってるのかしょうがないな。特別にやってやろう。 #!/bin/sh exec /bin/bash <<'EOF' color=(Red Green Blue) for ((i = 0; i < 10; i++)) { echo ${color[RANDOM*3/32768]} } EOF
56 :
51 :2011/07/13(水) 17:30:42.13
なんで返事がないのですか? 原理とかも質問したいので、できるだけ早くお願いします。
>>51 わりぃ、わりぃ。直ぐに書けたけど、環境が分からなくてね。今bourne動かせるかい?
オマエラ不親切だな。ちゃんと教えてやれよ。 ↓ #/bin/sh echo '#include <time.h> #include <stdlib.h> #include <stdio.h> char*c[]={"Red","Green","Blue"}; int main(){int i;srand(time(0));for(i=0;i<10;i++){ puts(c[rand()*3LL/((RAND_MAX+1LL))]);}return 0;} '>t.c;gcc t.c;./a.out;rm a.out
#!/bin/sh color0=Red color1=Green color2=Blue for i in 0 1 2 3 4 5 6 7 8 9 do eval echo \$color`expr \`od -An -tu2 -N2 /dev/urandom\` \* 3 / 65536` done
traditionalなodだとそのオプションが使えないんだな
空気読めない空気デブは死ね。
62 :
51 :2011/07/13(水) 21:05:23.15
みなさん多数の回答ありがとうございました。
一番回答が早かった
>>55 さんので提出しようと思います。
本当に助かりました。
#!/bin/sh str_rand= str_rand_buf= while : ; do str_rand=$( expr "`echo "$$$str_rand$( date )" | md5sum`" : '\([^ ]*\)' ) str_rand_buf=$str_rand_buf$str_rand if expr $str_rand_buf : '^\(...\)*$' >/dev/null ; then echo $str_rand_buf | sed 's/.../\0\n/g' str_rand_buf= fi done | tr 0123456789acf 'bureRGdlRlrGu' | sed -n 'y/b/B/;/Red/p;/Gre/s/$/en/p;/Blu/s/$/e/p' | head -n 10 理解度の違いを見せ付けるチャンス!
>>51 #!/bin/sh
color=(Red Green Blue)
for ((i = 0; i < 10; i++)) {
echo ${color[RANDOM*3/32768]}
}
>>44 1,2,3 が最初のフィールドで、root,apache,mysql が最後のフィールドで
間にあるのがログファイルのリストだと仮定するならば、awkコードを
{
for(n=2; n<NF; n++) {
printf "%s ", $n
}
print ""
}
とすれば出来るんじゃないかな
ただ間にあるログファイル名が「空白自体をファイル名に含む」という場合はこれではできない。
>>49 の言う通り、そういう細かい仕様を明確にしないと書きようがない。
tclはすばらしい
bashって do 〜 done を { 〜 } で書けたんだね。知らなかった。 manにない(のかな?)けど、bashの拡張?何時ごろ入ったんだろ。
>>67 ボーンでも for で { } って書けるよ。昔から。
whileでは書けない。
>>68 そーなのかー。ありがとう。確かにwhileは無理だった。でもselectはいけた。
whileはlistをとるから、区別できなくて使えないんだろうね。
while :;:;:;:;:;:;:; do echo ok; done
こんな風に書けるとは思ってなかったよ。
>>262 ファイルの先頭に文字を追加するにはどうすればいいですか?
スレが建ってからおよそ一ヶ月。回答を得られるのは約四ヵ月後か。
ずいぶんロングパスだね。
>>262 までは2か月くらいかなあ。
>>70 rename "" "prefix" file...
とか
prename 's/^/prefix/' file...
とか
>>73 ありがとうございます。
Sedでファイル先頭を置換するのと、
中カッコでエコーとキャットをグルーピングする方法を思いついたので、今回はそれで行こうと思います。
>>74 を見る限り、
>>73 は明らかに勘違いした回答(ファイル名を変換してるw)だが、
ありがたいか?w
>>73 横からだが、ありがとう。renameの亜種がいっぱいあるせいでperlで実装されたものが行方不明だったんだが、
うちのシステムにもprenameで見つかった。プログラムの名前はかち合うように作らないで欲しいな。
>プログラムの名前はかち合うように作らないで欲しいな。 *BSD や Linux の killall と同じつもりで Solaris で killall を叩いてしまうと、 プロセスだけでなく自分まで死にたくなるな。 # Solaris の killall の方が先のはず
79 :
名無しさん@お腹いっぱい。 :2011/07/15(金) 18:50:08.88
以下のバッシュをボーンで書き直せ ただし、添付ファイルを使わないこと わかる方、来週中までにお願いします。 #/bin/bash diff -c <(ls -l /フォルダ1) <(ls -l /フォルダ2)
学ぶような知能があったらここで質問しないだろ。
bashとかだと$RANDOMで乱数得られるけど、他のやり方ってどんなのがある? odとかで/dev/urandom読むとか、md5sumみたいなハッシュ関数使うとか出てるけど。 自分はあまり精度が必要でないときdateでナノ秒とってきて使ったことはある。 awkのrand()使うのも思いついたけど、これだと何でもありか。 環境に依存しないのは、exprで線形合同法でも実装するくらいしかないのかな?
ぶっちゃけawk使ったほうが環境依存度としては低いかも知れないw(awkにしか依存しないことになるので) シェルスクリプトとしては/dev/randomをodで読む、が一番いい気がするんだけどなあ
/dev/randomってどのシステムにもあるの?仕様も同じ?つか、うちだと止まるんだけど。
gawkやnawkではrand()が使えるが、純正awk(solarisのawkとか)では rand()は使えないので、その場合わけが必要になる。
/dev/randomは乱数のタネがたまるまでブロックする。 つーか、貴重な共有リソースだから素人は使うな。/dev/urandom使え。
randomはともかく、urandomってどの環境にでもあるものなのか?
>>85 そうなのか…perlとかのが却っていいのかな?
>>86 /dev/urandom -> random に symlinkされてる FreeBSDでどうしろと?
エントロピーを凌駕するしかないな
FreeBSDはデフォルトが/dev/urandomのように振る舞うようになっている。 バカが理解せずに使うからバカ用のインターフェースが残された。
んで、urandomはどの環境にも必ずあるの? そもそも環境依存の話をしてるんだから、問題はそこだと思うのだけど。
solaris8以前に/dev/(u)randomはない。
urandomはおろか、randomも無いのか、そいつぁ困ったな
>>85 POSIXならrand()あるんだからそれくらい実装してくれよ。
urandomって30代目ジャンヌダルクのこと?
どのシステムにも漏れなく入っているハッシュを計算するコマンドで代用はどう? 「どのシステムにも」って所が難しいか。
ハッシュは乱数じゃないから用途によっては利用できない。
rand() { _seed_="`expr \( ${_seed_} \* 1103515245 + 12345 \) % 4294967296`" expr ${_seed_} / 65536 % 32768 } exprだけで実装。man randからパクリ。 $ _seed_=$$; for i in `seq 5`; do rand; done 21733 22089 6602 23744 28678 乱…数…?か?exprって幾つまで数えられたっけ?そもそも種はどこから持ってくるべきなんだ?
乱数の種の定番は現在日時じゃね
>>98 その rand()関数、単純に randで呼び出して表示するだけならいいけど、
i=`rand`
echo $i
みたいに変数に代入する使い方をすると
rand関数全体が暗黙のサブシェルになって、_seed_が更新されないという罠。
環境に依存しない、現在時刻を数値で取得する方法ってあったっけ。dateで出来たか?
>>100 マジだな。そこまで気にしてなかったわ。欲しい乱数の個数が決まってるなら、これでどうだろ。
for RND in $(for in `seq 10`; do rand; done`); do 〜 done
mktemp -u XXXXXX で何とかならないか。A-Za-zが邪魔だけど。cygwinだと/dev/urandomとか ないんだけど、mktempもGNUにしかない?
もうjotでいいやw
>>103 じゃーどうすりゃいいのよ?
>>104 これってBSDだけ?わざわざ用意するってことは、他に適当な方法がないのだろうね。
/dev/(u)randamがFA。 ないOSには死んでもらったほうがいい。
暗号にもちいるなら予測可能なタイムスタンプは使わない。 シミュレーションなどで再現性が重要な場合もタイムスタンプは使わない。 したがって、タイムスタンプ使うバカは死滅すべしが結論。
108 :
名無しさん@お腹いっぱい。 :2011/07/18(月) 00:28:21.96
大量データを処理するツールを作っているのですが、 bash/perl/awkどの言語で作成するべきか悩んでいます。 言語の特性を考えると、どれが一番おすすめでしょうか? 作成するツールの要件は下記の通り。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 作業前後でOSすべてのファイルリスト+md5sumを取得、 比較を取得し、差分を検出する。 取得するファイルリストはfind / -printf %p %T+ %l %s %m %g %uで、 %pの結果すべてをmd5sumに喰わせてハッシュ値を取得する。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 最初はbashで作成したのですが、思ったような性能を出すことができませんでした。 高速化を目指しAwkで作成したところ、10分の1以下になりました。 perlならもう少し早くなります。 が、チームにperl/awkが使えるメンバが自分以外不在です。 bashなら多少使えるそうなのですが…。 個人的には、bashが使えればawkも似たようなものなので、awkで作成しようかと思っているのですが。
パフォーマンスを向上させたいならホットスポットを見つけて、地道に対処するべきなんじゃないの? 原因も分からず場当たり的に作業しても何も残らんよ。
>>109 ネックになってるのはハッシュ値を計算している箇所です。
bashだと一行ずつmd5sumを呼び出すためプロセス起動、
ハッシュ値計算とコストがかかりすぎます。
代案としてawk,perlならそこを解決できるとわかったのですが。
ですので、bashでここの問題を解決できるならbashでも構いません。
例えばファイルを一意に識別するのにmd5sum以外の方法があったりとか。
xargs使って複数のパスを同時に引数に渡せよ。
>>111 ありがとうございます。
ためしてみます。
それから内容の同一性確かめなくてもst_ctime使えばいいんじゃないの? それならrsyncのdry run。
>>110 awk, perl ではハッシュ計算を行っていないということですか?
115 :
名無しさん@お腹いっぱい。 :2011/07/18(月) 01:39:49.47
>>113 ls -lで確認できる権限、パーミッション、オーナー、タイムスタンプ、ファイルサイズが全く同じで、
中身だけ異なるようなファイルを cp -pで入れ替えられた場合を考慮していたつもりだったのですが。
今ctimeの仕様を見るとinodeも考慮してくれているのですね。
であれば、ctimeでOKという気もします。
rsyncのdry-runというのもあるのですね…
勉強不足でした。
まだ理解で規定な箇所もありますが、
早速、教えてもらった方法を試してみます。
ありがとうございます。
116 :
名無しさん@お腹いっぱい。 :2011/07/18(月) 01:40:57.89
>>114 いえ、しています。
が、findの結果一行ごとにmd5sumを起動しないので、早くなっていました。
rsyncの--checksumオプションを使った場合、 awkやperlと比べてどちらが速いのだろうかと思った。
>>113 st_ctimeでは無理でした。
事前、事後にrsyncでバックアップ、リストアを実施しています。
リストアップのタイミングで必ずctimeが変わるため、
ファイルの内容に変更がない場合でも必ず差分として出てしまいます。
代わりにmtimeが戻るのでmtimeで比較も考えたのですが、
touch コマンド等で修正時刻を操作された時に検知が出来ません。
やっぱり、なにかしらファイルの同一性を見る必要があります。
xargsは文字数制限が発生したおちましたが、
オプションでなんとかならないか調べてみます。
>>117 私が作るアホシェルよりは早いきがしますね。
こちらも試してみます。
ありがとうございます。
ノンストップの処理を行わせておいて、指定した時間の経過で自爆させる時って ( cat /dev/zero > /dev/null & ; sleep 10 ; kill $$ ) & のような感じで良いですか?
>>108 tripwireというファイルの改変を検出するツールがある。
122 :
名無しさん@お腹いっぱい。 :2011/07/18(月) 12:17:22.58
>>121 tripwireも検討したのですが、処理が重く…
時間がかかるため、自作することにしております。
>>120 $$はサブシェルのPIDに展開されない。親が死ぬよ。
ファイルシステム全体のスナップショットを取って、そこから個々のファイルの差分を取れたら凄く楽そうなんだがなぁー。
>>102 -uオプションって初めから有った?昔mktempスクリプトから
使おうとして動かなかったことがあったけど、何が原因だったけ…
もう一つ思いついたのは、重複が無いって条件付でこんなのはどうだ?
seq 1 10 | sort -R
>>124 sortの -Rオプションが思いっきりGNUですw
GNU mktemp -u はドライラン
freebsdやsolarisの mktemp -u は、unlinkオプション。
動作が違う。
>>125 やっぱりかー。微かにそんな気はしてたToT
mktempとか(自分のまわりでは)良く使われてるのに
別の環境に持ってくと挙動が違って泣きたくなる事あるよね。
こんなオプションが挙動違うのかよって思ったコマンドってどんなのがあったけかな…
topも結構違わなかったっけ
128 :
名無しさん@お腹いっぱい。 :2011/07/18(月) 17:15:36.05
>>108 自己レスです。
教えていただいた方法で大分早くできました。
find の結果をawkで1行ずつ整形。
ディレクトリ、シンボリックリンクなら%p %T+ %l %s %m %g %uのみ出力。
ファイルだったらxargs -P 0 md5sum にてハッシュ値を取得、
findでとった%p %T+ %l %s %m %g %uにハッシュ値を付与しました。
大分早くはなりましたが、勉強も兼ねてもう少し、うまい方法がないか考えてみます。
シェルスクリプトで、特定の確率でcommandを実行する方法ありますか? 単純に 30% とかなら RANDOM % 3 -eq 0 でいけると思いますが、27% とかだったらどうすればいいのか。。。
>>131 function foo() {
local -i i="$1"
((RANDOM % 100 < i)) && "$2"
}
foo 27 command
とかで正しい?
>>132 すみません、頭が固くて嫌になるのですが
RANDOM % 100 < i
これでどうして確率になるのでしょうか?
100で割った余りは0から99
135 :
132 :2011/07/19(火) 17:47:19.49
>>132 は
RANDOM の取り得る値が 0 から 32767 だから、
foo 27 command
だと正確には 27% にならないかな。
RANDOM % 3 -eq 0 で 30% らしいから、そこまで正確でなくて良いのか。
>>131 RANDOM % 3 -eq 0
は、30%じゃなくて 33.3333..% な。
あと、算術式だと ((RANDOM % 3 == 0)) な。
%単位で正確にやるには100の倍数からはみ出たところを捨てるか。 while (((i = RANDOM) >= 32700)); do :; done ((i % 100 < 27)) && echo OK
139 :
131 :2011/07/20(水) 11:03:58.02
みなさま、ありがとうございました。 理解できました。 それほど正確じゃなくてもいいので、これで十分です。ありがとう
>>173 RANDOM >= 32700 じゃなくて RANDOM <= 32700
だな
>>140 こういう、正解を間違い呼ばわりするアホは何とかならないものか
143 :
140 :2011/07/20(水) 14:49:05.40
なんで? while (((i = RANDOM) >= 32700)); do :; done これだと i は 32700〜32767 ((i % 100 < 27)) → (0〜67 < 27) おかしいじゃん。
>>143 > これだと i は 32700〜32767
↑ ハイ、ここ違うね。
おまえ数学もプログラムも苦手だろw
>>143 while (((i = RANDOM) >= 32700)); do :; done
の実行後、
iの範囲は 0〜32699 になる。
whileループの基本。
わからないなら試してみろ。
$ while (((i = RANDOM) >= 32700)); do :; done
$ echo $i
25678
このやりかたって、乱数が完璧なら、 一定の確率で1日たっても終わらんなんて事態も発生するよな
たしかに可能性はゼロではないが、 1日どころか1秒以上ループが回り続ける確率ですら 宝くじで3億円当てるより低いだろう。
それを気にするなら、unsetとかexportとか気にするべきでは? どっかにexport RANDOM=40000とか入れられたら意図的に無限ループにできる。
exportは大丈夫だけどunsetはまずいな
>>148 export RANDOM=40000
ってやっても、それはseedが設定されるだけで
RANDOMは乱数のまま(無限ループにならない)。
一旦unset RANDOMしてからexport RANDOM=40000とやれば
RANDOM=40000固定になるが、いくらexportしても
スクリプト起動時に別のシェルが起動され、
exportに関わらずRANDOMは乱数機能で動作する。
確かに固定にしようと思ったらunsetやってからexportしないと駄目だね。 だけど、それでスクリプト書いて試したらRANDOMが40000で固定されたんだが?うちのbashだけか? もう一つ気が付いたのだが、exportするとそこから呼ばれたスクリプトの乱数列が固定される。 用途によってはこれも問題な気がする。
>>151 >exportするとそこから呼ばれたスクリプトの乱数列が固定
>>150 のいうseedの意味が分からんかったのか。
ランダムなseedを保証したかったら、スクリプトの中で
RAMDAMをランダムな数値でexportすればよい
>>152 RANDOMをランダムな数値でexport…だと…?
>>140 もあれだが、おまえももっとさわやかになれよ
他のサーバにtelnetでログインして、シェルを実行して、ログを取得することはできますか?
できますん。 そもそもtelnetじゃないとだめなのか? 普通そういう時にはremshやsshを使うもんだが。
どうしてもtelnetでやりたいならexpectを使うと簡単。
>>158 、159
ありがとうございます。
remshというのは知りませんでした。
sshは使えないと思います。
expectはネットで用例を見つけました。
teratermマクロで似たようなことをやっていたこともあるんですが、シェルスクリプトにした方が色々出来そうなのでちょっと調べてみます。
>>160 > sshは使えないと思います。
使えるよ。ssh-agent使えよ。
>>161 該当のサーバはtelnet接続のみでssh接続自体ができないということです。
設定を変える権限もありませんので。
ログの出力先がサーバでなく、ターミナルを動かしてるPC側ってことなら ターミナルソフトによってはログ取れるのもあるから(teratermも確かあるよね?) ターミナルでログ開始して、ログ取りたいコマンド打てば良いんでね
>>163 teratermでは出来ると思いますが、バージョンによってマクロの仕様が異なるのと、フリーソフトに頼るのもいまいち不安なのです。
expectで各サーバにログインして、シェルスクリプトを実行、ログをサーバ上に保存。ftpでログを接続元サーバにget。
取得したログをcatで一つにまとめる。
こんな感じで考えています。
自宅でvmware playerでcent osとfreeBSDを動かせるようにしているので、それで試してみようと思います。
しかし、cent osはsshでしか接続出来なかったとおもうので、設定を弄らなければならないですね。
わざわざ別ファイルに保存して、FTPで取りに行くようにするのはなんでだろ?
凄い初歩的な質問で申し訳ないのですが、2個以上の半角スペースを区切り文字に指定して抜き出す方法ってありますか? 例えば a b c d e の場合c dだけ抜き出したいんですが…
awk '{ print $3,$4 }'
>>166 あう…例えが全部半角になっちゃった
_が半角スペースで
a__b___c_d__e
の場合です。
>>167 うーん
言い方が悪かったですね。
c_dの部分は一列として抜き出したいです
この場合は3列目だけでc_dって感じで…
>>166 sed 's/.*[ ][ ]¥(.*¥)[ ][ ].*/¥1/'
あ、行じゃなく列ってことか? いまいち仕様がよくわからん。
>>170 おー素晴らしい。
ありがとうございます。
>>172 $3 $4だと冒頭とかがa_bみたいな文字列だった場合、ずれてしまうんです…でもありがとう。
1行に複数無いのか?
>>174 冒頭が「a b」でもちゃんと出るでしょ?
>>176 えーと
こんな時は…
a_b___b__c_d__e
bcって出ちゃうと思います。
こんな時でもc_dって出したいわけです。
>>165 expectで接続元のサーバにリダイレクト出来ますか?
>>177 なんか凄い出遅れた感があるけど、awkでやるならフィールドセパレータに正規表現を使えばいい。
awk -F'__+' '{print$3}'
同じようにアンダースコアはスペースに置き換えてね。
>>179 ほーawkでフィールドセパレート指定出来るのは知ってましたがそんなやり方有るんですね
勉強になります。
見た目はそっちのがスマートですね。
>>179 いま帰って試して見たんですがawkのやり方だと完璧ですね。
上で教えていただいたsedでやる方法だと文字が長くなったりスペースの数が不定だと変な所が抜き出されて駄目っぽいです。
今回はこちらの方法で行きますTHX
182 :
名無しさん@お腹いっぱい。 :2011/07/24(日) 23:10:11.58
そのネタもういいよ。
>>79 dir1=`ls -l /dir1`
dir2=`ls -l /dir2`
diff -c "$dir1" "$dir2"
すみませんが詳しい方のみ回答をお願いします
>>79 #! /bin/sh
ls -l /フォルダ1 | (ls -l /フォルダ2 | diff -c /dev/fd/3 /dev/fd/4 4<&0) 3<&0
>>186 ありがとうございます。これで提出しておきます。
文字列を一文字ごとにバラバラに処理するのは、どう書くのが一番かな? できるだけ多くのシェルで動かせるようにしたいのだけど。 自分で思いついたのはこんな感じ。 while read line; do while :; do chr=`echo -n "$line" |cut -c 1` echo -n "<$chr>" [ "$chr" = "$line" ] && break line="$(echo -n "$line" |cut -c 2-)" done echo done
そういうのはLL使っちゃうな。
while read line; do for chr in $(echo -n "$line"| sed -e 's/\([^ ]\)/ \1/g'); do echo "<$chr>" done done
bashならこうも書けるか。部分文字列の置換って標準的かな?
while read line; do
while [ -n "$line" ]; do
chr="${line:0:1}"
echo -n "<$chr>"
line="${line:1}"
done
echo
done
>>188 これのchrに設定するところ、"〜"で括り忘れてた。
>>191 bash使っていいならもっと簡単に書ける。
(改行も同列扱いだけど)
while read -n 1 c
do
echo -n "<$c>"
done
> できるだけ多くのシェルで動かせるようにしたいのだけど。 ってお題なのに、bashならって言い出すのってなんなの? 池沼?
>>193 欲嫁。
>>191 > bashならこうも書けるか。
に反応してるんだろ。
「どうせbashならもっと簡単に書け」と。
>>193 そう突っかかるなよ。
>>188 は「できれば」って言ってるし答えてる方も
『bash「なら」』って書いてるだろ
>>189 > できるだけ多くのシェルで動かせるようにしたいのだけど。
ってお題なのに、LL使っちゃうって言い出すのってなんなの? 池沼?
197 :
189 :2011/07/25(月) 11:29:21.25
>>196 「できるだけ多くのシェルで動かせるようにしたい」ってだけで、
「シェルで動かなければならない」ってことではないでしょ?
198 :
189 :2011/07/25(月) 11:30:37.16
要件をちゃんとわかってるのは質問者だけなんだから、 質問者以外がどうこう言ってもしょうがないよ。
>>194 はあ? ↓これをまとめて書いたんだが。池沼?
if (181 == 191) {
> できるだけ多くのシェルで動かせるようにしたいのだけど。
って、お題出してといてbashならって言い出すってなんなの? 池沼?
} else {
> できるだけ多くのシェルで動かせるようにしたいのだけど。
って、お題もらっといてbashならって言い出すってなんなの? 池沼?
}
>>178 ログはstdoutに出して、その出力を全部expectで処理すればいい。
expectに付いてくるサンプル改造すればすぐ出来る。
188です。いろいろなレスありがとう御座います。 シェルスクリプトで簡単なパーサを書きたいなと思いまして、質問しました。 perlのようなLLや、sed、awkなどを使うと全部それにやらせればいい と言う話になりますので、私自身は使わずに書きました。 実際書こうとすると、個々の文字に分解する標準的な方法が無いのかと気になった次第です。 せめて簡単な正規表現をシェルスクリプトだけで実装したいので、 正規表現を扱える外部コマンドを呼ぶのは何だかな、と言ったところです。
全部それにやらせればいいのに。 だめなのかな。
>>199 私の書き方が悪く、意味が不明瞭になってしまったようで、大変申し訳なく思っています。
そこは、bashではこう書けるが他のシェルでも使える標準的な方法か?と聞きたかったのです。
重ね重ね、池沼さん、大変申し訳ありませんでした。
>>204 同じような実装をしたときにどの程度の速度差があるのか調べる目的もあります。
シェルスクリプトは基本的に速さに期待できないのは分かっていますが、計ったことがなかったもので。
アンチbashがよく可搬性の点から、bashスクリプトを非難するけど、 シェルのシェアを考えると、bashはどの程度なんだろうね。 MacOSXやLinuxが基本bash (dashを含む)なので、bashが首位で かなりの割合を占めそうだけど。
世界全体のシェアを考えてもあんまり意味がないと思うなぁ。 要は自分が作ったスクリプトが自分が使う環境で動けばいいんでしょ。
bashスクリプトが#!/bin/shを名乗ってるから非難するのであって #!/bin/bashなら問題ないよ
Linuxでは sh -> bashのシンボリックリンクによって shの正体はbashであることを明示している。(Debianは sh -> dash) しかし、FreeBSDはshの正体がashであるにもかかわらず、 ashの名前ではインストールされておらず、 shを名乗ったままシンボリックリンクすら存在しない。 これはおかしい。
/bin/sh が ksh な環境もたくさんあるけどどうしましょう。
>>210 /bin/shのような基本コマンドはカーネルから直接exec()で呼び出されたりもするから
symlinkには出来ないんだよ。システムコールのexec()はsymlinkを追跡しない。
ライブラリのexec()では、内部でreadlink()呼んでsymlinkを追跡するから
気づかないんだけどね。
普通にsymlink追跡するよ。何歳だよジジイ。戦前の話か? www
>>203 shは構文木を保持するのが苦手。
カーニハンが"Beautiful code"で書いた
正規表現関数を模倣してみては? 文書はPDFで手に入る。
あれは内部表現使わずに解析する毎に逐次的に実行してるから。
>>215 ありがとう。元々内部表現を使う実装は無理かなと思っていたので、そのようにするつもりです。
どちらにせよ、一文字一文字個別に扱えたほうが都合が良いので、どのような方法があるのだろうと思ったのです。
内部表現持たないと、扱える正規表現の仕様はかなり小さくなる。
219 :
名無しさん@お腹いっぱい。 :2011/07/30(土) 00:54:06.04
bashでファイルの1行目の10バイト目にある文字だけ置換させたいのですが どのように書けばいいか教えていただけますでしょうか。 sed、awkコマンドでいろいろやってみたのですが、知識不足で 全行の10バイト目が置換されたりしてなかなかうまくいきません。 回答お願いします。
sedはパス。awkならこんな感じ。でも多分edの方が速い。 awk 'NR==1{$0=substr($0,1,9)"x"substr($0,11)};1' file ed -s file <<\EOF 1s/\(.\{9\}\)./\1x/ wq EOF もっといい書き方はあるかも。まあこの方法は、10バイト目じゃなくて10文字目なのがもしかしてマズイかも。
ついでだからsedでも書いた。GNU sedなら3つの中で一番遅い方法かな。 sed -n '1s/\(.\{9\}\)./\1x/;p' file
うとうとしながら書くもんじゃねーな。↑は、いらん部分があった。 sed '1s/\(.\{9\}\)./\1x/' file
>>219 せっかくbashならbashの機能使おうや。
(IFS= read -r; echo "${REPLY:0:9}X${REPLY:11}"; cat) < in_file
bashのくせに#!/bin/shとか書いてあるんだからそんな特殊機能なんか使うなよ
/bin/sh と書くからにはコメントすらも特殊機能だからな
シェルスクリプトでのコメントなんてライセンスの主張くらいにしか使わんだろw
おまえは1000行野郎を書いたことがないな
改版履歴とか書いたりして
232 :
名無しさん@お腹いっぱい。 :2011/08/02(火) 21:23:22.11
bashで前ゼロ削除をやろうとしているのですが、 初心者のためうまくいきません。すみませんがご教授ください。 00099999 ↓ 99999
expr 00099999 + 0
>>233 こういう風に答えられるように私はなりたい。
echo 00099999 | awk 'sub(/^0+/,"")'
a=00099999 echo $(( 10#$a ))
echo ${a##*0}
echo ${a##0*0}でいいんじゃない?
あー、a=010999だとダメかw
a=000 とか a=0102 とか
echo $a | sed 's/^00*\(..*\)$/\1/'
[[ $a =~ ([^0][0-9]*|0)$ ]]; echo ${BASH_REMATCH[0]}
expr $a : "0*\(..*\)"
無駄に長くしてみた t=$a; while :; do case $t in 0?*) t=`expr $t : '^0\(.*\)$'`;; *) break;; esac; done; echo $t
直感的なわかりやすさで
>>233 だな。
既存の文法に無理矢理おさめただけの#って何だよって感じだ。
符号付きも考えるのかよ…
echo $a | sed 's/^\([+-]\{0,1\}\)00*\(..*\)$/\1\2/'
そういや小数点はどうする?
a=001.3
>>233 >>235 だとエラーになるぜ
おまえら
>>232 の細かい仕様が分からないままでよくそんなに遊べるな。
実は、sed 's/000//' ですむ問題かもしれないぞ
a=1000だったら…
>>250 スマン、、
echo $a | sed 's/^\([+-]\?\)00*\(..*\)$/\1\2/'
>>249 expr で
>>233 がエラーになる環境って何?
次善策はbcに食わせることかな
echo -00123 | bc
なんで要求がどんどん増えるんだ。
曖昧な仕様で最小限の要求だけ想定するとつまんないから
printf '%d' 00099999 じゃだめか?
おまえらががっつくから
>>232 が怖がって出てこないじゃねーか
>>257 printf '%d' 00011111とかやると2進数だとして処理されちゃうので
printf '%g' の方がいい
間違えた、octalで処理されるんだった
ん?結局整数限定?
だな
>>253 がもうちょっとまともに動けば文字列処理型で最善だったかもな。
>>261 まてよ、、指数表記もアリだとしたら…
a=001.2345e+06
echo $a | bc
(standard_in) 1: syntax error
たぶん >> 233 で FA だと思うが… >> 266 a="-001.2345e+06" echo $a | sed 's/\([0-9.]*\)[Ee]\([+-]\?[0-9]*\)/\1*10^(0\2)/' | bc -1234500.0000
指数は展開しなくてもいいんじゃ…
>>253 を使えば"-1.2345e+06"になるし
よし、俺が仕様を決めてやるよ 入力:10進数、正負あり、小数可、指数表記可 出力:10進数、入力と数値的に等しい最短の文字列、指数表記可
233で満足したんだろう
ならそう書いてほしいな。
>>233 見て、それでも別解出し続けたバカ共の事なんか気にしなくていいだろ。
バカはともかく、お題を楽しんでるだけなんだから、質問者放置でよし 質問やり逃げなんていつものこと
実は別解出し続けた回答者のひとりが
>>232 と同一人物。
>>232 は初心者を装ったネタ振り。
それは、下手したら233一発で収束してしまう諸刃の剣
279 :
名無しさん@お腹いっぱい。 :2011/08/03(水) 22:32:05.53
ファイルに改行コードがあるかどうか判定し、なければ10バイト目に 改行コードを入れるbashを教えてください。。。。
↓のようなテキスト(sample.txt)があり aaa 1 xxx 2 bbb 3 aaa 4 aaa 5 xxx 6 bbb 7 xxx 8 aaa 9 「xxx」以降、最初に出現した「aaa」の後に続く数字を出力しようと思っています。 上記テキストの場合、期待する結果は4と9です。 そこで以下のようなスクリプトを作りました。 #! /bin/sh cat sample.txt | awk '/xxx/{ while ( getline > 0 ){ if ($0 ~ /aaa/) { print $2; break; } } }' 期待した動作はするのですが、「xxx」を見つけたら→その後一行ずつ探す、という実装で ちょっと力技すぎるかな?と思ってます。 xxxを検索条件としている所と、if文中でaaaと比較する所とで、方法がマチマチなので これってどうなのだろうか、と。 かといって全てwhileループ内に入れて、まずxxxだったら…というのもイマイチかと… よりうまい書き方とかありましたら、教えてください。
>>279 エスパー解釈すると、ファイルに一切改行がない場合のみ、
1行10文字で改行を入れる、ということでいいかな。
↓
case `wc -l < file` in
0) fold -10 file;;
*) cat file;;
esac
迷わずperl perl -n -e 'if ((/^xxx/ .. /^aaa/) && /^aaa\s+(\d+)/) { print "$1\n"}' < sample.txt
>>281 いくつか思いついたけど、できるだけそれを尊重してフラグを使う方法にしてみた。
cat sample.txt | awk 'z&&/aaa/{z=0;print$2};/xxx/{z=1}'
sedでも書けそう。perlならもっと短く書けるかな?
>>283 perlで書くとこうなるのか。ちょっと意外。
それ見てawkも範囲指定できること思い出した。
awk '/xxx/,/aaa/{if(/aaa/)print$2}' sample.txt
これ以上簡単に書ける方法は思いつかんかった。
再々修正。同じ正規表現を使うのは非効率なので結果を再利用。 awk '/xxx/,a=/aaa/{if(a)print$2}' sample.txt
じゃ、sedで sed -n '/^xxx/,/^aaa/{s/^aaa \([0-9]\+\)/\1/p}' < sample.txt 範囲指定のregexpを{}内から参照ってできないんだっけか
>>283-287 皆さん情報ありがとうございました
いろいろ新しい発見をしました
いただいた情報をもとに、修正の方針など検討します
>>289 awkやってるといつも思うんだが単項+演算子じゃダメなん?
+ 0 (as number)は . "" (as string)と対称構造を持つ定石。
奥が深いですね!
>>291 ありがとう。そういうことか。演算子の優先順位が違うから専用の演算子でも欲しいところだ。
294 :
名無しさん@お腹いっぱい。 :2011/08/04(木) 21:08:43.16
>>219 の質問に似ているのですが
先頭文字がABCDEで始まるレコードの10バイト目にある文字だけを置換させたいのですが
どのように書けばいいのでしょうか。
直ぐ下のレスのawkスクリプトのNR==1を/^ABCDE/にすればいいと思うの。
>>294 せっかくbashならbashの機能使おうや。
while IFS= read -r; do
case $REPLY in ABCDE*) echo "${REPLY:0:9}X${REPLY:11}";;
*) echo "$REPLY";; esac; done
bashのくせに#!/bin/shとか書いてあるんだからそんな特殊機能なんか使うなよ
read で変数を指定しなかったときに $REPLY に入れるとか、 ${var:m:n} で変数から文字を切り出すってのは ksh 系の機能で sh にはない機能だよね。 少なくとも、/bin/sh が dash や ash である OS では動かない。
>>300 > read で変数を指定しなかったときに $REPLY に入れるとか、
なんでこんな馬鹿な仕様を新設したんだろうな。
リハ用のシェルのソースで、 ふざけ心で変数無指定時にはREPLYに入れるようにしておいたら、 誤って本番のソースとして流れてしまったんです。
そのつもりならコミットせんだろ
誤ってコミットしてしまい、23秒間Ctrl-Cを押し続けたんですけど取り消せませんでした
つまんね。
306 :
名無しさん@お腹いっぱい。 :2011/08/11(木) 10:25:22.54
rsync で相互同期(src と dst で共に更新がありえて、新しい方を採用)する場合って、 rsync -u src dst rsync -u dst src すればできますが、時間がかかります。 一発でやる方法ありますか? また、rsync じゃなくてコレならそれを一発でできるよみたいのありますか?
shまたは、bashで、 コマンドをタイムアウトさせる関数timeoutを作りたい。 timeout [タイムアウト秒数] [コマンド] で、 指定[タイムアウト秒数]以内に[コマンド]が終了した場合は、 その[コマンド]の終了コードを、 [タイムアウト秒数]に引っかかった場合は、timeout関数の終了コードを返す。 そんな関数って書けますか?
追記、 もちろん[タイムアウト秒数]に引っかかった場合は、 [コマンド]を強制終了させます。
すみません、出来ました・・・
どうやって?
312 :
名無しさん@お腹いっぱい。 :2011/08/12(金) 04:05:08.93
unison昔試したときイマイチ挙動が安定しなかったんだよな 更新かけたファイルがたまに消えたり。 今は良くなったかな?
>>311 こんな感じでやりましタ。行数の問題で見にくいですが。
timeout() {
TIMEOUT=$1
shift 1
"$@" &
PID=$!
PASSED_SEC=0
while [ ${PASSED_SEC} -lt ${TIMEOUT} -a `ps -p ${PID} | grep -cv PID` -ne 0 ]
do
PASSED_SEC=`expr ${PASSED_SEC} + 1`
sleep 1
done
if [ `ps -p ${PID} | grep -cv PID` -ne 0 ]; then
kill -KILL ${PID}
wait ${PID}
echo "$@: killed, for timeout(${TIMEOUT}sec) exceeded." >&2
return 1
fi
wait ${PID}
return $?
}
>>314 別にcoreutilsに入っているtimeoutコマンドをエミュレートしたかった訳じゃないのね。
denコマンド作ったよ $ den -- 東京電力 ------------------------- 2011/8/12 21:55 UPDATE PEAK供給力: 5480 万kW 21:55: 3771 万kW (68%) -- 東北電力 ------------------------- 2011/8/12 22:02 UPDATE PEAK供給力: 1228 万kW 22:00: 884 万kW (71%) -- 関西電力 ------------------------- 2011/8/12 21:55 UPDATE PEAK供給力: 2850 万kW 21:45: 2081 万kW (73%)
den co
man co
ping co
tin sh
dmesgの先頭の [ 0000.000] を削除したいんですが どうすればできますか
sed 's/^\[ 0000\.000\]//'
323 :
321 :2011/08/15(月) 13:51:10.11
>322 ありがとうございます。 ただ 全部の行の[ 4.01234] などをずべて消したいです
>>321 dmesg | sed 's/[^ ]* //'
条件後出しかよ。
>>324 は不正解だろ。
こっち正解
↓
dmesg | sed 's/[^]]*[]] //'
dmesg | sed 's/.*\] //'
>>328 不正解。
それだと dmesg中の [8086:0040] type 0 class みたいな行の [8086:0040] の部分まで
消えてしまう。
330 :
321 :2011/08/15(月) 15:03:57.65
みなさん ありがとう、ございます。
もう遅いけど、とりあえず dmesg | cut -d']' -f2-
332 :
名無しさん@お腹いっぱい。 :2011/08/16(火) 19:06:44.80
bashでファイルの先頭が’A’で始まるレコードの10バイト目から12バイト目までが ’空白’(スペースが3個)であれば、その空白を’XXX'に変換したいのですが うまくいきません、良い書き方教えてくださ
333 :
名無しさん@お腹いっぱい。 :2011/08/16(火) 19:07:28.10
bashでファイルの先頭が’A’で始まるレコードの10バイト目から12バイト目までが ’空白’(スペースが3個)であれば、その空白を’XXX'に変換したいのですが うまくいきません、良い書き方教えてくださ
>>333 sed -e '1s/\(A.\{8\}\) /\1XXX/'
しまった。2chに書くと空白3つが一つに変換されてしまうのね。 sed -re '1s/(A.{8}) {3}/\1XXX/'
ではなく{3}使ってくるとかワラタw
337 :
名無しさん@お腹いっぱい。 :2011/08/16(火) 22:35:00.01
>>335 初心者のためあまりよく分からないのですが、
10バイト目から12バイト目が’空白’の条件は
どうやっているのでしょうか。。。
>>336 あと を使う書き方は{3}を に変えるだけで
よいのでしょうか。
>>337 ああ、確かに
>>334 ,
>>335 は間違いだった。スマン。
正しくは
sed -re '1s/^(A.{8}) {3}/\1XXX/'
だな。
これは
「一行目の先頭の文字がAであり、その後に任意の文字が8文字続き、そのあとに空白が3文字続いたなら
その部分を()でマッチした部分+XXXに置き換える」
という意味。
もっと詳しいことが知りたかったらsedとか正規表現でググると良いぞ。
面倒くせえな
対した事の無い処理をわざわざ複雑に書くのはただの馬鹿。 perl一つで解決する物をsed使ったりして頑張っちゃうとか
sed一つで済むのにわざわざperlを使っちゃうのも如何なものだと思うけど。
わざわざっつーか、汎用テキスト処理スクリプトであるPerlを使っちゃうと スクリプトの意味が解りにくくなるんよね。 sedだったら、まず最も多い用途は置換だから、置換かな?と思って読むことが出来る。 もちろん、複雑なテキスト処理に使うのは大賛成だけどね。
大半のテキスト処理はsedとawkがあればできちゃうからなあ。 Perlじゃないとできないことは滅多にないし Perl書くぐらいならRubyかPythonで書いちゃう。
まあ、重たい処理ならPerlオンリーでも良いんじゃね? シェルスクリプトだとどうしても処理長くなっちゃうし。 ただまあ、ここはシェルスクリプトのスレなんだよな。
まあおいらが言いたかったのは列抜き出すだけで単純にawkで済むものをsed使って正規表現の置換で無理やり見たいのをこのスレでよく見るからさ 本人はスキルを自慢しているつもりなんだろうけど、見辛いだけなんだよね 可視性も考慮しろと言いたい
まあ、いいんじゃないの? ここは初学者用の教科書じゃないんだから。 自治厨より役に立つ。
と言うか個人的な好みも有るかもしれないが、sedは見た目がきたない 正規表現で置換をやるなら何故perlを使わないのか理解に苦しむ まあスレチですが…
そもそも正規表現自体が汚いんだからperl使おうがsed使おうが一緒だろ まあスレチですが…
>>345 全く逆
単純にsedで済むものは必ずsedで書くこと。
sedで書けない処理の場合のみawkで書く。
sedで書けるのにわざわざawk使うのはバカ。
sedもawkも使わずにシェルだけで書けるものはシェル(内部コマンド)で書く。
(おまけ) perlで書くのは無条件で馬鹿。
perlって、awkの機能もsedの機能もgrepの機能も持ってるじゃん awk、sed、grep使ってる程度のシェルスクリプトって、perlで書こうと思えば書けちゃうじゃん だから全部perlで書くなら、別にいいと思うんだよ でも、シェルスクリプト中で、awkやsed、grepでできる処理をperlで書くっていうのは、 それはなんかイケてないって気がするんだよな 逆に、perlでなきゃ無理な処理をシェルスクリプトに混ぜ込むってのも、perlを必要とするなら 全部perlで書いちゃえyo、とも思うんだよな なんというか、シェルもperlも、スクリプト動かせる土台じゃん、と まぁawkも結構いろいろできるけど、それはそれとして、さ
sedはawkより遅いってイメージがあるw
イメージで語るなよ。
sedで充分なのはsedで、不十分なのはperlで、pythonはワンライナー書けないから却下。 awkの出番はほぼ無い。唯一「n番目のフィールドを取り出す」これだけがawkを使う場面。
>>353 そんだけならcutでいいでしょ。
だから、不十分なのはperlでって、本当に不十分なんすかね?という話になる。
>>354 cutは文字列をセパレータに出来ないじゃん。使い分けるの面倒だからその用途にはawkで良い。
>>354 cutでawkと全く同じようにフィールド切り出せるの?
357 :
名無しさん@お腹いっぱい。 :2011/08/20(土) 17:20:50.24
linux環境上で120MBぐらいのファイルの文字コード変換を iconvコマンドで別ファイル書き出すbashを作成していたのですが、 エラーが出てしまいました。エラー内容がうろ覚えなのですが、 (たしか容量的な問題のエラー) 容量の問題かと思い調べたのですが、2GBまでは大丈夫そうなのですが 何か他に問題てありますか。。。
bashというのは名前からしてシェルですか? でも、すでにbashという名のシェルは存在するので、別の名前にした方が良いですよ。
>>357 iconv に -c オプションを付けろ。
-c がないとiconvで変換できない文字コードに出会った時に異常終了する。
>>358 エスパー失格の上に返しがつまんね
360 :
名無しさん@お腹いっぱい。 :2011/08/20(土) 19:54:25.02
>>359 エスパーさんは隔離スレから出てこないでください。隔離スレに回答待ってる質問者がいますよ。
361 :
359 :2011/08/20(土) 20:48:13.07
>>360 俺はそっちのスレの住人じゃないよ。
他板でも、エスパー回答はごく当たり前の風潮。
>360 わかります がんばって! ^^
流子さんのbash、智花のbash。
現在のディレクトリ以下のディレクトリ、ファイルから再帰的に 目的の文字列を検索て、フルパスを一覧表示したいです。 どうすればよいですか
それはシェルスクリプトでやるべきではありません。とても遅くなるからです。
find . | xargs grep "AAA" では
GNU grepなら-rオプションがあるよ〜
368 :
364 :2011/08/21(日) 10:28:39.99
まったく、違う方法を考えてました ありがとう
>>366 それ、今時のスペース入りファイル名で誤動作するから禁止。
「xargsは使うな」っていうテンプレ、前スレまであったのになくなったな。
$ find . -print0 | xargs -0 AAA でいいっしょ。
>>370 それはGNU限定になるから没。(しかもgrep忘れてるしw)
find . -exec grep AAA {} +
が正解。
(最後 + がポイント)
>>371 最後の+は古いバージョンのfindじゃ使えないんじゃないの?
>>371 の方法に別に異論はないけどFreeBSDのfind/xargsにも -print0/-0はあるみたい。
+が使えるなら-print0も使えるってオチとか無いの?w
むしろgrep -r -nで|sedで削って| uniqとかでまとめちゃうとかw
>>375 何をしたいのかよく分からないけどgrep -r -lとは違うの?
>>374 Solarisでは +は使えるが -print0は使えない
+はposix -print0/-0は非標準。
xargsを使っちゃいけないってことはhogeにファイル名の一覧があるとして $ tr '\n' '\0' < hoge | xargs -0 grep AAA みたいなことをしたい場合はどうすればいいの?
>>379 IFS='
'
grep AAA `cat hoge`
-0もできないような古いOSなんか使ってるんじゃねぇってことじゃね?
find ./ -type f -exec grep AAA {} /dev/null \; てのがよくある方法だと思ったが
>>381 昔はファイル名にスペースなんか入れないことが暗黙の了解だった。
CUIのみの操作だから、スペース入りファイル名は作りにくいし作らない。
だから、-0なしのxargsが普通に使われていた。
>>380 それ、スペースはOKだけど、* ? [ab] とかのワイルドカードが展開される。
set -f 追加しろ。
なぜファイル名にスペース禁止にしなかったのかほんとに意味が分からない
>>387 ありがとう。参考になったよ。この程度の英語ならそのまま読める。
"mojibake"だけ日本語だった。これって英語圏でも通じる言葉になったのかw
シェルスクリプトを勉強する前に、Perlを勉強することにしましたw
>>387 のページより、
IFS="$(printf '?n?t')"
# CORRECT if filenames can't include tab/newline *and* if IFS omits space:
COMMAND $(find .)
↑ 駄目だよ。
>>385 が言うように set -f しないと、
findしたファイル名に素の * とかが含まれていると、それが再度展開される。
emojiも英語みたいだぞ?
>>371 最後 + だと grep に渡されるファイル名が1つだけの場合が起こり得る。
>>383 はそれを回避できるが、まぁ効率は悪いな。
「フルパスを一覧表示」だから、素直に -l オプションつければいいんじゃないか?
find ${PWD}/ -type f -exec grep -l 'AAA' /dev/null {} +
/dev/null は "-e" のような名前のファイルがあっても動くように入れてみた。
>>392 grep に渡されるファイル名が1つだけの場合は起こりえない。
>>371 では、あえて -type f を付けていない。
だから、カレントディレクトリの . が必ず渡されるため、
それと通常ファイルを含めて2個以上の引数がgrepに渡る。
CentOS 6でやってみた 以下連投すmanko $ find . . ./oppai oppai ./oppai oppai/oppai text.txt ./unko ./unko/text.txt ./manko ./manko/text.txt $ cat ./oppai\ oppai/oppai\ text.txt AAA $ cat unko/text.txt shit $ cat manko/text.txt pussy
>>366 $ find . | xargs grep "AAA"
grep: ./oppai: そのようなファイルやディレクトリはありません
grep: oppai: そのようなファイルやディレクトリはありません
grep: ./oppai: そのようなファイルやディレクトリはありません
grep: oppai/oppai: そのようなファイルやディレクトリはありません
grep: text.txt: そのようなファイルやディレクトリはありません
>>370 $ find . -print0 | xargs -0 grep AAA
./oppai oppai/oppai text.txt:AAA
>>371 $ find . -exec grep AAA {} +
./oppai oppai/oppai text.txt:AAA
>>383 $ find ./ -type f -exec grep AAA {} /dev/null \;
./oppai oppai/oppai text.txt:AAA
>>392 $ find ${PWD}/ -type f -exec grep -l 'AAA' /dev/null {} +
/tmp/oppai oppai/oppai text.txt
AAAじゃなくxだったらどうなる?
>>396 $ find . | xargs grep "x"
grep: ./oppai: そのようなファイルやディレクトリはありません
grep: oppai: そのようなファイルやディレクトリはありません
grep: ./oppai: そのようなファイルやディレクトリはありません
grep: oppai/oppai: そのようなファイルやディレクトリはありません
grep: text.txt: そのようなファイルやディレクトリはありません
$ find . -print0 | xargs -0 grep x
$ find . -exec grep x {} +
$ find ./ -type f -exec grep x {} /dev/null \;
$ find ${PWD}/ -type f -exec grep -l 'x' /dev/null {} +
Binary file なんちゃらって出るのはBSD限定? NFSだと別の表示になるかもしれんが。
ufsだとディレクトリが読めちゃうよね。 NFSだと読めないし、ext[234]でもディレクトリは読めない。 他のファイルシステムはどうだろう? あと、検索対象のファイルがバイナリファイルだった場合、 古いgrepだとBinary ...のエラーで門前払いされて 中身を検索してくれないことがある。GNU grepだとバイナリでもOK。
zfsでも$ cat . とかできちゃうな。 この辺の挙動の違いってファイルシステムじゃなくて FreeBSDとLinuxのシステムコールの実装の違いだと思ってたんだけど違うのかな。
>>393 最初に実行される grep についてはそうなんだが、ファイルがたくさんあって、
渡される引数が ARG_MAX を超えたときに別のプロセスとして実行される
grep でも起こり得ないんだろうか。まぁ、めったにはおこらないと思うが…
そもそもこれを想定しないで良いなら grep AAA `find ./` でいいわけだし。
>>401 >grep AAA `find ./` でいいわけだし。
↑ それ、スペース入りファイル名で誤動作。で、話がループ。
みんな GNU grep 入れようぜ。
>>402 grep AAA "`find ./`" でいいわけだし。
grep pattern filename* /dev/null は定石かと。
xargs的には、grep pattern /dev/null filename* がいいのかな。
>>405 それ、過去のバッドノウハウな。
今は -H オプションがあるから grep -H hoge file*
-Hは0個に対応できないでしょ。file+にしか。
>>408 0個の場合は findから呼び出されないから無問題。
そんなこと全く気にしたことが無かったのだが、その/dev/nullは、運悪く渡されるファイルがなかったときに、 標準入力を読みに行ってシェルスクリプトが固まるのを防ぐためのもの…なのか?
>>408 コマンドライン直接の話だとしても、
ファイルが0個の場合は file* って文字列自体が grepの引数になってエラーになるだけ
だから、stdinを読んでしまうことはない。
file* の文字列自体が渡ってしまうことは /dev/nullを付けても解決しない。
file*は正規表現のつもりなんじゃないの? +とか書いてるし。
414 :
名無しさん@お腹いっぱい。 :2011/08/24(水) 23:38:26.66
質問です。 以下のようなスクリプトがあります。 ------------------------- $ cat ./hoge.sh #!/bin/sh -x find . -type f | wc -l ------------------------- このスクリプトを実行すると、通常以下のように出力されます。 ------------------------- $ ./hoge.sh + find . -type f + wc -l 1 ------------------------- しかし、時々以下のように変な出力がされることがあります。なぜでしょうか? そして、回避策はありますか? ------------------------- $ ./hoge.sh + find+ wc /home/mao/tmp/110824 -l -type f 1 -------------------------
すいません、最後のサンプルだけ訂正させてください ------------------------- $ ./hoge.sh + find+ wc . -l -type f 1 -------------------------
私が思うに、パイプの左と右が一緒に実行されるのでは?と疑っています。
>>414 質問とは直接関係ないけど、
それ、改行入りファイル名で誤動作するから使用禁止。
>>416 パイプの左と右が同時に実行される、で正解だよ。それで仕様。
嫌な場合はBIOSでCPUを1コア以外止める。
>>419 いいや、1コアなら大丈夫。
ヒント:プリミティブ
1単語出すごとにflushしてるのに?
Windows7 UltimateにあるUnix互換モードって普通のunixみたいに使えるものなの?bashとかもあるらしいのだけど
シェルの実装依存だろ set -x のデバッグメッセージについては、 ksh zsh bash: 行ごとflush ash: 単語ごとflushw
行ごとflushならマルチコアでも
>>414 の問題置きなくね?
>>424 jshも単語ごとだね
v7shは明示的にはflushしてなさそうだけど、単語ごとwrite
同様に、単語ごとflushでもシングルコアなら
>>415 の現象は起きにくい。
で、ありがたいヒントくださった
>>420 どこいった?
つか、単語ごとにflushする利点ってなんだ?
>>422 ターミナルの画面がでかくできない
コピーペーストできない
つかえない
test
質問です. set -x による出力が + date -d '2011/4/2 6 day' +%Y のようになっていて,その次の出力行が date: 余分な演算子 `day\'' 詳しくは `date --help' を実行して下さい. と出力される箇所があるのですが,-xの出力をそのまま端末エミュレータに コピペしてみると正しく実行されます. このエラーの原因が分からなくて困っています. どなたか助けてください.よろしくお願いします.
>>435 シングルクォートが、通常の文字として解釈されてる。
シングルクォートが余分。
あるいは、もう1回解釈させるために
evalを付けると良い。
再現方法:
$ date -d "'"2011/4/2 6 day"'" +%Y
date: 余分な演算子 `day¥''
詳しくは `date --help' を実行して下さい。
>>435 エスパー回答するぞ。他の変数にdateの引数入れてるんだろ?
$ hoge="-d '2011/4/2 6 day' +%Y"
$ date $hoge
date: 余分な演算子(ry
$ eval date $hoge
2011
>>436 の言うようにevalで解決。
438 :
435 :2011/08/27(土) 16:35:27.84
>>436 ,437
evalで解決できました.ありがとうございました.
ちなみに,
>>437 さんの言うように,dateの引数を変数に入れて使ってました.
>>1 のお約束について
Ubuntuのデフォルトが"dash"っになってたような気がするんだけども・・・それは書かなくていいのか?
Ubuntuっつーか、Debian系で使われるのがdash(Debian ash)だな、ashのDebian版 Debian系では対話環境のデフォルトはbash、シェルスクリプトはdashを前提とすることが多い Ubuntuの/bin/shも確か中身はdashなんだっけ? ちなみにお約束に追記するとしたら、どの辺にどう追記するよ?
見てきた sh -> dash てなってた 知らんかったわ@Ubuntu
>>440 >>Linuxユーザは/bin/shの正体がbashなので特に注意。
>>FreeBSDユーザは/bin/shの正体がashなので注意。
の下に一緒にいれときゃいいんじゃないかな?
>>441 if [[ "${foo}" =~ "${foo}" ]]; then 〜fi
みたいな式が使えなくてさ・・・「何で?デフォルトのshはbashにリンクされてるんじゃないの?」
って思って調べてみたら・・・
950あたりでまた言ってくれ。
AIX6.1環境に旧サーバーからのアプリケーション移行を行ってるんですが その際不要なファイルが大量にあり、一括表示する方法はないものかと あれこれ試してみました。 結果として下記のような記述になったのですが…(色々省略してますが) $ echo "ls -l $1 "`while read line do; echo "grep -v "$line ;done < $2` > 不要ファイル一覧表示.ksh $ 不要ファイル一覧表示.ksh $ rm 不要ファイル一覧表示.ksh $1は検索対象ディレクトリ、$2は必要ファイル一覧です 不要ファイル一覧表示.kshの生成と削除を行わず、いきなり実行は出来ないんでしょうか?
echo "ls -l $1 "`while read line do; echo "grep -v "$line ;done < $2` | ksh
>>445 なるほど、ありがとうございます!
あと自分の記述が間違えてた…
$ echo "ls -l $1 "`while read line do; echo "|grep -v "$line ;done < $2` > 不要ファイル一覧表示.ksh
パイプ入れ忘れ〜
ash復権してるのか bash笑()
コマンドAのstdoutをコマンドBのstdinへパイプで入力、コマンドAのstderrをコマンドCのstdinへパイプで入力を 一発でやることはできますか?
一発じゃ無理だろうな
>>448 (com_A | com_B) 2>&1 | com_C
cmd_Bが変なの吐かないように細工した方がいいんじゃね?
>>446 セミコロンの位置とかいろいろ間違えすぎだろ
$ for f in "$1"/*; do fgrep -q "$f" "$2" || echo "$f"; done | xargs rm
これで仕様合ってんのかね。
# .で始まるファイルもあるとこれではまずいが
>>442 「Debian系Linux(Ubuntuなど)では/bin/shの正体がdash(Debian版ash)だったりするので注意。」
って感じかな、
>>443 の言う通り
>>950 辺りでまた言ったほうが良いかもね
>>442 > if [[ "${foo}" =~ "${foo}" ]]; then 〜fi
> みたいな式が使えなくてさ・・・「何で?デフォルトのshはbashにリンクされてるんじゃないの?」
状況が分からないけど、 bash 特有の機能を使うときは、シェバングを
/bin/bash などに変えたほうが良いと思う。
[[ は bash 特有の機能じゃなくて ksh 由来だったかと。 それはそうと、/bin/sh が bash な環境しか使ったことない人は どれが bash 特有の機能なのかなんかぜんぜん知らないし気にしてないというのが実情。
>>446 grep使うなら"^$line$"した方がいい。
>>452 grep, egrepだと正規表現に使う文字がパス名に含まれると難しい。
しかしfgrepだと部分文字列でマッチしてしまうよ。
>>455 一応そういう人を対象(?)にbashの固有の機能を使わないように書くガイドが
debianのマニュアルの中にあった気がする
まあDebianの場合bash依存を減らすのに一番の方法は ガイドとか読むよりも、まずdashで書き始めることなんだろうけどな
実際、ほとんどのUbuntu(Debian)ユーザーは
>>460 で
/bin/sh -> bash に設定してるよ。
だから、Debian系Linux(Ubuntuなど)では/bin/shの正体がdash」(
>>453 )
と言うとそれはそれで嘘になる。
「になってることもある」で
ほとんどのユーザがしているってこれからもそうとは限らないのでは? そもそもdashを採用したのはDebianでは現行のsqueezeからだし。 デフォルトではそうなっているっていう事実は考慮すべき。
素人の私に教えてください。 シェル内で scriptコマンド使ったら、 そこでexitで抜けるまでシェル止まってしまうんですが、 script 色々処理 exit ってシェル内でうまく処理する方法ってないの?
同じではないが、近い方法でなら exec >foo 2>&1 とかあるが。
>>466 "&" でscriptコマンドをバックグラウンド実行させればいいのでは?
script &
色々処理
exit
ただしこの場合、scriptコマンドが投げっぱなしになるので、
・scriptコマンドの終了値を取得したい場合
・最終的にscriptコマンドの終了を待ってから呼び出し元のシェルスクリプトを終了したい場合
こういう状況なら少し工夫が必要だと思う
帰宅途中につきスマホしかないので試してないけど script script.log << EOF 色々処理 exit EOF とできた気がする
>>462 してないしてないw
シェルスクリプト走らすのにいちいちフットプリントのデカいbashなんか使わん
>>468 バックグラウンドで実行すべきはいろいろな処理の方だろ。
scriptは対話的に使うものだから。
"script" って名前のLinuxコマンドがあるんだね
The script command appeared in 3.0BSD.
475 :
自動再起動 :2011/09/07(水) 06:41:54.75
477 :
自動再起動 :2011/09/07(水) 17:03:35.86
>>476 Thanks! そういうスレがありましたね.でもしばらくはここで募集します.
open -g は使うと思うので,鍵は「このアプリは起動中?」を確かめるコマンドじゃないかと考えてる.
>>477 >このアプリは起動中?
普通はpgrepなんだけど
$ which pgrep
/opt/local/bin/pgrep
標準じゃなかったorz
>>477 launchサービスでコントロールしなよ。
$ EXPR="echo \"scale=2;8 / 10\" | bc" $ PERCENT=`${EXPR}` $ echo ${PERCENT} の結果が "scale=2;8 / 10" | bc って出力される .80 って出力を得たいんだけど、どこ直せば良いか教えてください。
eval ${EXPR}
>481 $ EXPR="echo \"scale=2;8 / 10\" | bc" $ PERCENT=eval ${EXPR} "scale=2;8 / 10" | bc $ echo ${PERCENT} "scale=2;8 / 10" | bc こうなっちゃいました。 なんか間違ってますか?
>>482 PERCENT=`eval ${EXPR}`
484 :
自動再起動 :2011/09/08(木) 12:33:32.60
>483 できた!さんくす!
>>468 さんのやり方だと、色々処理の中での出力がログに出ないような・・・
>>469 のやり方で、うまくいきました
> ・最終的にscriptコマンドの終了を待ってから呼び出し元のシェルスクリプトを終了したい場合
そうですね、色々処理の終了を待ってくれはしませんね
シェルスクリプトの中で、scriptコマンドを使ってログを取りつつ、何らかのコマンドの
実行結果のログを取って、それらのコマンドの終了後、scriptコマンドをexitで抜ける、
という作業をうまく行うやり方って、あるのかな?
exitで抜けた後に、取られたログをgrepとかで解析したりしたい
いま似たような事をしているシェルスクリプトは、例えばftpのログはリダイレクトさせて
ログに吐かせ、SQL*Plusの実行時はspoolでログに吐かせ、といちいちコマンド単位に
別々の方法でログに出力させて、一式集めたうえで解析しているのですが、
それをscriptコマンドで統一的に行うことができればなあと思いました
もっとうまくやりたいことをまとめられないのか。
set -xでよくね?
490 :
自動再起動 :2011/09/08(木) 23:25:14.75
>>479 >>486 の回答はありがたいが,勉強不足で理解できてません.
ちなみにUNIXシェルスクリプト逆引き大全333の極意の243番に
「特定のコマンドが実行されているかどうか調べる」
というのがある.それが何かは知らないが,
この場合,Macのアプリは「コマンド」には該当しないということですかね.
もし該当するならすぐ答えが出そうなものだから.
491 :
自動再起動 :2011/09/08(木) 23:32:52.83
おっと失礼.
>>486 のリンクがおかしくて,今まで OS X Developer Library の Getting Started
に飛んでいた.いま,再びクリックしたら具体的な項目に飛べた.
Thanks a lot! 読んでみます.
>>487 昔ながらの方法:
#!/bin/sh
exec 3>stdout.log
# stdoutをfd3に切り替える
exec 1>&3
exec 4>stderr.log
# stderrをfd4に切り替える
exec 2>&4
echo "ftp:"; echo "ftp:" 1>&2
echo "ftp log"; echo "ftp error" 1>&2
echo "sql:"; echo "sql:" 1>&2
echo "sql log"; echo "sql error" 1>&2
# 切り替えを復帰してfd3とfd4をクローズ
exec 3>&1 3>&-
exec 4>&2 4>&-
>>492 嘘書くな。
最後の2行で stdoutとstderrが復帰できてない。
あらかじめ fd1 fd2 を execで複製しておいてそれを復帰するべき。
>>493 なんか丁寧に書こうとして失敗してたね…
#!/bin/sh
exec 3>&1 4>&2 1>stdout.log 2>stderr.log
echo "ftp:"; echo "ftp:" 1>&2
echo "ftp log"; echo "ftp error" 1>&2
echo "sql:"; echo "sql:" 1>&2
echo "sql log"; echo "sql error" 1>&2
exec 1>&3 3>&- 2>&4 4>&-
echo "return"
echo "error return" 1>&2
>>487 scriptでやろうとしたり、
>>494 のような努力をするよりも、
TeraTermとかでログとって、まとめて取れたログをPC上で
解析すんのが、ぶっちゃけ一番簡単じゃね?
>>487 というか、その何らかの処理ってのをまとめて関数にしてしまえばすむ気がするのだが。
俺が勘違いしてるのかな?
awk(種類は問いません。インストールするので)で二つの表の処理したいと思っています。 表1 bad.com a3 ddfa.net a5 zdf.sj a13 aaa.com a222 表2 aaa.com sd zdf.sj tt bad.com tt ddfa.net sd 処理結果の表 bad.com tt a3 ddfa.net sd a5 zdf.sj tt a13 aaa.com sd a222 フィールド3の数字を昇順にソートした表にして、表2をフィールド2を挿入したい。 ※ワンライナーのPerlでも参考までにお願いします。
>>497 表1のフィールド1は、表2のフィールド1に絶対に存在すんの?
>>498 > 表1のフィールド1は、表2のフィールド1に絶対に存在すんの?
できれば、絶対存在しない場合の方が望ましいです。
存在しない処理のその項目には不明だかとか、そんな感じで処理されるとありがたいです。
>>497 $ cat tab1.txt
bad.com a3
ddfa.net a5
zdf.sj a13
aaa.com a222
$ cat tab2.txt
aaa.com sd
zdf.sj tt
bad.com tt
ddfa.net sd
$ cat awk.sh
#!/bin/sh
while read LINE
do
col1=`echo $LINE | cut -d ' ' -f 1`
col2=`echo $LINE | cut -d ' ' -f 2`
coln=`echo $col2 | sed s/^a//`
coltmp=`grep $col1 tab2.txt`
if [ 0 != $? ]; then
newcol='-'
else
newcol=`echo $coltmp | cut -d ' ' -f 2`
fi
echo $coln $col1 $newcol $col2
done < tab1.txt | sort -n | cut -d ' ' -f 2,3,4
/\___/\ / ⌒ ⌒ ::: \ | (●), 、(●)、 | / ̄ ̄ ̄ ̄ ̄ | ,,ノ(、_, )ヽ、,, | < やるじゃん | ト‐=‐ァ' .::::| \_____ \ `ニニ´ .:::/ /`ー‐--‐‐―´´\
>>500 あ〜あ、先に書かれちゃったw でも一応書いておこうっと。。。
ただ、表1のフィールド1が表2のフィールド1に存在することが前提だから
ダメだけど
$ paste -d" " <(sed 's/[ \t]\+/ /g' 02.tbl | sort) <(sed 's/[ \t]\+/ /g' 01.tbl | sort) | cut -d" " -f1,2,4 | sort -t" " -k 3.2 -n
>>500 awk or Perlでお願いします。
colnの意味が分かった
>>500 ,503
ここはシェルスクリプトスレだから…って思ってたら、やっぱりこうなったかw
自分も書こうと思ったけど、やらなくてよかったわ。
正直ソートはsortコマンドに投げたほうが良さそうだと思うんだ。
仕様で表1のフィールド2が重複するならawkだけだと面倒になる。
>>506 に答えてくれないから分からないけど外部コマンドも使って重複してても動くように書いた。
awk 'file != FILENAME { file = FILENAME; table++ }
table < 2 { t[$1] = $2; next }
{
n = $2; gsub(/[^0-9]/, "", n)
x = ($1 in t) ? t[$1] : "表2に無いよ"
print n, $1, x, $2
}' 表2 表1 | sort -n | sed 's/[^ ]* //' >処理結果の表
どのawkでも動く。動作未確認。sortに-k0が要るかも。
勉強になるな a222だのa13だのって、ソート無理じゃね?と思ってたが、こういうひと手間尊敬するわ
509 :
名無しさん@お腹いっぱい。 :2011/09/12(月) 16:17:47.89
やるなぁ
バイナリエディタの無い環境で、高々30数バイトのために インストールするのが面倒だったから、下のようなスクリプトを書いた #!/bin/bash IFS= printf "${*/#/\x}" 引数に並べた1バイトのヘキサを、バイナリに変換するだけなんだが ${*/#/\x} ← こいつがbash依存なんだよね 他の環境だったらどうしたらいいか、賢いやり方が思いつかないのだけど どういった方法があるかな?bash固有の機能を使わないようにしたい
いちばんどこでも使えそうなのはawkかな
for i in "$@" do printf "\\$(printf "%o" 0x$i)" done ってのはPOSIX shなら動くと思う
マジな話ポータビリティにこだわるのって本当に意味あるの?
>>497 亀レスですが perl で、こんなんどうでしょう?
表1を逆にしてハッシュ%cに、表2は%dにそれぞれ突っ込んでます。
perl -0777 -e '
%c=(reverse split(/\s+/,<>));
%d=(split(/\s+/,<>));
foreach $k(sort {($a=~/(\d+)/)[0]<=>($b=~/(\d+)/)[0]}keys %c)
{print "$c{$k} $d{$c{$k}} $k\n"}' tab1.txt tab2.txt
実行結果
bad.com tt a3
ddfa.net sd a5
zdf.sj tt a13
aaa.com sd a222
ありゃ、改行が変に... 空行は無視してください。
awkだとこれでいいのかな awk 'BEGIN{for(i=1;i<ARGC;++i)printf("%c",int("0x"ARGV[i]))}'
>>513 こだわる心がけそのものについては、殊勝であり意味はあるが、だがその行為には価値が無い
>>511 初めに考えたけど、これを思いついたから。awkも亜種が多いし
>>512 そういえばprintfはどのシェルでも内部コマンドで用意されてたっけ
1つずつ処理するのは時間がかかりそうって思ったんだが、そうでもないのか
>>513 こだわってる訳じゃなく手元にbashの無い環境もあったので
最終的に入力がワードサイズのリトルエンディアンだったことに気が付いて下のようになった
IFS=\
printf "`echo " $*" |sed 's/ \([^ ]*\) \([^ ]*\)/\\\\x\2\\\\x\1/g'`"
皆さんどうもありがとう
>>516 文字列を数値に直すとき0xを見て16進数と解釈するのはgawkの拡張じゃなかったかな。
perlだと sprintf("%c", chr(hex($_))) 辺りかな。
>>513 30代の漏れは大学自体は NEWS や SUNOS / Solaris, FreeBSD, Linux
と混沌とした混在環境だったからポータビリティに気を使ってたなぁ。
よく perl に逃げてた覚えが...
Perlってひとつの環境のバージョン違いぐらいしか基本的にないから、そういうときは何気に便利よね
機能に過不足があっても何とか代替手段を編み出せるOSコマンド群と、 モジュール不足で機能が欠損するperl環境を比較すると、perlもそんなに 便利じゃない 原理的OSコマンドセットかGNUのbinutilsかって違いよりも大きいだろ
シェルスクリプトのちょっとした補完(ここではバイナリ出力) という目的でLL使おうって話なんだから、 モジュールやらなんやらまで必要なプログラムの話じゃないだろ
「LL」っていう定着していない略語使う奴に限ってシェルスクリプトを使いこなせていない、の法則。
LLくらい定着してるだろ
デブが着るサイズの事だろ。
LL教室
>>524 uname の結果見て if 文書きまくって OS 毎にちゃんと動くようにするのは結構辛いぜ?
# 昔 echo -n するのに Solaris ならわざわざ /usr/ucb/echo って指定したり
# とか面倒な事してましたよ。
perl の機能欠損? /bin/sh だけだと機能欠損あるから grep/sed/awk とかを
使ってるわけで、 perl からだって grep/sed/awk とかを呼び出ししても良いわけだし。
何でもかんでも perl で書こうとしてるから不便に感じてるのでは。
llと言えば 'ls -l' のエイリアスかなと思う。
64bit定数値を代入する時は右端にちゃんと LL 付けろよ。 long long hoge; hoge = 123LL;
"””"とかだっせーw
"\"””\""とかだっせーw
llって、どのへんが起源なんだろうな 実現方法がOSによって違うからビビる
ls -l ってわざわざ別名でaliasするほどのものかなあ よく使うオプションをls自体にaliasしておいて、時々使うものは逐次指定でよくない?
わざわざっていうか、OS 側でデフォルトで設定してあったりする。
mjd
aliasで設定しているOSもあれば、llというコマンド(実体はlsのリンクだが)で提供しているOSもある
/etc/profileや /etc/profile.dにある設定って余計なお世話だから、 OS新規インストール直後に即攻で消すわ。 おまえらもそうだよな?
消さないよ。
消さずにリネームして無効にするっていう意味ね。
リネームもしないよ。
547 :
名無しさん@お腹いっぱい。 :2011/09/15(木) 18:50:05.32
使うサーバの数多いし自分だけで使うわけじゃないから なるべくツルシの状態で使うようにしてる。
商用OSかフリーOSかで違うなぁ。 商用OSなら/etc/profileとか考えられて設定されてるんだろうから、消さない。 フリーOSの場合、メンテナなりパッケーじゃなりの個人的趣味が /etc/profileに 書かれてたりするから、趣味の押しつけ拒否ですぐに消してしまう。
商用でもいーかげんな設定はあるし、 フリーでも考えて設定してあるのもあるし、 そんなの一概には言えんよ。
AIXやSolarisだと、いい加減というか、ほとんど何も設定してないでしょ。 HP-UXだと、Terminalの追加設定がprofileだったかに書かれてて、うかつに置き換えたりすると、「あれ?キーがきかねーぞ」とか言われたりするけど。
j jobs
k kill
l ls
とか、aliasで短縮している。
>>513 > マジな話ポータビリティにこだわるのって本当に意味あるの?
捨てプログラムなら何でも良いし、使用頻度低くて危険ではないプログラムならとりあえず自分の環境で動けばいいんじゃないの。
あとLinuxを使いつづけているとオリジナルのプログラムって自然と増えていくし、半年以上経ったプログラムをまじめに読み返したくないから
書きたい衝動のときにやれることはやっておくのがあとあと楽。
そういう話続けたいなら別のところで
aliasでやってんのかコマンドでやってんのかって違いは、下手するとシェルスクリプトの実行結果にの影響を与えるものだよ cronで動かしてるシェルスクリプトとかで
スクリプト内で短縮形を使うとかありえないw あと、特に意味もなく使う相対パスも。
>>538 そう思うけど過去にRed HatだったかVineだったかで/etc/profileにデフォルト設定されてたのよ。
la='ls -a' とかな。
変な癖ついちゃうと後々面倒だから使わなかったけど。
だからメンテナなりパッケージャなりの個人的趣味の /etc/profileは 即攻で消すべきなんだよ。
いきなり消すことないじゃん。 インストール後に速攻rsyncで/etcと$HOMEをコピーして、当分の間残しておく。
>>557 そうなのか…そういう鳥があったなら仕方ない。
俺はその辺から入った身じゃないけど、その辺から入ってたら確かにaliasしてたかも知れんな。
561 :
名無しさん@お腹いっぱい。 :2011/09/28(水) 23:09:14.82
./test.sh "a a" "b b" "c c" とスペースありの 引数を複数指定してシェルスクリプトを起動して、 さらに、 test.sh では、 ./test2.sh "a a" "c c" と引数 "b b" を削って、別のシェルスクリプトを起動します。 初めの test.sh に渡される引数の数が不定で、 "b b"がどこに現れるかも不定の時、 引数 "b b" だけを抜いて、 test2.sh の引数としたいのですが、どうしたらできますでしょうか?
>>561 #!/bin/bash
argv=("$@")
for ((i=0; i < $#; i++)) {
case "${argv[i]}" in 'b b') unset argv[i];; esac
}
./test2.sh "${argv[@]}"
563 :
名無しさん@お腹いっぱい。 :2011/09/28(水) 23:26:47.27
>>562 ありがとうございます!
が、ホントすみませんが、shでお願いします。
>>561 #!/bin/sh
n=$#
while [ "$n" -gt 0 ]; do
if [ "$1" != 'b b' ]; then
set "$@" "$1"
fi
shift
n=`expr $n - 1`
done
./test2.sh "$@"
565 :
名無しさん@お腹いっぱい。 :2011/09/28(水) 23:43:24.70
>>564 ありがとございます!
set "$@" "$1"
にはやられました。
ホント助かりました。
精進します。
setの意味がいまだに良く分かっていない俺
いいかい、setの活用は set set set。どの setかは文脈で判断するんだ。 ただし、三単現の場合は setsになるので、これも手がかりになる。
>>564 引数の中に -a -b -c とか含まれていると誤動作する。
set -- "$@" "$1"
だな。
常に set -- にする習慣を。
引数として渡された複数のテキストファイルに対して 各ファイルの冒頭に、ファイルのフルパス名を書いた簡単なヘッダを付け それらをcatのように連結させて標準出力したいのですが、どんな感じでやれば良いのでしょうか
#! /bin/sh for UNKO in `echo $*` do echo "Header: ${UNKO}" cat ${UNKO} echo "manko" done
ファイル名を相対パスで渡したらフルパスにならんな
>>570 ありがとうございます、とりあえずこれでも充分です
フルパスにする方法は自分で調べますね
>>570 フルパス以前の問題として、
in `echo $*` ってギャグかよ! スペース入りファイル名で誤動作しまくり。
in "$@" が常識。あるいは、for文では省略すると in "$@" の意味になる。
自分は与えられたファイルのフルパスを調べるとき、
>>570 に倣うなら、
FILENAME=`basename ${UNKO}`
PATHWORK=`dirname ${UNKO}`
FILEDIR=`cd ${PATHWORK}; pwd`
FULLPATH=${FILEDIR}/${FILENAME}
みたいな感じに順々にやってるけど、なんかサクッと取得する方法って、ある?
FreeBSDやUbuntuにはデフォでrealpathが入ってたような気がするし Linux系列ならreadlink -fでおk
bashで local A=aaa と local -i A=aa の違いは何なのでしょうか?
man bash
>>573 ってことは、相対パスの場合
for S do
echo "<<<<< ${S} >>>>>"
cat ${S}
done
が最適解ですね、ありがとうございます
doの前に;
相対パスの場合、 ファイル名として -n とか -v とかが含まれていると cat "${S}" が面白いことになるw
>>575 readlinkか…何気に今日最大の収穫だわい
>>581-582 ってことは、こんな感じですか?
for NAME; do
echo "ヘッダ${NAME}"
cat "-- ${NAME}"
done
惜しい!
ボーンで、配列って使える?くぐってもわからんかった。
bashとかじゃなきゃ無理じゃなかった?配列っぽく変数を扱うことは出来るが
とつぜんだがちょっと関数書いたので貼ってみる gengou(){ TMP_LANG=$LANG ; LANG=ja_JP.UTF-8 ; export LANG ; case $1 in [0-9]*) echo $(if test $1 -gt 1988 ;then echo '平成'$(expr $1 - 1988 ;) ; elif test $1 -gt 1925 ;then echo '昭和'$(expr $1 - 1925 ;) ; elif test $1 -gt 1911 ;then echo '大正'$(expr $1 - 1911 ;) ; elif test $1 -gt 1867 ;then echo '明治'$(expr $1 - 1867 ;) ; else echo '西暦'$1 ; fi ;)'年' ; : ;; [[:alpha:]]) echo "USAGE $0 1" ;; esac ; LANG=$TMP_LANG ; } どうかな?明治以降で申し訳ないが
行末の;がキモ過ぎ
元号は元日から変わるわけじゃない。
そうだね他に何かある?
ボーンで使えない $( ) とか [[:alpha:]] は使うべきじゃない。 逆に、ボーン対応しなくていいなら、遅いexpr使わずに $(( )) を使うべき。
case文で [0-9]*) で判定してるけど、3hoge とかでもマッチするぞ。 正規表現と勘違いしてる? case文で場合わけするなら、残りは *) でデフォルトにするべき。 シェル関数内の $0 はシェル関数名を表さない。(もとのシェルスクリプト名になる) なので、USAGE $0 とか書いてるのはおかしい。
596 :
名無しさん@お腹いっぱい。 :2011/10/15(土) 07:49:31.32
「もし、当該ファイルに、指定した正規表現が含まれているなら、次の処理を実行する」 というような時、どのように書けばいいでしょうか?
>>596 if egrep '正規表現' file > /dev/null 2>&1; then
次の処理
fi
grep -qs -e regexp file && hogehoge
>>598 grep の -q や -s オプションはバージョンによって使えなかったり
挙動が異なったりするので、-q -s を使わずに /dev/null にリダイレクト推奨。
>>597 thenの前に ;
>>597 ,598,599
ありがとうございました
$PATHに、とあるパス($PWD/bin)を追加したいのですが、 $PATHに存在しない場合だけ追加したいです。 それで、あるパスが$PATHに含まれているかどうかを調べるにはどのような方法がいいでしょうか。 if `echo $PATH | grep "$PATH/bin"`; then export $PATH=$PATH/bin:$PATH fi こんなのでいいでしょうか。
>>601 内部コマンド(case文)だけでやった方が良い
case ":${PATH}:" in
*:"$PWD/bin":*)
;;
*)
PATH=$PWD/bin:$PATH
;;
esac
windowsサーバのMRTGをunixで作ってます unixサーバはMRTG出来てるんだけど、シェルスクリプト使って値取得してます unixに合わせて欲しいと言われたのでスクリプトやろうとしてますがプログラムほとんど分からなくて困ってます メモリとcpuとハードが対象で、メモリは%表示でcpuと一緒に一つのグラフに載せてて、MIB取得とグラフ表示は出来てます 出来てるunixのスクリプトの中身を見るとMIB値を取得して変数に入れて除算とかしてるようです どなたか助けてください
いや。助けろって言われても俺に具体的に何をしろと? とりあえずその「出来てるスクリプト」を読んで同じように書けばいいだけのような。
>>604 監視対象が Windows で値をとってグラフにする側が UNIX ってことでしょ?
別に相手が UNIX だろうが Windows だろうが SNMP で MIB の値をとってくる
ことに変わりはないと思うぞ。
もちろん OID が違うだろうから OID のところだけ変えてやればいいだけなんじゃないか?
# 軽くググった感じでは Windows XP の CPU 使用率とかの OID がでてくるけど。
>>605 >>606 そうです。windowsのMIB値取得して、unixでグラフ表示です
スクリプトの中身もsnmpwalkでMIB値を変数に入れて計算させてるようなので、MIB値変えてやってみます
ありがとうございます
608 :
名無しさん@お腹いっぱい。 :2011/10/18(火) 08:35:04.55
配列を各変数に一度に代入したいのですがどう書けばいいのでしょうか? イメージとしては a,b,c=array('a','b','c') のようなことをしたいです
>>604 です
何度も申し訳ないのですが、助けてください
OIDを変えたりいろいろやってみたのですが、いまいちうまく動いてくれません。
下記がまともに動いているunixのスクリプトです
※一度に入らないのでいくつかに分けます
##!/bin/sh
SNMPWALK="/usr/local/bin/snmpwalk"
COMMUNITY="${1:-public}"
HOST="${2:-localhost}"
CPU1=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
ssCpuUser.0 2> /dev/null | awk '{print
$4}' 2> /dev/null`
X=`expr "$CPU1" : '\([0-9][0-9]*\)'`
if [ $CPU1 != $X ]; then
echo "0";echo "0" ; exit;
fi
CPU2=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
ssCpuSystem.0 | awk '{print $4}'`
USAGE1=`echo "( ${CPU1} + ${CPU2} ) * 10" | bc`
>>609 の続きです
MEM1=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
memTotalReal.0 | awk '{print $4}'`
MEM2=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
memAvailReal.0 | awk '{print $4}'`
MEM_FREE=`echo "scale=3 ; ( "${MEM2}" / "${MEM1}" ) * 1000" | bc | cut -d\. -f1`
USAGE2=`expr 1000 - "${MEM_FREE}"`
if [ "${USAGE1}" -lt 0 -o "${USAGE1}" -gt 1000 ]; then
USAGE1="0"
fi
if [ "${USAGE2}" -lt 0 -o "${USAGE2}" -gt 1000 ]; then
USAGE2="0"
fi
echo "${USAGE1}"
echo "${USAGE2}"
exit 0
>>609 がCPU処理
>>610 の最初がメモリ処理
最後がifでの分岐と最終結果の表示になってます
CPUについてはOIDを 「hrProcessorLoad」 にしたのですが
どうやら取得できているようです
メモリについては 空きメモリ / トータルメモリ * 1000
をやって使用率をパーセント表示させているようです。
ただ、windowsのsnmpだとトータルメモリが一発で取れないため
MEM3=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
hrStorageSize.5 | awk '{print $4}'`
MEM4=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
{hrStorageAllocationUnits.5 | awk '{print $4}'`
MEMtotal = "${MEM3}" * "${MEM4}" を追加してトータルメモリを取得してます
同様に使用メモリも算出して
空きメモリ = トータルメモリ - 使用メモリ としてます
そして、最後に 空きメモリ / トータルメモリ * 1000
で後は使いまわしているのですが、うまくいきません。
そもそもやり方としてはあっているのでしょうか?
bcに-lがない。突っ込みたいところはあるけど仕事だろ?じゃあ寧ろ弄らないほうがいい
着信したメールをパイプして、Subject: が特定の文字(例えばrequest)なら
本文を標準出力に出すスクリプトを書きたいんですが、考え方が良く分かりません。
ちなみにメールは
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1
MIME-Version: 1.0
To:
[email protected] Subject: Test
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit
This is test mail.
-
Subject: が Test で
本文が This is test mail. です。
>>613 procmail 使え、とかそういう話?
615 :
613 :2011/10/19(水) 19:42:40.82
>>614 postfixで返信を考えてるんですが、aliasesでメール内容をスクリプトに
パイプすることはできるんです。
パイプで渡された内容は、引数として扱えるのでしょうか?
標準入力に入る。
>>611 純粋に snmpwalk でこけてるだけでしょ?
snmpwalk 単体で実行して値が取れるところまで頑張ってくれ。
snmp の話でスクリプト関係ない。
板違いなんで一旦終わりの方向で。
板違いだが一応指針だけ。
もう一度 Windows で CPU 使用率とる OID 調べてみろ。
俺が見た限りだと SNMP4NT とやらをインストールして、
.1.3.6.1.4.1.311.1.1.3.1.1.2.1.3 あたりのどっかの値をとるみたいだ。
ちなみにロード(ロードアベレージ)はかなりの確率で君のほしがって
いる値ではないであろうと推測される。
>>613 Subject: に Test が含まれるメールのみ、その本文(のみ)を標準出力に出すスクリプト
#!/bin/sh
sed -n '1,/^$/{ /^Subject:/{ /Test/!q } }; /^$/,$p'
619 :
名無しさん@お腹いっぱい。 :2011/10/19(水) 20:40:06.76
>>613 RFCに従ったメールであれば、「ヘッダ部+空行+本文」の構成なので、
本文のみを抜き出したければ、最初の空行以降の文を抜き出してみそ。
そっとしといてやれ。
>>617 MIB値が正常に取れてなかったです
今日朝イチでケアレスミスを見つけて、そこ直したらメモリとCPUの%とれました
板違いで本当にすみませんでした
教えてくださりありがとうございます
623 :
613 :2011/10/19(水) 22:55:23.44
>>619 ありがとうございます。
一行ですむんですか
まだ、しっかり理解できないので、勉強してみます。
結局お礼もらったのは「抽象概念」だけ書いた方じゃないかw
昨今のメールだと、Subject がエンコードされてて 1行じゃ済まない気がしますが…
質問です シェルで、代入するときに、変数名を可変にすふことは可能でしょうか? array_$1=$some_value みたいにして、配列のようにあつかいたいのですが…
>>626 可能。
eval array_$1=$some_value
>>626 Bシェル系に従ったシェルであれば、「左辺変数名決定→変数展開」の順なので、
展開後に左辺変数名として解釈させたければ、evalを付けて実行してみそ。
あれじゃマルチパートのメール着たら死亡だけどねえ。
boundary指定のメール来ることも考えるのなら、
専用のモジュール使ってperl, python辺りで書いた方がいいよ。
今は
>>613 みたいな古典的な形式のメールばかりじゃないからね。
>>625 >>631 元の質問
>>613 は、
システムの遠隔操作等で
「自分で」特定のSubject:(半角英数)のメールを送って操作したいということだから、
SubjectがMIMEエンコードされてたり複数行の場合とか、
マルチパートのメールについては考えなくていい。
633 :
625 :2011/10/21(金) 09:58:20.71
>>632 だんだんとスレチになってきたけど…
User-Agent が Thunderbird だから、エンコードを知らない古の mail コマンドや
telnet コマンドでmail するときのように自分で Subject をゴリゴリ書いてないのが気になります。
「自分で」アラートメールを送らせて監視するシステムっぽいというのは判断できますが
メールクライアントは、そのアプリの判断で MIME エンコードしますよ。charset=ISO-2022-JP だし。
仕事で作ったとなると「日本語のほうが分かりやすいだろ」とかで仕様変更されトラブることも考えられる。
あえて言えば、勘違いさせるサンプルが悪い。そして俺必死すぎ。
そういうのは本人が考えることだから 議論してもしょうがない。
>>633 メールクライアントはThunderbirdだと特定できてるのだから、
Thunderbirdは英数文字のみのSubject:をMIMEエンコードしない。
(たとえcharset=ISO-2022-JPでも)
RFC 2047 の話題なので、スレチ
>>632 > 元の質問
>>613 は、
> システムの遠隔操作等で
> 「自分で」特定のSubject:(半角英数)のメールを送って操作したいということだから、
どこにそんなこと書いてあるの?
ちょっとびっくりした。それとも
>>613 本人なのか?
なんか日本語読解力ない人が居ますねぇ〜
「操作する」と「出力する」は全然違うんだが。
>>639 読解力のなさをわざわざアピールしなくていいよw
また質問者不在のまま荒れて行く。
>>640 「出力する」を「操作する」と誤読したボンクラのレスなど読解する必要は無い。
>>642 「出力する」のは何の為か、って読解力もないのかねw
メールボックスのフィルター捕まえて、 「遠隔操作」って言葉が最初からおかしい。
>>644 えっ?
メールボックスのフィルターの話じゃないんだけど・・
>>615 読めよ。
aliasで| cmdしたいんだろ。
質問者を置いてきぼりにしたくだらない揚げ足取りって、 すっかりこのスレの名物だね。 この板の他のスレではめったにないのに、ここだけは日常的にやってる。
ここだけじゃないだろ ○○システムズ最後の○○ のスレで毎日やってる
649 :
613 :2011/10/22(土) 08:27:38.00
やっと、sed -n '1,/^$/{ /^Subject:/{ /Test/!q } }; /^$/,$p' の意味が
分かって帰ってきました。なにかお騒がせしてたみたいですいません。
>>618 ありがとうございました。
とりあえず、Subject: は英文のみ、本文は最初の1行のみを有効にするつもりです。
sedはどうも、一般のシェルとは様子が違うようでなかなかわかりにかいですが
Retrun-Pasth: と 本文を変数に代入することって出来ないでしょうか?
>>637 よ、
>>649 ↓のカキコ見たかい?
> Subject: は英文のみ、本文は最初の1行のみを有効にするつもりです。
やっぱり質問者は制御メールに関する質問をしていたわけだ。
(メールボックスのフィルターの話じゃない)
読解力のなかった
>>637 は謝罪会見開け。
バカが必死すぐる。www
>>649 凝ったことやりたいならperlか何かで書いた方がいいんじゃないの。
そういうこと言う奴に限って、「じゃあperlで書いて」と言ったら書けないんだよなw
そうでもないよ。
>>649 ちょっと時間がないので概念だけ、
sedを使わずに、/bin/shの while read arg1 arg2 でメール全体を行ごとに読んで回す。
case $arg1 で場合分けして、Subject: やRetrun-Path: の時、
arg2の値を変数にコピーして記憶する。
$arg1が空文字( '' )の時はヘッダーの終了なので、
その場で再度 read body ってやると、"$body" にメール本文の最初の1行が入る。
ここで breakでwhileループを中断する。
656 :
613 :2011/10/22(土) 09:48:18.87
>>652 Postfixのaliasが、メールのテキストをパイプで渡すみたいねんですが
シェルにしても、perlにしても標準入力を変数に代入するにはどうすればいいですか?
どうもこのパイプからの入力の扱いが理解できて無いもので
read使う。
俺は656の質問に答えただけだけど。
>>655 をコーディングすると、以下になる。
#!/bin/sh
while read arg1 arg2
do
case $arg1 in
Subject:)
subject=$arg2;;
Retrun-Path:)
return_path=$arg2;;
'')
read body
echo "$subject"
echo "$return_path"
echo "$body"
break;;
esac
done
ただし、while文を抜けるとサブシェル問題で変数が元に戻る問題は別途対応のこと。
661 :
613 :2011/10/22(土) 11:01:19.56
>>655 660
なんとなく分かったような
また、しばらくもぐりこんできます。
ありがとう
謝罪とか何とかはよそでやってくれよ。邪魔。
>>650 何ら立証できてないのに、バカがはしゃいで勝ち誇ってる。哀れすぎる。
>>666 >>649 (質問者本人)
> Subject: は英文のみ、本文は最初の1行のみを有効にするつもりです。
↑
この質問者本人からの1文で,完璧なまでに
>>666 の敗北が立証されたねw
それとも
>>666 は読解力がないから、自分が敗北したことも理解できてないのか?ww
捌くメールの数が大したことないなら1パスにこだわらずに、 subject=`sed -n '1,/^$/s/^Subject:\(.*\)/\1/p' "$FILE"` returnpath=`sed -n '1,/^$/s/^Return-Path:\(.*\)/\1/p' "$FILE"` body=`sed -n '/^$/,+1p' "$FILE"` としてもいいんじゃないの? 多い場合は舐めるデータ量より、sedの三回起動のほうが問題になるはず。
>>656 上のようにstdinを三回舐める時は、
cat > /tmp/foobarbaz$$
/tmp/foobarbaz$$に対する処理
rm -f /tmp/foobarbaz$$
とすればいい。
1パスの解答
>>660 の後に 3パス(しかも一時ファイル必要)の解答する
>>668 って・・・
>>667 精薄哀れすぎる。 www
それだけで制御と決めつけられる単純な思考しか出来ない事を
そんなに必死になってアピールしなくてもいいんだぞ。
>>670 必要なかったかね。
仕様では:の後はスペースなくても構わないので、
(その辺は説明せずに)つい書いてしまったわ。
IFSに:を加える修正したほうが良かっただろうね。
>>670 くだらねーツッコミしてるお前よりかは、
建設的というか有益なんじゃね?
findコマンドでカレントディレクトリからファイルを探す場合、 find . -name '*.html' としますが、これだと ./views/foo.html のように、頭に「./」がついてしまいます。 今はsedを使ってこれを取り除いているのですが、find自体でこれをつけないようにすることはできませんか。
>>674 GNU findで、 -printf %P
find * -name '*.html' で行けるかなと思ったけど、ドットで始まるディレクトリ が検索対象にならないからダメでした…
>>675 うう、Macだからgnu findではなかった。。。
linuxだったらいけるんでしょうね。残念!
678 :
名無しさん@お腹いっぱい。 :2011/10/24(月) 18:16:30.00
前の担当者(フランスに渡米中)が書いたシェルに、 ↓みたいなのがあるんだ。 exec 3<&0 exec < ファイル while read line; do ほげほげ; done exec 0<&3 これ、何でわざわざ execとか使ってるの? なんか意味あるの? while … done < ファイル って書けばいいんじゃないの? 担当者が書き方知らなかったんでしょうか?
使ってみたかったんじゃない。「exec使ってる俺ってステキ!」みたいな
>>680 そんな深い意味があったのですね。ありがとうございました。
あやうくシェルを書き直すところでした。
b
シェルってゆーな フランスに渡米中するな
シェル自体を書き直すのは尊敬するなあ 普通はシェルスクリプトの修正で済ませるだろうに ぐらいにしとき
この中に何問くらい 学校のレポート課題があるんだろう…
今時学校のレポート課題にシェルスクリプトを書けってのはそんなにないんじゃない?
>>589 みたいに何の役にも立たないスクリプトなら見ただけで学校の課題って分かるけど。
そうだ。
128bit の数値って、シェルでそのまま扱えたでしょうか? expr だと 32bit まででした…IPv4ならともかく、IPv6が…
今のバージョンの GNU expr は 128bitでも行ける。
bcでも使えばいんじゃないの。
ldd expr したら、 libgmp とリンクしてるじゃん。 こりゃ、128bitどころか、10進で1万桁とか100万桁とかでも行けるわ。
>>692 う〜ん、GNU…最新版に更新させてくれるかなぁ…
できなきゃ、やっぱり桁毎にわけて管理するトリッキーな方法を採るしかなさげ…
>>693 あ、bc だと 64bit までいけましたが、128bitになると途端に挙動がおかしくなってくれまして。
libgmpってお絵書きソフトのライブラリだっ毛? それがbit数とどういうご関係で??
gimpとgnu mpは違うものとマジレス
>>697 dc は対話モードだけかなぁなんて思ってたので、挫折してました…。
128bit が扱えるなら、もうちょっと頑張ってみます。
IPv6アドレスの処理ならビット演算くらいしかしないでしょ。 16bitに分けて計算すれば? それとも足し算して桁上がりとかあるのかい? v6なら16bitバウンダリ以外で区切る状況は少ないでしょ。
701 :
691 :2011/10/27(木) 18:54:44.18
みなさま、ありがとうございます。
>>700 四則演算するというより、ソート目的ですね。
ip2long的な(これはPHPですが)。
単純にできれば、それに越したこと無いと思います。
シェルでソートしちゃうの?
703 :
691 :2011/10/28(金) 00:26:42.49
$ sort -n で…と思ったましたけど、sort コマンド自体 128 bit を扱えそうにないことに 今更気づきましたよ。ダメじゃん。 素直にトリッキーなシェルスクリプト(16bit毎に計算するタイプ)組んでおきます orz 128bit 空間は、デカすぎ
省略なしの文字列にしたらsortで比較できるでしょ
bashで別サーバのファイルリスト取得したいんだけどftp&ls使うのが良いのかな? 他に良い方法ある?
ふつー ssh 別サーバー ls -laR /
ああそっか一回入っちゃえば良いか 「別サーバの情報取得」みたいに考えちゃってたのが不味かったか 回答ありがとうございます
FTPだって「一回入っ」てね?
ftp でやるなら ncftpls でやると少し楽だよ まぁ、ssh できるなら間違いなく ssh つかうけど
rsh のように ssh を使えるなんて、、、
もともと rsh のセキュア版じゃん。
712 :
名無しさん@お腹いっぱい。 :2011/11/02(水) 00:02:17.09
文字列の先頭を小文字から大文字に変えたいんですが、どうすればいいですか? イメージ的には echo hello | hoge とやれば、 Helloが出力されるみたいな。
echo hello | sed -r 's/(^[a-z])/\U\1/'
へえ、sed -rだと\Uが使えるのか echo hello | sed 'h;s/\(.\).*/\1/;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;G;s/\(.\)../\1/'
誤解してるようだけど-rは () NO
誤解してるようだけど-rは()の前の\をなくすためだぞ。
\UってGNUかなんか?
ああほんとだ GNU依存だね
じゃあPOSIXの範囲で echo hello |awk '{print toupper(substr($0,1,1))substr($0,2)}'
シェルスクリプト内でexportしたい場合って どうすべきなのでしょうか・・・ 普通に #!/bin/sh OUT="$HOME/bin" export OUT というスクリプト(test.sh)を作って パーミッションを755なんかに設定して ./test.sh このように実行しても シェル内の環境変数にはセットされないですよね? source test.sh とすれば環境変数にはセットされますが exitできなくなったりで不便で・・・
>>720 sourceしたスクリプトでexitすると元のシェルが終了してしまうという問題なら、
exitの代わりに returnを使えば桶。
微妙にスレチかも知れないんですが教えてください mysqladmin ping とかでmysqlのインスタンスが起動しているか否か判別出来ると思うんですが、 例えばインスタンスが起動していない場合でも mysqladmin ping > a.log とかやっても実際はエラーが出力されるのにテキストにはこの場合、何も出力されません。 何か良い方法ありませんか?
> a.log 2>&1 という話か?
>>723 おおー!!エラーは出力が別なのか…知らなかった!
ありがとうございます
sedで、"を置き換えたい場合は、sed 's/"//'のようにして、 'を置き換えたい場合は、sed "s/'//"のようにしてますが、 'も"も置き換えたいという場合は、みなさんならどうしますか?
$ sed "s/['\"]//g" ...
>>726 シングルとダブルを逆にしてみたらこうなった。
$ echo morning\'noon\"night | sed 's/["\']//g'
>
不思議。。。
[ の直後の1文字は特別扱いされる
単純にシングルクオートの中だからエスケープされてないだけでは?
sed -e 's/"//' -e "s/'//"
俺なら面倒だから全体あるいはその部分をクオートからはずす sed s/[\"\']//g sed 's/['\"\'']//g'
シェルスクリプトの超初心者です。 linuxマシンからリモートのlinuxマシンに対して ローカルマシンからsshでリモートログインして、リモートマシンのシェル上での操作を連続して実行するシェルスクリプトを 作成したいと考えているのですが、それは可能なのでしょうか。 ローカルマシンでssh等のコマンドをシェルスクリプトで連続して実行できますが、ログインしてからの操作を、どう 書いたら良いのか全くわかりません。これって原理的に無理なのかな?と思ってしまいますが・・・。 ヒントをいただけると助かります。
>>732 -----
#!/bin/sh
hostname
whoami
-----
↑というスクリプトをリモートで実行したい場合、
-------------------------
#!/bin/sh
ssh リモートホスト '
hostname
whoami
'
-------------------------
全体(複数行)を ' ' で囲んで中にコマンドを書く
>>733 さっそくコメントありがとうございます。
さっそく試してみたいと思います。
>>733 #!/bin/sh
ssh remotehost /bin/sh -c '
hostname
whoami
'
でしょ
>>735 確認してから書き込め馬鹿。
>>735 だと、
「/bin/sh -c」
「hostname」
「whoami」
という3つのコマンドが個別にremotehostで実行される。
で、「sh -c」で
sh: -c: option requires an argument
ってエラー出る。残りのhostnameとwhoamiは、
/bin/sh -c を通さずに sshのログインシェルで直接実行される。
で、結局 /bin/sh -c の意味がないので
>>733 で良いことになる。
>>736 「動かない場合がある」じゃなくて、もともと期待通りに動かない。
apt-get install hoge などが並んだスクリプト作ったのですがいちいち[y/n]で入力を求められます ここでy自動的にを入力とかできるんですか?
apt-getなら-y | -yes | --assume-yesあたりのオプション使えば良い
ありがとうございます
a="foo\nbar" のような変数をフィルターしたい場合はどうすればいいんでしょうか? とりあえずechoを使って echo $a | head -1 としていますが他に書き方がありますか?
echo "$a" | (read b; echo "$b")
>>737 >>733 の前半のスクリプトは確実に /bin/sh で実行されるのに対して、
後半はリモートホストのログインシェルで実行されるんですよね。
/bin/sh で実行したいときはどうしたら良いですか?
実行されるシェルが違ったら同じスクリプトを実行しても結果が同じとは限らないからな〜 バカはどっちかなぁ
>>744 こうじゃね
ssh remotehost sh -c "'hostname
whoami
printenv'"
>>744 ssh remote-host 'sh -c \'なんだ; かんだ\''
いまどき ログインシェル≠/bin/sh なんてユーザーはいないから。 少なくともリモートログインする鯖は ログインシェル=/bin/sh 以外あり得ない
>>747 それちがうよ。シングルクォートの中はバックスラッシュでエスケープできない
>>748 えっ?逆に今どきだからログインシェルzshとかあるだろ?
/bin/shの実体がbashだったり、posixシェル(といいつつksh)だったり。
>>746 でFAで良いんじゃないのか
よー分からんが
echo 'hostname whoami' | ssh remotehost sh
>>756 それだと、rm -i のように標準入力を読むコマンドがあった場合におかしくなる
>>757 /bin/shで実行されなきゃいけないスクリプトだったとしても
/bin/shで実行される保証のない
>>733 よりはマシだと思うな。
つーか、流しこむスクリプトがshじゃなくてperlだったりなんだったりする 可能性を考えると、 scp hoge.sh remotehost:/tmp/ ssh remotehost sh /tmp/hoge.sh ssh remotehost.rm /tmp/hoge.sh がいちばん汎用性が高くて確実だな。
>>760 添付ファイルを作っちゃうと美しくないし、
複数のプロセスで同時実行した時干渉する。
添付・・・?
ネタニマジレ(ry
結局、ログイン先のシェルも指定でき、且つどんなコマンドも実行出来て余分なゴミファイルを作成しない模範回答はどれよ?
(echo ""; sleep 1 echo "コマンドをつらつら記述"; sleep 1 echo ""; sleep 1 echo "exit") | telnet (ホスト名かIPアドレス) むかし、こんなやりかたでメールを送ってたことがある…(もちろん記述内容は違うけど)
最初にsleep 1する意味が分からん
実際やってみるとわかるけど、適度に sleep を入れないと取りこぼす。 っていうか、1秒でもよくコケる。 結論: telnet は使いものにならないから nc を使え。
>>767 SMTP みたいに "会話" する場合は expect がいいんだが、マイナーだからみんな知らないのかな。
昔作ったメール送信用 expectスクリプトの一部晒しとくわ。 興味持ったら勉強してみるといい。
spawn telnet localhost 25
expect -re "220 .*"
sleep 0.3
send "HELO localhost\r"
expect -re "250 .*"
sleep 0.3
send "MAIL FROM:
[email protected] \r"
...
>>768 昔作っただけあって、EHLOじゃなくてHELOですがそうですかとか、
expectはもちろんみんな知ってるけど、いまどきexpectはスマートじゃないので
なるべく避けるのと、SMTPなら curlコマンドの smtp://mailhost とかでできるので
そっち使った方がいいとか、まあそんなとこだな。
rsh remote-host sh -c ' 頑張って 中身は クオートしながら書いてくれ’
772 :
768 :2011/11/14(月) 23:03:22.81
>>769 curl で SMTP できるのは知らんかった。 勉強になります。
今時は expect は使わないのか... で何使ってるん?
>>771 だから
>>737 はログイン先の
シェルを指定してないから
予期しない動作をする可能性があるだろ。
逆にログイン先のシェルに手元のシェルを合わせたらいかんのか
>>773 ログイン先のシェルはBシェル系と考えて良い
少なくとも、自分がアカウントを持っているログイン先なんだから
「予期しない」わけがない
あと、発想を変えて、
/bin/shをログインシェルにしたアカウントを別に作ってもいいわけだし。
「リモートはUNIXじゃないかもしれない」とか切りないので、 適当な仮定を考えるセンスが必要。 話は変わるが、コマンドを区切るのに改行派が多いのに驚愕。 俺はセミコロン派。
>>776 ワンライナーでシェルスクリプト書くのか?
やりたいこと: 「git merge」を必ず「--no-ff」つきで実行したい 方針: function git {} を定義し、引数に「merge」があった場合にそれを「merge --no-ff」に置き換えて実行する Perlで書くとこんなかんじ sub git { my $i = 0; for (@_) { $i++; if ($_ eq "merge") { slice(@_, $i, 0, "--no-ff"); last; } } my $command = join(" ", @_); `$command`; } わからないこと: shell関数の書き方、特に slice と `$command` の方法 function git { for i in $*; do # どう書けばいいの? done } だれか教えて!
>>778 function git {
n=$#
while [ "$n" -gt 0 ]; do
set -- "$@" "$1"
if [ "$1" = 'merge' ]; then
set -- "$@" --no-ff
fi
shift
n=`expr $n - 1`
done
command git "$@"
}
>>779 なにこれすごい・・・
sliceのかわりに、配列の要素を循環させていくのか。すごいテクニックですね。
ありがとうございました。
bashです。
up()
{
curl -F "file=@$1;filename=$(basename $1)" -X POST
http://www.example.com/upload.cgi }
up manko.jpg
で417エラーが返ってくるのですが、curlに追加すべきオプションは何でしょうか?
それともアップロードCGI次第なんでしょうか。教えてください。
CGI次第。
>>782 つまりCGIを変更しない限りシェルスクリプト側ではどうにも出来ないという事ですか?
それもCGI次第。
>>784 シェルスクリプト/CGIを含めて、一番スマートなファイルアップロードの
仕組み・書き方を教えてください。
最初からこう聞けば良かった。
scp
scp は認証もあり十分複雑だと思う。 ftpで
インデントはスペース何個分が一般的ですか?
>>785 その聞き方だと話が拡散するぞ。
もうちょっと状況を絞ってくれ。
>>789 すみません。CGIと出しているので、scpやftpがくるとは思いませんでした。
具体例を書きます。
1)アップロード先サーバはフリーのレンタルサーバ。SSH不可。FTP/CGI(perl)可。
2)CGIアップローダは既存のものが使えたら良いが、自前で準備することも可。
3)クライアント側のポートフィルタの関係上、HTTPでファイルをアップロードしたい。
4)curl/wgetなどの一般的なコマンドでbashベースのスクリプトでアップロードしたい。
5)アップロードするファイル(バイナリ)は、設備の温度ログ等なので秘匿する必要はない。
といった具合です。
ftpのPASVモードでええやん
>>791 ポートフィルタ以外にも、HTTP以外のセッションは張れないよう、プロトコルを監視して
フィルタリングしているので無理ですね。仮に使えたとしても、クライアント側にFTPパスワードを
記載しておけないので、FTPは使えません。
と、言いたいところですが、シェルスクリプト(curl/wget)でHTTPのPOST送信ってそんなに難しいものなんですか?
やたら、こちらが意図してないftpばかり勧めてくる方がいるので、不安になってきました。
(´・ω・`)
> 1)アップロード先サーバはフリーのレンタルサーバ。SSH不可。FTP/CGI(perl)可。 「FTP可」って書いてあるけど?
>>792 別に難しくないけど、
CGIによってどういうパラメータ渡せばいいかが違うから
「こうやればいい」なんて簡単には言えない。
だから一般的なscpとかFTPとかを勧められる。
まーそろそろ誰か教えてやれよw
スクリプトを自作するつってる時点でパラメータも糞もないだろw
>>793 >>792
「自作する」とは言ってないような。
799 :
797 :2011/11/16(水) 16:44:47.05
あ、CGIのスクリプトじゃなくアップロード側のスクリプトか。 だとしてもパラメータは関係あるじゃん。
試してはいないが、CGI側が
<form method=POST>
<input type=file name=file>
<input type=submit>
みたいなフォームを処理できる場合
>>781 の-Fで十分な気もするが。
> "file=@$1;filename=$(basename $1)"
まさにこれがパラメータだよなぁ。
>>797 796じゃないが、対偶は常に成立するから「既存」じゃなくて
新たに作るのは事実だろう。「自」作かどうかは知らん。
>>792 問題はそもそも「417 Expectation Failed」なんだから、
Expectヘッダを上書きしてやりゃいいんじゃないの?
802 :
792 :2011/11/16(水) 17:38:35.43
ユーザーのパスワードを一括で変更したいです linuxのようにchpasswdみたいなのでリストから読み込むのを想定していますが、soiarisなので出来ません。 追加でツールを入れるのはNGです 出来れば、シェルスクリプトを叩いただけでアカウントリストを元にパスワードポリシーに沿ったパスワードを自動生成し変更してくれるのを想定しています。 ただし何度も言いますが追加でツールを入れるのはNGです。 誰か知恵をかして下さい
perlか何かで書いちゃえば?
TeraTermでマクロ書いてガシガシ通したって記事ならある
expectくらい入れさせてもらえよ
適当なLinux上でchpasswdでpasswdファイルを作成後、 ファイルをsolarisに転送してsolarisのpasswdとマージしろ。
>>803 Solarisでもバージョンによって入ってるツールに差異があるし
システム側で要求される仕組みも若干違うぜ。
9までか、10か11か、10ならどのバージョンなのか。
まさかいまさら1.1.2や2.xあたりってことはないと思うが
>>809 とりあえずは10でお願いします
10のどのバージョンかは見て見ないと分からないので即答は出来ませんが…
Solarisのpasswdコマンドには、 引数でパスワードを指定できる隠しオプション(manに載ってない)が あったような気がしないでもない。 passwd -? パスワード ユーザーネーム みたいな形式で
質問です。 viでプログラミングしているときに、=をそろえたい場合がありますが、何かいい方法ありますでしょうか? ---------------- aaa = 10 bbbbbbb = 11 c = 12 ---------------- ↑を↓のようにしたい。 ---------------- aaa = 10 bbbbbbb = 11 c = 12 ---------------- viでは出来ないみたいなので、シェルスクリプトで出来ないかなと考えた次第です。
すいません、、複数の空白文字が消えたようです。。 下の例では、=がそろっているイメージを出したかったのでした。
なんで vim 前提よ。 変数名なんてリファクタリングとかですぐ名前変わっちゃうので、 先頭の字下げ以外、揃えようという努力は無駄。
vim前提なのはvi=vimとなってるのがいくつかあるから。 一般的によく使われてるFedoraやUbuntuはvi=vimだったりするし。
ここはlinux板じゃないよ
プログラミングというものは、もはや統合開発環境でやるものよ実際 近頃の環境でシェルスクリプト作る場合は、そういった統合開発環境で書いてビルドすりゃ ターゲットマシンへの転送から起動からログ取得からできちゃうし、いわゆるステップ実行も できるし、変数の評価ロジックも確認できるしと、シェルでゴニョゴニョやる以上のことが できるものだよ 仮にターゲットマシン上でごちゃごちゃ弄っても差分は分かるし、それぞれの差分についても 取り込むかどうかの取捨選択もできる シェルを開いて各種コマンドの実行したり、manを見たりもできるし、満足したものができたら そのままプロダクトへのデプロイだのレポジトリへのコミットだのもできるものだよ
話それてるな。
>>818 スクリプトなんてプログラミングじゃないと申すか
いやまあ、人によって線引き違うから
何でも統合開発環境があるとは思わんほうがいいかと
>>812 shより、Perlとか使ったほうが楽そうだなあ
ただ、最近はイコール揃えるってあんまやらんと思うぞ
>>818 シェルスクリプトのIDEなんてあんの?
なに使ってるか教えてほしい
あんまりかまうな。
bashのシェルスクリプトで cp -R -- src dest のようにコピーしてたりするものがあるのですが --ってどういう意図があってやるものなんですか? 単なるオプションってわけでも無さそうですし・・・
>>825 srcが変数で、- で始まるファイルだった場合でもオプションと解釈されないように
するために -- を付けておく。
man bash に書いてあるよ。
たかだか3行のスクリプトなのですが、期待通り動いてくれません>_< #!/bin/sh TARGET=' -name "*.txt"' find . $TARGET #< もしや-nameと"*.txt"が1引数とみなされてしまっている?? findの行をeval find…に変更することで期待動作にはなったのですが、 どのように記述するのが正しかったのでしょうか?
>>830 #!/bin/sh
set -- -name '*.txt'
find . "$@"
>>829 それは cp の -- の話じゃなく bash の -- の話だよ。
>>827-829 レスありがとうございます。
CPのmanには
>>828 さんが書かれてる通り書いてありませんでした。
rmやbashには書かれてるんですね。
rmのmanでoptionの取り回しはgetoptを使っているという事が書かれており
getoptのmanを見たらなるほどって感じでした。
>>828 これ載せてもらうよう言った方がいいんじゃないの。
>>831 >>832 レスありがとうございます!
evalによる方法と"$@"による方法ですね。勉強になりました!
拡張子だけじゃ何とも言えないっしょ。 shやbashでのCGIは個人的には結構作ったりするけど 大規模になってくるとrubyとかpythonの方が楽なんだよな。当たり前だけど。
市立図書館なら何でもありそうだ。1秒に1リクエストしか捌けない物すらあったんだし CSVをgrep、awk、sedで検索、切り出し、整形してるだけかも
たんに表示するだけみたいだし いいんじぇね?
みんなでアクセスしてサーバが落ちたりすると、業務妨害で逮捕されますよ。
シェルスクリプト内で、 「telnet www.test.com 80」でtelnet接続し、 「GET /testurl」コマンドでリクエストを投げたいのですが、 どのようにしたらよろしいでしょうか?
>>844 wget とか curl とか fetch あたり使うとか。
netcat 使うとか。
perl か何かのライブラリ使うとか。
あ、telnet を使わなきゃいけないのか。 なら expect かなぁ。
>>844 test.comの中の人でもこんな基本的なことも知らないんだ・・・
select文で打ち込む数字を引数としても渡せるようにしたいのですができますか?
つ eval
>>847 何言ってるんだ?
>>844 はwww.test.comに(通常とは異なる手段だが)アクセスをしたいと
言ってるだけだぞ?w
test.comの中の人、日本語お上手ですね
こんにちは。 シェルスクリプトの中で su を実行して、パスワードを自動で入力したいのですが、 それって可能でしょうか。パスワードを無しにすることはセキュリティ上できないので いい方がないか悩んでいます。
はい、可能です。
>>844 telnetじゃないがbashならソケットも扱えたはずだから外部プログラムなしでも同じことができるはず
bashだけで頑張ればhttpdって実装できるかな?netcatやinetdを使った例ばかり見つかる
>>852 思いつく別の方法はsuで実行したいプログラムにsetuidする。オススメしないが
>>854 >>855 ありがとうございます。
シェルスクリプトではなく、python等のスクリプト言語を使う方が良いかも?と思いました。
どちらも全くの素人ですが、勉強してみます。
857 :
844 :2011/11/27(日) 13:25:18.87
curlで解決できました! エスパーな皆様ありがとうございました!
perl -e 'print $1 if /href="(¥d¥d¥d¥d-¥d¥d¥-¥d¥d)"/' と同じことをawkでやろうとしているのですがわかりません。 awk -e '/href="(¥d¥d¥d¥d-¥d¥d¥-¥d¥d)"/ { print ??? }' グルーピングしたあとにそれを取り出す方法を探したのですが、わかりませんでした。 awkまたはsedでのやり方を教えて下さい。
>>855 シェルスクリプトってsetuid無視されるシステムの方が多いんじゃね?
環境変数PS1辺りを無視して、 実行される環境の方が多数派かと。
IFSと間違えたw
>>861 ラッパー作ってsystemで呼べばいい
>>865 とんだセキュリティホールになりそうだなw
>>865 system(3)のことなら、
system(3)は sh -c 'コマンド' の形で外部コマンドを呼び出すので、
shを通している時点で setuidビットはshによって無効化される。
だから、やるならexeclpあたりだな。戻る必要はないのでforkは不要。
どのシステムならそんな挙動するんだよ…余分なプロセス生成を減らすためにexec系を使うのは分かるが
>>868 /bin/sh -c を経由するのはどのOSでも同じだよ。
>>867 スクリプトの方じゃなくてラッパーの方を setuid するんだよ。
スクリプトを setuid すると、system(3) じゃなくてexec系の関数を使ったとしても
先頭に #! と書いてある時点で結局 setuid は効かない。
ラッパーの方を setuid しても効かない環境があるなら教えてほしい。
# cat id.sh
#!/bin/sh
/usr/bin/id -un
# cat hoge.c
#include <stdlib.h>
main(){
system("./id.sh");
}
# gcc hoge.c
# chown nobody a.out
# chmod u+s a.out
$ ./a.out
nobody
とはいえ、system() ではなく exec 系関数を使った方がいいというのはそのとおり。
system() は引数に含まれる sh の記号を解釈してしまうので、
`...` のような文字列が system() に渡ってしまうと
>>866 が言うように穴になる。
>>870 ラッパーの方を setuid するのはわかってるよw
そのラッパーから system()を呼ぶと、
system()ライブラリ内部で /bin/sh -c '....' が実行されるので、
この /bin/sh が setuid を無効にする。
よってラッパーは意図通りに動かない。(動作確認済み)
もし動くとしたらそれは setuid を無効にしないタイプの /bin/shなので、
それだったらそもそもラッパーを使わずにシェルスクリプト自体を setuidしても
動くはず。
いずれにしてもラッパーの意味がないことがわかったかな?w
>>870 をコピペして実行しても nobody にならなかったよ
FreeBSD と Debian で試したがちゃんと nobody になるぞ。 …とふと思いついて、ラッパーを system("/bin/bash ./id.sh"); に変えてみたら確かに nobody にならないな。 bash の勝手仕様か。
ash, dash, ksh93, pdksh, zsh いずれも nobody になる。 おかしいのは bash だけか。
ほらbashなんか使ってるからww
ごめん。補足したつもりがexeclpは使うなって書いてあったわ
UNIX使いの心得に excelは使うなって書いてあったよ
>>871 の勘違いをもうひとつ正しておく。
>もし動くとしたらそれは setuid を無効にしないタイプの /bin/shなので、
>それだったらそもそもラッパーを使わずにシェルスクリプト自体を setuidしても
>動くはず。
動かない。
setuid スクリプトの実行を禁止しているのは sh ではなくカーネル。
なので、sh だけでなく、perl やら ruby やらその他もろもろのスクリプト言語全般で
setuid されたものは動作せず、どうしてもやりたいならラッパーを書く必要がある。
# perl はビルドのときのオプションで suidperl という専用ラッパーも
# いっしょにコンパイルできる。
珍しくないようがあるようだ
bash使いはバカといういつもの結論のどこに内容があるのだ?
内容が
shに拘ってるのはこの板だけだよ
それでいいじゃない
sh (BusyBox, ash) dash (Debian, ash) sh (FreeBSD, ash) どれが一番素のshに近いの?
>>886 個人的な感覚的に、一番近いのはFreeBSDのsh
だがそれでも、shから拡張されてる
xmkmf厨目指してるんでもないかぎり、shとの互換性は、もういいんじゃね?
俺はもう、#! /bin/kshばっかだわ
普段使いの環境で動いて、互換性そこそこいけるのを選べばいいと思う FreeBSDなら最初からあるashだろし Busybox使われてるならそれのashだろうし Debian系Linuxにらdashかと それ以外の環境ならdashが比較的導入しやすいか? OSXとかでも動くし、互換性のためにBusybox…てのは違和感がw
>>886 >>1 にある通り、OpenSolarisのheirloom shが一番v7 shに近い。
ash系はどれも大差ない。
890 :
sage :2011/12/01(木) 16:59:14.89
質問があるんですが現在あるシェルスクリプトをprocmailから動かそうと思っています。 シェルスクリプトはすでにできあがっていてターミナルに直接sh test.shと打ち込むとちゃんと 動作するのですがprocmailから動かそうとするとうまく動作しません。 どんな原因が考えられるでしょうか?
891 :
sage :2011/12/01(木) 17:00:35.73
質問があるんですが現在あるシェルスクリプトをprocmailから動かそうと思っています。 シェルスクリプトはすでにできあがっていてターミナルに直接sh test.shと打ち込むとちゃんと 動作するのですがprocmailから動かそうとするとうまく動作しません。 どんな原因が考えられるでしょうか?
893 :
sage :2011/12/01(木) 17:18:44.60
>>892 ありがとうございます。
そっちで聞いてみます。
エスパーがいればいいな
PATHが違う
わざわざ追っかけて行って答える気などない。
ならここでも答えなくていいよ。
質問させてください。 先日からシェルスクリプトの勉強を始めたのですが、 取得した引数をもとにif文のORで条件分岐を行おうとした際、うまくいきません。 以下がソースコードになりますが、どのようなコーディングを行えばよいか教えてください;; #!/bin/sh if test ${1} ; then #第1引数が"str1"または"str2"以外の時はメッセージ("hoge")を表示する if test [ "${1}" != "str1" -o "${1}" != "str2" ] ; then echo "hoge" fi else #第1引数がnullの時はメッセージ("foo")を表示する echo "foo" fi
>>899 机上ですまが、まずは、4行目のtestを取ったらうまくいくかね
で、同じくそこのOR条件なんだが、str1だろうがstr2だろうが何だろうが何か設定されてりゃ
常に真になっちまいそうだな
#!/bin/sh if test -n "${1}" ; then #第1引数が"str1"または"str2"以外の時はメッセージ("hoge")を表示する if [ "${1}" != "str1" -a "${1}" != "str2" ] ; then echo "hoge" fi else #第1引数がnullの時はメッセージ("foo")を表示する echo "foo" fi
case使っちゃダメなの?
勉強だからどっちも勉強すればいいんじゃないの?
ド・モルガンの法則って高校の時にやんなかったけ?
日本語だと「または」と「以外」は「または」のほうが結合が強い、でいいよね。
同級生が高校生だった頃、俺は建築現場で働いて夜はスナックで飲んでた。
>>906 の言うとおり、ゆとり高校ではド・モルガンは教えない。
大学でデジタル回路でブール代数やる時に、ド・モルガンから教えなければ
ならないらしい。
>>888 HP-UX、AIXは、POSIXシェル(実体はほとんどksh)
>>907 わっかるかなー、わっかんねぇーだろなー♪
フォルダ毎にzip圧縮してzipにフォルダの名前をつけるにはどうすりゃいい?
フォルダ毎にzip圧縮してzipにフォルダの名前をつけるようなスクリプトでも組め
>>912 なるほどー、そんな方法があったんですね。目から鱗です。ありがとうございました!!
for d in .[^.]* ..?* *; do test -d "$d" && zip -r "$d.zip" "$d"; done
>>914 ありがと。
すごい馬鹿なことを聞くけど
.[^.]* ..?* *
の意味がわからない。
パス名に見えるけど"/"がない。
OSによる差?
ちなみにUbuntu9.04です。
globって言った方が伝わり易いんじゃね
man 7 glob かな?
920 :
915 :2011/12/04(日) 18:17:19.52
いろいろありがとう。 globについてはよくわからないけど、 やろうと思っていたことはできそうだ。 ちなみに、シェルスクリプトに書かなくても ターミナルの上で実行できるのは少々驚いた。
ちょっと不安に思ったら端末でユニットテストですよ。
質問です。 あるプログラムファイルのある関数だけ、sedで変数の置き換えをしたいのですが、 そのような場合、どうすればいいのでしょうか? 言語はphpです。プログラムファイルはたとえば以下のようなかんじです。 ----------------------- function aaa() { } function bbb() { $hoge = ""; $foo = $hoge; $bar = $hoge; } function ccc() { } --------------------- この中でbbb関数のhoge、foo、barという変数をぞれぞれ、$_hoge、$_foo、$_barという名前に置き換えたいです。 よろしくご教示お願いします。
sed '/^function bbb() {$/,/^}$/s/$\([a-z]\+\)/$_\1/g'
>>899 です。
レスが遅くなって申し訳ありません。
>>900-905 さん有難うございます!
おかげで解決出来ました。
こんな質問してしまい、お恥ずかしい限りです・・・。
シェル始めたばかりなので、いろいろ試しながら勉強していきたいと思います。
有難うございました。
execについて質問させてください。 次のようなスクリプトbazを書きました。 #!/bin/sh switch=yes if [ "$switch" = "yes" ]; then exec tac "$@" | cat -n | tac fi exec cat -n "$@" このスクリプトを cat file | baz のように適当なファイルを対象にパイプで実行した場合は最初のexecしか実行されないのに、 ファイルを直接引数にして baz file のように実行すると、最初と次のexecが両方実行されてしまいます。 これはどうしてなんでしょう?
>>925 結論からいうと、どちらの場合でも最初と次のexecが両方実行されている。
execの後をパイプでつなぐと、パイプ全体がサブシェルになるため、
execは意味をなさず、execなしで普通に実行したのと同じになる。
そのため、if文の次のexecのコマンドのところまで実行されてしまう。
cat file | baz の場合、標準入力がパイプのため、
1回目の execのところで標準入力がEOFになり、
2回目の execのところではコマンドは起動されるけど
EOFなのでそのまま何模せずに終了して、
1回目しか実行されていないように見えるだけ。
928 :
名無しさん@お腹いっぱい。 :2011/12/07(水) 00:37:24.68
grepのwオプションや、egrepの\bみたいな単語を指定する方法は、sedにはないですか?
どのsed?
930 :
925 :2011/12/07(水) 11:44:41.50
>>926 パイプでつないだコマンドをexecしても意味ないのかなくらいまでは思ったのですが、
なるほど、とてもよくわかりました。すごく勉強になります。ありがとうございました!
>>929 freebsdのsedです。
manのhistoryでは以下のようにかいてました
A sed command, written by L. E. McMahon, appeared in Version 7 AT&T UNIX.
-Eつけたら使えるんじゃない?多分
[[:<:]]と[[:>:]]ではさむ。 man re_format
934 :
名無しさん@お腹いっぱい。 :2011/12/08(木) 21:24:33.01
ヒヤドキュメントをワンタイマーで書けないんでしょうか? 初心者シェラーですいません
ワンタイマーってなんだよ。
シェラーもな
つっこんだら負け。
>>936 教えてあげるざます
熱狂的なミーのファンざます!シェー!
シェリストじゃないの?
チャロに出てたハーフの娘? 最近よくバラエティに出てるよね
ワンタイマーはシェラーの基本だと聞いたのですが、 冷やドキュメントには対応していないんでしょうか?
シェルラーじゃね?
シェルスクリプター
シェルスクリプティストだろ
シェルスクリプタリストが シュラシュシュシュー
こんなスクリプトあったら、どうやって書き直しますか・・・ #!/bin/sh # params CSV="no" EXEC_OPTS="-f1" TARGET=${TARGET:-"/var/tmp/test"} # functions process_args () { if [ "${1}" = "yes" ]; then CSV="yes" fi } exec_cut () { if [ "${CSV}" = yes ]; then EXEC_OPTS="-d, ${EXEC_OPTS}" fi cut ${EXEC_OPTS} ${TARGET} } # main process_args exec_cut
俺ならvimを使って書き直すな。
>>946 わざわざ関数にしてるってことは、書いてるモノのほかに hogehoge する部分があるんだろうけど…
#!/bin/sh
EXEC_OPTS=""
TARGET=${TARGET:-"/var/tmp/test"}
[ "${1}" = "yes" ] && EXEC_OPTS="-d, "
cut ${EXEC_OPTS} -f1 ${TARGET}
本気でそれだけだったらこう書き直すかも。
僕のアタマだと TARGET に入れてる内容も理解しきれない。
CSV に no を入れる理由がよくわかってないし( no であることを case とかでチェックしないなら何でもいいじゃん)、
関数で全部済ます理由もわかんない。
>>947 間違いない。
こんな不自然なスクリプト見ると、例によって学校の課題で出された問題だと邪推してしまうな。
例えば
「
>>946 に機能を追加して ./hoobar.sh 6
とか引数を追加することによってCSVの6番目の要素を列挙できるようにせよ」
とかな。
冷やしドキュメントをラーメンタイマーで書けないんでしょうか? 初心者シェラー始めました♪ by Amemiya
csvは扱いが面倒だよね。 "1,000","2,000",,, なんてのがあるからね。
gawkのexampleにあったな。gawk限定だが というかちょっとしたデータベースもどきにCSVは使うけど やっぱりシェルスクリプトでもSQL使った方がいいのか? 別にSQLでなくてもいいけど、SQLiteくらいしか思いつかない
>>952 シェルスクリプトで、ってんなら
cutやawkで使える形式がいいなー
何にしろcsvよりは空白区切りでやると思う
csvならexcelに食わせろよ。色々と捗るぞ。
中級者シェラーによくある無駄 (1)空文字列の代入に無駄なクォート HOGE="" → HOGE= だけで桶 (2)変数展開等がないのにダブルクォート HOGE="hage boke" → HOGE='hage boke' シングルクォートで桶 (3)変数の条件展開等がないのにブレース hoge "${var}" → hoge "$var" で桶
シエラって何かあったよな? なんだっけ、ブラウザだったかな……。
>>952 CSVなら他のスクリプト言語使う。
大抵読み込みライブラリあるから。
>>955 (3) は、もしかして
hoge "${var}boo"
と後で変更するかもと考えると悪くないと思う。
>>958 そう変更するなら
hoge "${var}"boo
とするべきで、だったら
hoge "$var"boo
とした方がいいので、やはり { } は無駄。
diff -q ${var}{_old,} || ... とかふつうに { } 使わない? で、こういうとこだけ { } 使ってるのやだから、全部 ${var} にしとこ、とか? まあ、元のスクリプトの使い方が単純なケースだから、{ } 不要じゃねと言われればそれまでだけど
無駄とかそういう理由で省略するもんじゃないから。
>>960 それは
diff -q "$var"{_old,} || ...
だな。${var}だと、varの中身にスペースがあった時に誤動作するから。
{}が要る場所とか要らない場所とか考えるの面倒だから俺は全部省略せずに${hoo} って書くことにしてる ${hoo}って変数名を${bar}に一括置換したくなった時にも便利だしね。
>>963 だったら全部 "$hoo" って書けば良い。タイプ数は同じ。
"$hoo" って変数名を "$bar" に一括置換するのも同じこと。
問題なのは、${hoo} って書いて、それがスペースを含んでいた場合に誤動作する
ということを知らないで書いている人。
{ } で囲んでもスペース問題は解決しない。
。囲む時はダブルクォートを徹底すること。
なんでそんなに${hoo}の表記法を憎むのか理解出来ない。 もしかしてソースに${hoo}って書いたせいで親が殺されたり恋人に振られたりした経験でもあるのか?
966 :
948 :2011/12/10(土) 16:28:58.88
>>955 中級者に格上げありがとう。
正直 EXEC_OPTS="" 自体も要らないんだけど、Excel マクロとかも使ってて
クセになってるんですよね。気をつけます。
TARGET の中身に入れてる内容がどういう意味なのか説明していただけると、
とてもうれしいです。初心者を自覚してたのでわかりません…
>>967 ありがとう。
TARGET=${TARGET:-"/var/tmp/test"}
TARGET の中で、未定義の $TARGET が展開されてる理由は
たぶんシェルスクリプト実行前に環境変数へ入れてるんだろうな〜
というのだけは分りました。
俺も${var}はできるだけ使わない派だけど、 {}使ってるスクリプト見ても無駄だから省略しろとは思わない。
>>968 TARGET=${TARGET:-"/var/tmp/test"}
よりも、
: ${TARGET:=/var/tmp/test}
の方がいい。
>>959 boo などが引用符に囲まれてないと、ちょっといやだ。
自分は * や ~ などパターンマッチをしたいときだけ引用符なし、
それ以外は基本引用符で囲むことにしてる。
シェルスクリプトのパイプの受け取り方わかんない(´・ω・`) Path通してコマンド化しようとしてる2つのシェルスクリプトA,B。 例だからNRで1行でできるとかは、なんせんすな A:Gen (file名).dat なんか適当な数字を発生させる B:Ave (file名).dat 平均を求める B: #Average of Time-series #Ave ***.dat line=`wc -l $1 | awk '{print $1}'` ←行数読む awk '{a+=$1/'$line'}END{print a}' $1 ←平均出す たとえばAで発生させた数字列をパイプで Gen (file名).dat | Ave で つないで平均もとめようとするとと空出力。Ave単体だとちゃんと動く。 大規模計算だからできればawk使いたい。おじさんたちたすけて。
何を聞きたいのか全然わからない。一見日本語のようだが日本語と異なる言語のようだ。
>>973 Aveがこの内容だとパイプ受け取れない(´・ω・`)
どうすればいいですか?
awkスレ以前だろ。引数でファイル渡すようにスクリプト書いてるのに それにパイプでデータを渡したいって話だろ?書き直せ
/dev/stdin w
スクリプトの中で標準入力の内容を何度も処理したい場合は、とりあえず cat > $tmpfile しておく。んでもって line=`wc -l < $tmpfile` awk ... $tmpfile とかかしらん。 ファイルも引数に取れるようにするには、最初の部分を cat "$@" > $tmpfile にしておけばいいし
ファイルに出力するのと標準出力に出力するのは別だってのを 理解していないように思えるが? #!/bin/sh # --- GEN.sh version 2.0 --- OF=$1 if [ "$OF" = "" ] ; then OF=rand.txt ; fi echo 10 > $OF echo 20 > $OF echo 30 > $OF echo 40 > $OF echo 100 echo 200 echo 600 exit 0
すまん、重複してしまった... 削除依頼出してきます。
>>979 if [ "$OF" = "" ] ; then OF=rand.txt ; fi
↑
無駄
: ${OF:=rand.txt}
独りよがりもいい加減にしとけ。な。
>>979 if [ "$OF" = "" ] は無駄だな。ifで書くとしても、
せめて if [ -z "$OF" ] だな。
しつこいねぇ。 $ fgrep -1 ' = ""' /usr/bin/xmkmf if [ "$topdir" = "" ]; then args="-DUseInstalled "$configdirspec $ head -n 7 /usr/bin/xmkmf #!/bin/sh # $XFree86: xc/config/util/xmkmf.cpp,v 1.3 2000/11/06 21:57:10 dawes Exp $ # # make a Makefile from an Imakefile from inside or outside the sources # # $Xorg: xmkmf.cpp,v 1.3 2000/08/17 19:41:53 cpqbld Exp $
>>985 Xの付属のシェルスクって無駄な書き方多いよ。
全然参考にならないし、その例挙げても反証にならない。
>>978 のやりかたでできた。
ありがとうございました。
-z って、どっちだっけってわからなくなるんだよね。 だから自分はいつも if [ "$args" = "" ]; then って書くよ。-n もあるしね(-zと-nはどっちがどっちだっけってなる)。
>>988 シェルによっては、
if [ "$arg" = "" ];
という書き方だと argが -f とかの特殊な値だと誤動作するんだよ。
だから、if [ X"$arg" = X ]; みたいなバッドノウハウもあった。
それを避ける意味でも if [ -z "$arg" ] の方が良い。
-z とか -n ってどういう意味なん 毎回覚えられなくて調べるんだけど
zeroとnonzero これが覚えられないなら頭を使う仕事はやめた方がいい。
ああ一番肝心なの調べてなかったのかthx 覚えられないのは普段使わないからだよ
こんな覚えやすいのに…
-s "$var" もあるから紛らわしいんだよね。 その場でちょこっとスクリプト書いてささっと作業済ませたいときにmanとかかったるい
>>993 頭は普段から使うようにした方がいいぞ。
ブロック壊したり、アイテム出したりするのにいつも頭を使っているから、凄く頭はいいと思うんだが なぜか毎回姫を攫われてしまう。何かいいアイデアはない?
>>992 大木金太郎やボボブラジルみたいな使い方もあるしー
君が勝てるかなあ?その頭で。
999 :
名無しさん@お腹いっぱい。 :2011/12/11(日) 16:27:00.77
bash で waf つくるよ
-z って変数が空か入ってるかぢゃ無いのかよ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。