|
はじめまして すいませんが質問です。 vi でヒアドキメントの使い方がわかりません linuxで試しているのですが ex/vi: Vi's standard input and output must be a terminal とエラーになってしまいます。 できないのでしょうか? |
|
>>1514 taka > vi でヒアドキメントの使い方がわかりません ex mode なら大丈夫なようです。ただし ex コマンド使わないと いけませんが。そのまま vi mode で使う方法は分かりません。 #!/bin/sh ( vi -e | sed -e 's/^#/foo: /' ) << 'END' a hoge hoge hoge hoge . 1,$s/^/#/ 1,$p q! END あとシングルクォートかエスケープ使った方が良いです。 最後の行の $ とシェル変数がバッティングしますから。 |
|
有難うございます 以下のシェルで更新できました。 #!/bin/sh vi -e data001 << 'END' i hoge hoge hoge hoge . wq! END ps レスのつけ方がわかりませんでしたすいません |
|
>>1510 E田 構造体の受け渡しに関しては、僕の出る幕はなさげですが、 一応まとめておきます。まず、E田さんはポインタの使い方を 学んで下さい。rosegarden さんのソースは tes_s.test1 = ((unsigned long *)ptr)[0]; tes_s.test2 = ((unsigned short *)ptr)[1]; となっていますが、rosegarden さん自身が説明されている通り これではまずいので tes_s.test1 = *(unsigned long *)(ptr); tes_s.test2 = *(unsigned short *)(ptr+4); の方がいいでしょう。わからなければ再度質問してください。 で、それを理解してからやっとバイトオーダの話になります。これは 今回の件では関係ないかもしれない (エンディアンによってたまたま 問題が顕在化していないかもしれない) ので、参考程度にどうぞ。 以下のソースでは配列 data から変数 test1/2/3 に値を代入しようと しています。 #include <stdio.h> #include <string.h> void my_memcpy(char *dst, char *src, size_t len){ src += len-1; while (len--) *dst++ = *src--; } main(){ unsigned long test1; unsigned short test2; unsigned short test3; char data[] = {0x12,0x34,0x56,0x78,0x0,0x1,0x0,0x2}; char *ptr = data; test1 = *(unsigned long *)(ptr); test2 = *(unsigned short *)(ptr+4); test3 = *(unsigned short *)(ptr+6); printf("普通に代入 0x%x 0x%x 0x%x\n", test1, test2, test3); memcpy(&test1, ptr+0, sizeof(test1)); memcpy(&test2, ptr+4, sizeof(test2)); memcpy(&test3, ptr+6, sizeof(test3)); printf("memcpy 0x%x 0x%x 0x%x\n", test1, test2, test3); test1 = htonl(*(unsigned long *)(ptr)); test2 = htons(*(unsigned short *)(ptr+4)); test3 = htons(*(unsigned short *)(ptr+6)); printf("hton して代入 0x%x 0x%x 0x%x\n", test1, test2, test3); my_memcpy(&test1, ptr+0, sizeof(test1)); my_memcpy(&test2, ptr+4, sizeof(test2)); my_memcpy(&test3, ptr+6, sizeof(test3)); printf("逆順にmemcpy 0x%x 0x%x 0x%x\n", test1, test2, test3); } このサンプルでは char data[] = {0x12,0x34,0x56,0x78,0x0,0x1,0x0,0x2}; となっていますが、これを適当に切り取って変数に代入すると 順序が狂ってしまいます。実行結果は以下の通り。 普通に代入 0x78563412 0x100 0x200 (間違い) memcpy 0x78563412 0x100 0x200 (間違い) hton して代入 0x12345678 0x1 0x2 (正しい) 逆順にmemcpy 0x12345678 0x1 0x2 (正しい) 前の2つは順序が逆になっています。これはリトルエンディアンマシン (x86 など) で発生します。ビッグエンディアン (68000, Sparc など) では起こりません。 後の2つは htons/htonl や自作の my_memcpy でバイト順を置換して 代入しています (もちろん hton を使う方がよい)。 これはソケット経由でデータを送ると、バイト順が狂うという 意味ではありません。エンディアンが異なるマシン間でも、 データは送った順序で届きます。ですから、同じエンディアン 同士でデータを送りあえば問題は顕在化しません。 ただし、 「異なるエンディアン間で変数の値を直接送信したとき」 は、 「一方の CPU 内部ではバイト順の交換が行われるのに、 他方では行われない」 ので、バイト順が狂ってしまいます。ですから、 「事前にネットワークバイトオーダに変換してから送信」 し、 「受信側はネットワークバイトオーダと認識して変数に代入する」 のが望ましいということです。 実際のソースで書くと、以下のような感じになります。 送受信側でバイトオーダが一致していれば OK。異なるなら NG。 (送信側) long send_num=0x12345678L; write(socket, &send_num, sizeof(send_num)); (受信側) long recv_num; read(socket, &recv_num, sizeof(recv_num)); バイト列をソケット経由で変数に代入する。受け手側が リトルエンディアンなら OK。そうでなければ NG。 (送信側) char buf[]={0x12,0x34,0x56,0x78}; /* 0x12345687 を送りたいとする */ write(socket, buf, sizeof(buf)); (受信側) long recv_num; read(socket, &recv_num, sizeof(recv_num)); ネットワークバイトオーダで送信。ネットワークバイトオーダを ホストバイトオーダにして代入。これが一番よい。 (送信側) long send_num = htonl(0x12345678L); write(socket, &send_num, sizeof(send_num)); (受信側) long recv_num; char buf[256]; read(socket, buf, sizeof(recv_num)); recv_num = ntohl(*(long *)(buf)); なお、ネットワークバイトオーダ=ビッグエンディアンのオーダです。 別に両者で合意が取れていればいいので、リトルエンディアンで 統一したければそれはそれで構いません。 ちなみに X プロトコルでは高速化のため、事前にクライアント・サーバ 間でバイトオーダが異なるかどうかチェックして、 - 同じバイトオーダならそのままデータを送る - 異なるバイトオーダならネットワークバイトオーダに変換してから送る となっているとか。 ところで my_memcpy(void *dst, void *src, size_t len){ とすると gcc に invalid use of void expression と怒られるんですが、 引数を void * で受けるのってできないんでしたっけ? >>1512 gixs > Linuxのselect(2)は、戻った時、第5引数の値が残り時間を示して戻ってくる > (タイムアウトしたら値はゼロになる) ので、waitvalの値の設定はwhile > ループ内でやる必要があります(manにも書いてあります)。 ご指摘どうもです。その通りですね。ちなみに FreeBSD では select(2) の BUGS の項で、本来上記のような動作をするべきだが、 現状ではそうなっていない (waitval の値は書き換えられない) と あります。 >>1513 CoreFighter > NICにはMACアドレスってのがありますよね。 > モデムやTAにもMACアドレスってあるのでしょうか? ないです。なぜかっちゅうと NIC は Ethernet の端点だからです。 # なぜ Ethernet だと MAC アドレスが必要で、モデム/TA に # MAC アドレスが必要ないか…は、うまく説明できないなぁ。 # 誰か教えて下さい。 |
|
すいませんがまた質問です。 今度はftp でヒアドキメントの使い方がわかりません ftp ftp.xxx.xxx.ne.jp << EOF userid password by EOF これで実行すると Password:Name(ftp.xxx.xxx.ne.jp:root): と聞かれてしまいます。 シェルだけで実行する方法はありませんか? |
|
>>1518 taka > 今度はftp でヒアドキメントの使い方がわかりません http://X68000.startshop.co.jp/~68user/unix/pickup?ftp の -n オプションの説明を見て下さい (Linux で使えるかどうかは わかりませんが)。 |
|
>>1487 68user 先日の FreeBSD の crypt(3) のデフォルトについてですが、 暮れから新年にかけてライブラリ関数のレベルで切り替えの メカニズムが commit されたようです。いまとのところ 5-current でしか使えず、管理権限がないと切り替えられないのですが。 /etc/auth.conf に crypt_default=md5 という設定を入れると perl の crypt もデフォルトが md5 になるようです。 # 今日 CVSup でソースとって来た人は 20 時以降のソースとって来た方が # いいです。昼のソースだと pccard 周りのコンパイルが出来ません。 # 今はなおっていますが。 |
|
せっかくなので、 >>1509 68user のソースを書き直して 「C 言語で echo サーバを作ってみよう (2)」 http://X68000.startshop.co.jp/~68user/net/c-echo-2.html を作ってみました。C言語+select によるタイムアウト機能付き echo サーバです。 # 一応バグは潰したつもり。 あと、これまでご指摘を頂いた >>1389 Yuuki の accept のバグ、 >>1215 UNIX見習い >>1216 68user の LocalAddr のバグを修正しました。お二人に感謝。 |
|
>>1520 rosegarden おろ、/etc/login.conf には passwd_format=md5 で、/etc/auth.conf には crypt_default = md5 des で、libutil で、libcrypt ですか。全然なにが なんだかわかってませんが、手元にソースがないので調べにくい。MFC を待つか…。 # 軟弱なので、うちは今朝の 4-STABLE です。 |
|
>>1522 68user 言葉が足りないようですみません。 4-stable では /etc/login.conf に passwd_format=md5 と明示的に 指定することによって passwd コマンドなどで 使用するハッシュ関数は変更できますが、perl などで使用している crypt(3) などのハッシュ関数はそのまま des だったりします。 解禁以降、大抵の人はそのまま des 入れているでしょうから。 一方、5-current だと /etc/login.conf でのハッシュ関数の 指定は passwd コマンドでは有効になりますが、それとは別に crypt(3) のハッシュ関数を /etc/auth.conf で指定できます。 これはさっき CVSup して確かめましたが、4-stable には反映されていません。 http://www.jp.FreeBSD.org/cgi/cvsweb.cgi/src/lib/libcrypt/crypt.c ソースはここで確かめられます。 CGI で差分も見れます。 > # 軟弱なので、うちは今朝の 4-STABLE です。 いや、あまり関係ないかと思います。去年の暮れに 4-stable が page fault 頻発して 放棄せざるを得ない状態まで追い込まれたことあります。結局 kernel panic 起こしながら、数個ずつ kernel のファイルをコンパイルして、 安定した kernel をインストールし、それで回復させましたが。 同じ時期の 5-current はすごく安定していました。 ハード構成いかんではそういうことも起こり得ます。 |
|
初めまして。 FreeBSD 3.5.1と、それに付属のperlを使っています。 そこでソケットに関するプログラムを組みましたが、ちょっと問題が出てきました。 下記のソースを見てください。 HTTPサーバに接続して、メッセージを受け取り、一定時間何も受信できないと プログラムを終了しようとしています。 (本当は、相手のサーバからコネクションを切られたら終了するようにしたいんです。) サーバと接続されいる状態では、selectは期待した値を戻してくれるのですが、 接続が切断されたあとも、selectの戻り値が 0以外で、いつまでたっても、 ループから抜けられません。 なにか解決方法はないでしょうか? (大抵のサンプルはwhile (<SOCK>) って感じでやってるみたいですが、 バイナリファイルが対象でもうまくいくのでしょうか?) ## ソケットを開いて、ポート80)に繋ぐ。 ## send(SOCK,"GET /index.html HTTP1.0\r\n",0); $rin=''; vec($rin,fileno(SOCK),1)=1; while (1) { $ret = select($rout=$rin,undef,undef,1); if ($ret == 0 ) { last; } #タイムアウト recv(SOCK,$x,1,0); print $x; } |
|
>>1524 みかん ちろっと見た感じでは 1. \r\n が一個足りません。 2. 相手側がコネクションを切断したときも select は 1 を返します。 その際、recv すると1バイトも読めず、0を返しているはずなのに 無視しているので永遠に終わらないのです。 # http://X68000.startshop.co.jp/~68user/net/echo-4.html |
|
>>1523 rosegarden > 言葉が足りないようですみません。 いや、解説を催促するつもりはなかったのですが、恐縮です。 login.conf ということはユーザごとに DES か MD5 を定義 できて、しかも各ユーザは ~/.login_conf で上書き自由、 ということだと思うんですが、それが出来て何がうれしい んだろう…ってのが疑問なんです。 # NIS 使用時に幸せ? > 去年の暮れに 4-stable が page fault 頻発して > 放棄せざるを得ない状態まで追い込まれたことあります。 恐いですねぇ。僕は FreeBSD-stable も流し読みだし、make world で こけたとき直すスキルもないので、ビクビクしながらやってます。 4-STABLE じゃなくて 4.2-RELEASE にしとけばよかったな。 >>1524 みかん > 大抵のサンプルはwhile (<SOCK>) って感じでやってるみたいですが、 > バイナリファイルが対象でもうまくいくのでしょうか? <> は C でいうところの fgets 相当 (+バッファサイズが無限長) なので うまくいきます。 うまくいきますが、改行コードが1つもないデータを読もうとすると 一度に多くのバッファ (=メモリ) を消費するので、 sysread(SOCK, $buf, 8192); read(SOCK, $buf, 8192); while ( read(SOCK, $buf, 8192) ){ print $buf } などの方がよいです。 ついでに言っておくと、状況にもよりますが、select に <> や read を使うのは不適切です。select で読み込み 可能だからといって、「改行コードを含むデータ」や 「指定したサイズのデータ」が読み込めるとは限らない ので (データの前半部分だけが先に到着しているかも しれない) からです。せっかく select でブロッキングを 回避しているのに、<> や read の部分でブロッキング してしまうかもしれない。 # ここでいう read は read(2) でなく perl の read (fread(3)) です。 |
|
>>1517 68user > ところで > my_memcpy(void *dst, void *src, size_t len){ > とすると gcc に invalid use of void expression と怒られるんですが、 > 引数を void * で受けるのってできないんでしたっけ? おや? 68userさんにしては珍しい。 # まあ、プログラミング言語って(自然言語も同じようなものですが)、 # ちょっと離れるだけで勘がにぶって、ポカをやらかしてしまいますが。 そのエラーは、引数で受けた部分ではなく、 dst++などの演算のところのエラーですね。 逆に、char*で受けた場合、gcc -Wallのwarningを黙らすために、 (char*)&test1のようなキャストが必要です。 # gccはいつも-Wall。これでポカミスを結構見付けられます。 |
|
>>1526 68user > それが出来て何がうれしい うーん、それはそうですね。ただ、人によってこだわりは あるでしょうから。本当の理由は私も良く分かりませんが、 des インストールしても md5 で crypt できるのはやはり 嬉しいです。 |
|
>>1527 gixs > そのエラーは、引数で受けた部分ではなく、 > dst++などの演算のところのエラーですね なるほどなるほど。 void my_memcpy(void *dst, char *src, size_t len){ (char *)src += len-1; while (len--){ *((char *)dst)++ = *((char *)src)--; } } てな感じでしょうか。 > おや? 68userさんにしては珍しい。 僕は元々ヘボです。-Wall は付けてますが、いつも warning が出る ものの、キャストの仕方がわからず、大抵「まぁ動いているからいいや」で 済ましてしまうレベル (^^; >>1528 rosegarden > des インストールしても md5 で crypt できるのはやはり > 嬉しいです。 ちと考えてみましたが、例えば apache+suExec で CGI を動かす とき、「俺は前の環境で作成したパスワードがあるので DES」 とか「私はセキュリティ重視で MD5」などと、ユーザごとに DES/MD5 を選べたりする、ってな場合があるかもしれませんね。 全然関係ありませんが、掲示板の使い方 http://X68000.startshop.co.jp/~68user/cgi-bin/wwwboard.cgi?howtouse を作りました。上の [使い方] から飛べます。 |
|
こんにちは、UNIX1年生のみかんと申します。 文字列置換のsedコマンドを使って変数の中の文字列を置換して 別の変数に入れたいと考えております。このようなことは可能でしょうか? sed -e "s/aaa/bbb/g" ${ABC} ここで変数${ABC} の中に入っている値(例えばaaa)を置換して 変数${CBA}に挿入したいと考えております。 大変に恐縮ですが、ご存知の方がいらっしゃいましたらご教授いただけませんでしょうか。よろしくお願いします。 |