シェルスクリプト総合 その3

このエントリーをはてなブックマークに追加
1前スレ著者様@お腹いっぱい。
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-5くらい)をご覧ください。


□お約束
・特記なき場合はbourne shがデフォルトです。
 bash/csh/tcsh/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashなので特に注意。
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
 manや参考リンクを見ましょう。
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
2名無しさん@お腹いっぱい。:2005/08/24(水) 22:21:19
□前スレや過去スレ:
シェルスクリプト総合 その2
http://pc8.2ch.net/test/read.cgi/unix/1113664637/
シェルスクリプト総合 その1
http://pc8.2ch.net/test/read.cgi/unix/1101820646/
☆シェルスクリプトを勉強するにあたって☆
http://pc8.2ch.net/test/read.cgi/unix/989659936/
便利なシェルスクリプト見せろ
http://pc8.2ch.net/test/read.cgi/unix/996949546/
【貝】第1回シェル講座【殻】
http://fun.kz/test/read.cgi/unix/1016372780/

□関連スレ:
sed
http://pc8.2ch.net/test/read.cgi/unix/1085730992/
正規表現
http://pc8.2ch.net/test/read.cgi/unix/1039165754/
おまえら! shell は何を使っているんですか?
http://pc8.2ch.net/test/read.cgi/unix/1012330865/
Eshell の使い方とか設定とか【Emacs Shell、Lisp】
http://pc8.2ch.net/test/read.cgi/unix/1102921590/

□他板の関連スレ:
Macでシェルスクリプト総合 Part 1
http://pc7.2ch.net/test/read.cgi/mac/1105074933/
【Shell】どのシェル使ってる?【Script】
http://pc8.2ch.net/test/read.cgi/linux/1067330754/
3名無しさん@お腹いっぱい。:2005/08/24(水) 22:21:58
□初心者向けリンク
「誰にでも」シリーズ
ttp://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications/dareUni/
/bin/shプログラミング入門
ttp://freebooks.info.nara-k.ac.jp/archive/ShellProgramming/
Bourne Shell 自習テキスト
ttp://www.tsden.org/takamiti/shText/shText.html
シェルを使おう - 導入からプログラミングまで -
ttp://www.netfort.gr.jp/~tomokuni/lms/shell/text/

□入門者向け書籍:
プロフェショナルシェルプログラミング
http://www.amazon.co.jp/exec/obidos/ASIN/4756116329/
入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
http://www.amazon.co.jp/exec/obidos/ASIN/4797321946/
UNIXシェルプログラミング徹底解説
http://www.amazon.co.jp/exec/obidos/ASIN/4822280489/
入門Kornシェル
http://www.amazon.co.jp/exec/obidos/ASIN/4873110149/
入門bash
http://www.amazon.co.jp/exec/obidos/ASIN/4900900788/
4名無しさん@お腹いっぱい。:2005/08/24(水) 22:22:47
□参考リンク:
UNIXの部屋 (沢山のコマンドの簡単な紹介など)
http://x68000.q-e-d.net/~68user/unix/
POSIX: Shell & Utilities (標準規格)
http://www.opengroup.org/onlinepubs/009695399/utilities/contents.html

□関連書籍と関連リンク:
FreeBSD Hypertext Man Pages
http://www.freebsd.org/cgi/man.cgi
Linux JF (Japanese FAQ) Project.
http://www.linux.or.jp/JF/
Unix Programming Frequently Asked Questions 日本語訳
http://www.adl.nii.ac.jp/~moro/unix-programmer/faq-j_toc.html
UNIXプログラミング環境
http://www.amazon.co.jp/exec/obidos/ASIN/4871483517/
5名無しさん@お腹いっぱい。:2005/08/24(水) 22:23:49
□シェルスクリプトでよく使うコマンド:
制御・条件判定系:
[,test,expr,true,false,yes,getopts

テキスト処理系:
cat,awk,sed,tr,sort,uniq,grep,wc,head,tail,cut,paste,comm,join

ファイル名・ディレクトリ系:
find,xargs,basename,dirname

出力系:
echo,printf

対話コマンド制御系:
expect

http/ftpの処理自動化:
wget,curl
6名無しさん@お腹いっぱい。:2005/08/24(水) 22:26:50
6!
7名無しさん@お腹いっぱい。:2005/08/24(水) 22:32:15
>>1
8名無しさん@お腹いっぱい。:2005/08/25(木) 00:15:21
htmlファイルから画像へのリンクだけを抜き出すスクリプトを教えてください
9名無しさん@お腹いっぱい。:2005/08/25(木) 00:23:36
>>8
シェルじゃなくて他の言語使った方が楽だと思うよ。
10名無しさん@お腹いっぱい。:2005/08/25(木) 00:32:06
>>8
画像をダウンロードしたいだけなら wget でごにょごにょすれば
リンクの抜き出しからダウンロードまで全部やってくれる。
11名無しさん@お腹いっぱい。:2005/08/25(木) 11:31:33
とりあえずシェルシェル略すなあ(>_<)
129:2005/08/25(木) 11:36:06
>>11
テンプレ以外で「シェル」という言葉を使ってるのは >>9 だけだが、
ここで「シェル」と言うのはおかしいかね。
13名無しさん@お腹いっぱい。:2005/08/25(木) 11:56:57
言語処理系としてのシェルだから別におかしくないと思うけど。

(そのスクリプトを書くには)
シェルじゃなくて他の言語使った方が楽だと思うよ。

ってことでしょ。

14名無しさん@お腹いっぱい。:2005/08/25(木) 14:58:18
※とにかく言い返さないと気が済まない
15名無しさん@お腹いっぱい。:2005/08/25(木) 18:10:51
はいはいシェルシェル
16名無しさん@お腹いっぱい。:2005/08/25(木) 19:08:49
バッチファイルだろ、要するに。
17名無しさん@お腹いっぱい。:2005/08/25(木) 20:46:09
どざ氏ね
18名無しさん@お腹いっぱい。:2005/08/25(木) 21:56:55
JCLだろ、要するに。
19名無しさん@お腹いっぱい。:2005/08/26(金) 03:18:40
おかま氏ね
20名無しさん@お腹いっぱい。:2005/08/26(金) 11:48:25
alias "cd.."="cd .."
dozaとしてはこれが必須のアイテム!
21名無しさん@お腹いっぱい。:2005/08/26(金) 12:40:36
なら
alias ..='cd ..'
でいいじゃん
22名無しさん@お腹いっぱい。:2005/08/26(金) 12:41:23
>>21
なら setopt autocd でいいじゃんプギャー
23名無しさん@お腹いっぱい。:2005/08/26(金) 15:08:12
(・∀・)カエレ!!
24名無しさん@お腹いっぱい。:2005/08/26(金) 15:56:17
(゜Д゜)ハァ?
25名無しさん@お腹いっぱい。:2005/08/26(金) 17:10:29
便所の落書が急速に減っている件について
26名無しさん@お腹いっぱい。:2005/08/26(金) 18:13:00
>>21
そういう統一性のない、どーでもいいようなaliasは書きたくないのだ。
cdを実行するという前提があって、なぜにスペースを空けねばならないか、
問題はそこなんだよ。
コマンドとパラメータの間ににどーしてもセパレータが必要だと言い張る
理由はないだろう。現に-Wall なんて記述もあるんだから。
しかもアルファベットを書くわけではなくてピリオド二つだ。./build.shのような
記述を許しておきながら、なぜcd.. は駄目なのか。
経験したほとんどのunix系OSは律儀にもすべて駄目だった。いいかげんなのが
売りのunixで。
27名無しさん@お腹いっぱい。:2005/08/26(金) 18:18:03
スクリプトスレで alias の話せんでもいいだろ。
28名無しさん@お腹いっぱい。:2005/08/26(金) 18:20:22
つーか、シェル「スクリプト」という時点で
aliasは使わないだろ。
aliasを使うのは「スクリプト」ではないコマンドライン上のみ。
alias定義しているようなシェルスクリプトは見たことないな。


>>26
「cd..」という名前の外部コマンドが存在するかも知れないから、
「cd..」をシェルが勝手に「cd ..」と解釈することはできないし、
やってはならない。なので、「cd..」という書き方を使いたいなら
aliasでも定義するしかないだろう。もちろん、推奨しないし、
俺は絶対やらないが。
29名無しさん@お腹いっぱい。:2005/08/26(金) 18:26:30
command.comって cd.. でも使えるのか、、
UNIXしか触ったことないから、逆に今まで知らなかった。
30名無しさん@お腹いっぱい。:2005/08/26(金) 18:27:41
特定の場合のみ空白を省略できるって方が統一性ないだろ。
31名無しさん@お腹いっぱい。:2005/08/26(金) 19:01:42
次スレのテンプレにはインタラクティブなシェルの使い方の話禁止を追加すべきだな
32名無しさん@お腹いっぱい。:2005/08/26(金) 19:05:01
あ、若干スレ違いスマソ

>>28
cd..というコマンドはまあ作らないだろうし、万一作ろうとするとコンフリクトしないかな
って思うのが普通の常識ジャマイカ

>>29
cd..\abc\defみたいなのは同じように使えるヨ。¥がちょとキモイかな。

>>30
え、いやあのDOSはできてうにはできない。
うにでもスペースなしで動くのもあるじゃん、って主旨なんだが。

まあ、レスありがと。みんなのうにびいきがひしひしと感じられるわ(^^;

33名無しさん@お腹いっぱい。:2005/08/26(金) 19:08:30
>>31
おまえほーけーで彼女いないだろ(藁
34名無しさん@お腹いっぱい。:2005/08/26(金) 19:10:19
捨てゼリフも聞けたところでスクリプトの話に戻ろうか。
35名無しさん@お腹いっぱい。:2005/08/26(金) 20:05:29
>>34
しきりうぜーよ。ネタだしてみろ。
36ニート@zsh user:2005/08/26(金) 21:56:24
zsh ユーザの俺は勝ち組

(info "(zsh)Description of Options")
AUTO_CD (-J)
If a command is issued that can't be executed as a normal command,
and the command is the name of a directory, perform the cd command
to that directory.
37名無しさん@お腹いっぱい。:2005/08/26(金) 22:37:23
彼の主張は
 「コマンドとパラメータの間に必ずセパレータ(空白文字)が必要なのは気に食わない。
  DOSではセパレータを省略できる場合があるのに。」
というところにあるわけだ。

DOSでもセパレータとしての空白文字を省略できるのは
ごく限られた場合だけなのだが、
それでもDOSの仕様のほうが優れていると。

結論としては
 「優れた仕様のほうへお帰りください。」
でFAだな。
38名無しさん@お腹いっぱい。:2005/08/26(金) 23:46:31
DOSで"ON"または"OFF"をechoさせたい場合はどうするの?
ってスレ違いも甚だしいか。
39名無しさん@お腹いっぱい。:2005/08/26(金) 23:48:55
板違い。
40名無しさん@お腹いっぱい。:2005/08/26(金) 23:50:38
echo \ON
41名無しさん@お腹いっぱい。:2005/08/26(金) 23:52:08
echo.ON
echo.OFF
42名無しさん@お腹いっぱい。:2005/08/27(土) 07:45:10
DOSは、各コマンドがセパレータを解釈する。
UNIXは、シェルがセパレータを解釈する。
43名無しさん@お腹いっぱい。:2005/08/27(土) 08:30:49
な、なんだってー
44名無しさん@お腹いっぱい。:2005/08/27(土) 12:15:58
マジレスすると、この場合cdとかechoが組み込みコマンドだから。
42自体はウソではないが。
45名無しさん@お腹いっぱい。:2005/08/27(土) 13:06:13
DOSだとワイルドカードの展開を各コマンド自身がバラバラにやるんだよな。
DIR *.TXT は使えるのに、TYPE *.TXT は使えないとか、
統一性が全然なくていやだな。
46名無しさん@お腹いっぱい。:2005/08/27(土) 13:38:23
>>45
copy *.txt con | more

ren(ame) a b vs. mv a b


47名無しさん@お腹いっぱい。:2005/08/27(土) 13:53:39
「-n」という文字列をechoするにはどうすればいいのでしょうか?
echo -e -n では何も表示されません。
echo -n -n でも何も表示されません。
echo -- -n では「-- -n」が表示されてしまいます。
48名無しさん@お腹いっぱい。:2005/08/27(土) 14:03:31
echo -- -n | sed 's/^-- //' とか...。スマン
49名無しさん@お腹いっぱい。:2005/08/27(土) 14:05:22
echo -e "\55n"
50名無しさん@お腹いっぱい。:2005/08/27(土) 14:07:36
printf "%s\n" -n
51名無しさん@お腹いっぱい。:2005/08/27(土) 14:11:03
echo - -n か?
52名無しさん@お腹いっぱい。:2005/08/27(土) 14:27:59
echo '-n'
53名無しさん@お腹いっぱい。:2005/08/27(土) 14:46:04
echo ./-n
54名無しさん@お腹いっぱい。:2005/08/27(土) 14:57:40
Solarisのechoは、出したくもないのに"echo -n"で"-n"が出力される…
しょうがないんで、代わりにprintf(1)を使うしかない。
55名無しさん@お腹いっぱい。:2005/08/27(土) 15:13:39
tcshのbuiltinだと

◯ 48,50
× 49,51,52,53

ですた。
56名無しさん@お腹いっぱい。:2005/08/27(土) 16:16:40
main()
{
printf("-n\n");
}
cc hoge.c -o "echo -n"
57名無しさん@お腹いっぱい。:2005/08/27(土) 16:27:09
echo -n - ; echo n
58名無しさん@お腹いっぱい。:2005/08/27(土) 16:28:45
苦しいな
59名無しさん@お腹いっぱい。:2005/08/27(土) 16:30:03
>>57
頭(・∀・)イイ!!
60名無しさん@お腹いっぱい。:2005/08/27(土) 16:53:09
>>57
すばらしい
61名無しさん@お腹いっぱい。:2005/08/27(土) 17:01:04
>>57
なるほど!
62名無しさん@お腹いっぱい。:2005/08/27(土) 17:05:48
>>57
おまえやるな
63名無しさん@お腹いっぱい。:2005/08/27(土) 17:05:48
$message の中に -n かも知れない任意の文字列が入っています。
これを、echo "$message" するにはどうすればいいでしょうか?

printf '%s\n' "$message"
はナシの方向でお願いします。
64名無しさん@お腹いっぱい。:2005/08/27(土) 17:08:13
echo x$message | sed 's/^x//'
65名無しさん@お腹いっぱい。:2005/08/27(土) 17:16:31
printf '%s\n' "$message"
66名無しさん@お腹いっぱい。:2005/08/27(土) 17:18:22
echo "$message" するには echo "$message" するしかないと思います。
67名無しさん@お腹いっぱい。:2005/08/27(土) 17:19:23
echo -n $me; echo
68名無しさん@お腹いっぱい。:2005/08/27(土) 17:32:05
echo ーn
69名無しさん@お腹いっぱい。:2005/08/27(土) 17:41:17
>>67
それだと駄目でした。

>>65
ナシの方向と書いたんですが・・
70名無しさん@お腹いっぱい。:2005/08/27(土) 17:47:55
printf '%s\n' "$message"
71名無しさん@お腹いっぱい。:2005/08/27(土) 17:55:42
>>70
梨の奉公!!
72名無しさん@お腹いっぱい。:2005/08/27(土) 17:57:28
printf '%s\n' "$message"
73名無しさん@お腹いっぱい。:2005/08/27(土) 18:21:23
zsh 4.2.5に組み込みのechoだと>>57が使えない。
% echo -n - | wc
      0       0       0
74名無しさん@お腹いっぱい。:2005/08/27(土) 18:47:06
echo -e \\055n
75名無しさん@お腹いっぱい。:2005/08/27(土) 20:30:14
env PS1="$message" sh -i < /dev/null; echo

これで逝けたと思ったが、bashだと余分なのが表示される… orz
76名無しさん@お腹いっぱい。:2005/08/27(土) 20:41:27
これでbashでもOK!
echo 'exec 2> /dev/null' | env PS1="$message" sh -i < /dev/null; echo
77名無しさん@お腹いっぱい。:2005/08/27(土) 20:46:16
VIPから来てあげたわよ

いまVIPが、世界が認めてない東海って名前を、
日本海に直してもらう作戦を行ってるのは、当然知ってるわよね?

VIPPERの力で、Googleが東海の単独表記を取り下げたのは有名ね。

でも、いまVIPは大きな問題を抱えてる。
ITスキル、特に鯖関係のものが、圧倒的に足りないのよ。

それでなんだけど・・・んちょっと、、、VIPに協力してほしいのよね。
べ、べつにあんただったから頼みに来たわけじゃないわよ!勘違いしないでよね!

でも、あなたの力があれば、日本海を取り戻すのが近くなるのは・・・確かだわ。
もし・・・協力してくれるんなら、このスレに書き込んでほしい。
http://ex11.2ch.net/test/read.cgi/news4vip/1125074145/

・・・・やっぱり、あなたに協力して・・・ほしいから・・ね・・
78名無しさん@お腹いっぱい。:2005/08/27(土) 21:20:50
zsh なら
print -- $message
79名無しさん@お腹いっぱい。:2005/08/27(土) 21:24:43
>>54
PATH=/usr/ucb echo
80名無しさん@お腹いっぱい。:2005/08/27(土) 23:40:08
>>79
それするくらいなら
echo 'hoge\c'
でしょ。
81名無しさん@お腹いっぱい。:2005/08/27(土) 23:40:53
>>54
echo "message\c" って話ではなくて?
(\cだっけ?...)
82名無しさん@お腹いっぱい。:2005/08/28(日) 00:01:30
Solaris以外のシステムでも動作するスクリプトを作る時とか、
他のシステムから持って来るときはちょっと手間が… orz

他の人が書いたのはprintf(1)使って機械的に置換、
自分で作るときはechon() { printf '%s' "$@" }でごまかしてます。
83名無しさん@お腹いっぱい。:2005/08/28(日) 00:12:11
Solarisだと printf は外部コマンドだから嫌だなぁ。
84名無しさん@お腹いっぱい。:2005/08/28(日) 00:15:08
SunOS 4.x にはそもそも存在しませんが。
85名無しさん@お腹いっぱい。:2005/08/28(日) 00:27:31
SunOS 4.xってまだ生きてんのか。Y2Kを契機に絶滅したかと思ってたのに。
86not 84:2005/08/28(日) 11:16:25
Y2Kの時は、通常は保守契約者以外非公開の patch もすべて公開され、
Y2K自体はとくに問題なく乗り切れた。
が、2002年の夏頃、SunOS 4.xの patch供給が終了したので、
その時点で事実上の消滅と思う。
まあ、ルーターより内側のLAN環境限定では趣味的に SunOS 4.xを
使っている者も残ってるかも知れんが。

で、話を戻して、シェルスクリプト書く時、
SunOS 4.x互換を考えなくてももういいよね?
87名無しさん@お腹いっぱい。:2005/08/28(日) 11:54:12
>>86
シェルスクリプトにポータビリティが必要かどうかなんて
こんなところで聞いて結論が出るわけはない。
88名無しさん@お腹いっぱい。:2005/08/28(日) 12:02:18
とりあえず1行目に
#!/bin/sh
と書いてあるのに、bashの独自拡張構文を使っている奴は論外。
89名無しさん@お腹いっぱい。:2005/08/28(日) 12:11:14
>>88
シェルスクリプトにポータビリティが必要かどうかなんて
こんなところで議論して結論が出るわけはない。
90名無しさん@お腹いっぱい。:2005/08/28(日) 12:33:07
とりあえず #!/bin/zsh と書く
91名無しさん@お腹いっぱい。:2005/08/28(日) 13:32:49
氏ね。
92名無しさん@お腹いっぱい。:2005/08/28(日) 13:47:35
とりあえず#!/bin/ash
93名無しさん@お腹いっぱい。:2005/08/28(日) 14:44:30
catのような、「ファイル名が指定されていればそのファイルから、
指定がなければ標準入力から読み込む」という動作を
シェルスクリプトで実現するにはどう書けば良いのでしょうか?
94名無しさん@お腹いっぱい。:2005/08/28(日) 15:10:30
>>93
普通に、
hoge "$@"
でいいだろ。引数がなければ "$@" が消えてくれるので、
hogeコマンドは標準入力から読む。

ファイル名引数が一つの場合は、
hoge ${1+"$1"}
でもいい。$1がない場合はちゃんと消えてくれる。
95名無しさん@お腹いっぱい。:2005/08/28(日) 15:41:04
おお、目から鱗。getoptの後でもちゃんと動きますね。
ありがとうございました。
96名無しさん@お腹いっぱい。:2005/08/28(日) 17:07:30
>>86
/bin/sh on Solaris で動いて/bin/sh on SunOS 4.xで動かないような文法はとくに無かった希ガス。
(except echo 'hoge\c')

だからSolaris
互換を考えてれば自動的にSunOS 4.x互換かと。
97名無しさん@お腹いっぱい。:2005/08/28(日) 18:14:48
もともとは SunOS4.x に /bin/printf が無いって話だから
言葉足らずに前提から外れた議論していくと、収拾付かなくなると思われる
98名無しさん@お腹いっぱい。:2005/08/28(日) 21:04:20
特殊な例を除き、シェルスクリプトで printf なんぞ使わないのが前提。
99名無しさん@お腹いっぱい。:2005/08/28(日) 21:13:02
勝手に前提作るなよ
100名無しさん@お腹いっぱい。:2005/08/28(日) 21:24:43
>>98
シェルスクリプトにポータビリティが必要かどうかなんて
こんなところで議論して結論が出るわけはない。
101名無しさん@お腹いっぱい。:2005/08/28(日) 21:28:26
結論:シェルスクリプトにポータビリティは必要。
102名無しさん@お腹いっぱい。:2005/08/29(月) 00:46:54
そだなシェル自身に互換性もたせるのが先だな。
103名無しさん@お腹いっぱい。:2005/08/29(月) 00:49:00
bash使わなければいいよ。
104名無しさん@お腹いっぱい。:2005/08/29(月) 01:26:17
やっぱり zsh だな
105名無しさん@お腹いっぱい。:2005/08/29(月) 02:31:11
program="/hoge/a.out"
flags="-m example"
と変数をセットして
${program} ${flags}
としてプログラムに引き数を渡して実行するFreeBSDのrcのスクリプトのような
shスクリプトを作ったのですが、
-m "This is message."
のようにスペースを含む引き数を送るために
flags="-m \"This is message\""
と変数をセットすると
/hoge/a.out -m \"This is message\"
を実行したように、'-m' '"This' 'is' 'message'の引き数が渡されたように
なってしまいます。
これをshスクリプトの改変だけで解決するにはどうしたらいいでしょうか?
106105:2005/08/29(月) 02:32:36
下から3行目の'message'は'message"'の間違いです。
107ヽ(´ー`)ノ ◆.ogCuANUcE :2005/08/29(月) 02:58:10
>>105
eval でどうよ。

#!/bin/sh

program="/home/a.out"
flags="-m \"This is a message\""

eval $program $flags
108ヽ(´ー`)ノ:2005/08/29(月) 08:37:02
>>107
だれだよ。おまえ。
109名無しさん@お腹いっぱい。:2005/08/29(月) 09:47:53
FreeBSDを語ろう
110105:2005/08/29(月) 09:59:05
>>107
どうもありがとうございます。
単体でものすごい高度な事ができるスクリプト言語のevalはとても
危なっかしかったので、すっかりevalの存在を忘れてました。
こういうところで使えるんですね。
111名無しさん@お腹いっぱい。:2005/08/29(月) 10:31:27
>>105
${program} "${flags} "
でもできるかも
112名無しさん@お腹いっぱい。:2005/08/29(月) 11:00:43
>>111
不正解。
それだと、「-m "This is a message"」までがそのまま1個の引数として
つながって解釈されてしまう。
クォートをネスティングして evalで解釈させるのが正解。
113名無しさん@お腹いっぱい。:2005/08/29(月) 20:39:35
aaa
bbb
ccc
ddd

と縦に並んでいる文字列を

aaa,bbb,ccc,ddd って ,区切りで横並びにはどうしたらいいでしょう?
114名無しさん@お腹いっぱい。:2005/08/29(月) 20:45:29
awk 1 ORS=,
115名無しさん@お腹いっぱい。:2005/08/29(月) 22:00:54
>>113
awkじゃなく、シェルでやれるよ。
while read s; do echo -n "$s",; done


>>114
$ awk 1 ORS=,
awk: syntax error near line 1
awk: bailing out near line 1

(gawkなら通ったけど)
116名無しさん@お腹いっぱい。:2005/08/29(月) 22:26:03
>(gawkなら通ったけど)

awk の極めて基本的な仕様に沿ったワンライナーで、特に拡張機能は使ってないので
gawk に限らず動くのがふつう。むしろ動かん方がおかしいような???

とりあえず Solaris の /usr/bin/awk ならば

awk 1==1 ORS=,

としてやれば動くことは確認。
/usr/bin/nawk や /usr/xpg4/bin/awk はこんなことせんでも動く。
117名無しさん@お腹いっぱい。:2005/08/29(月) 22:35:28
いや、awk使うくらいなら、

tr '\012' ,
118名無しさん@お腹いっぱい。:2005/08/30(火) 01:12:33
awkでやったほうがポータビリティが高い
119名無しさん@お腹いっぱい。:2005/08/30(火) 08:31:44
>>118
ハァ? 少なくともこの件では tr または while readの方が
ポータビリティが高い。

awkは >>115-116 の通り、動かない例があるわけだし。
120名無しさん@お腹いっぱい。:2005/08/30(火) 08:42:41
ポータビリティが必要かどうかは
>>113 が判断することだろ。
121名無しさん@お腹いっぱい。:2005/08/30(火) 13:12:39
こうした場所に書き込む時点で
既にポータビリティは問題になっているわけだが。
122名無しさん@お腹いっぱい。:2005/08/30(火) 13:17:18
大量のファイルのあるディレクトリから、find | grep して htmlファイルだけをファイルに出力したのですが、このファイルを読み込んで、特定のディレクトリにコピーしようと思っております。

cp <hoge.txt directory ってしてみたんですが、だめなようです。

正しいやり方を教えてください
123名無しさん@お腹いっぱい。:2005/08/30(火) 13:29:56
>>121
なってないよ。
124名無しさん@お腹いっぱい。:2005/08/30(火) 13:57:47
>>122
ふつーに find の -exec ほげほげでいいんぢゃないの?
125名無しさん@お腹いっぱい。:2005/08/30(火) 13:59:39
find ひとつで済ます方法じゃ駄目なの?
find . -name "*html" -exec cp {} hoge
126名無しさん@お腹いっぱい。:2005/08/30(火) 14:05:39
122じゃないけど
もしこれでコピーもとの相対ディレクトリの構造そのままコピーするんだったら
rsyncでも使うしか無い?
127122:2005/08/30(火) 14:24:39
122です。
>>125をやってみたら
find: -exec: no terminating ";"
ってでてしまいました。

引き続きアドバイスをお願いいたします。

128名無しさん@お腹いっぱい。:2005/08/30(火) 14:32:44
>>126
そういうのは find にパスごと出力させて
find |cpio -o|(cd hoge;cpio -im)
とか。

>>127
-exec の最後には ; をつけるんだよ。>>125 は書き忘れてる。
実際はシェルに解釈されないよう \; とする必要がある。
使い方調べないでむやみにやるのはよくないな。
129名無しさん@お腹いっぱい。:2005/08/30(火) 14:33:26
>>127
man find
130名無しさん@お腹いっぱい。:2005/08/30(火) 14:40:54
>>122
すでに hoge.txt に全ファイルリストができてるなら、

cp `hoge.txt` directory
131名無しさん@お腹いっぱい。:2005/08/30(火) 14:46:24
>>130
`` の中は `cat hoge.txt` では?
132名無しさん@お腹いっぱい。:2005/08/30(火) 14:50:10
bashなら、

cp `< hoge.txt` directory

でも可能。
133名無しさん@お腹いっぱい。:2005/08/30(火) 14:53:39
echo foo foo foo
のように、同じ文字列を繰り返したい場合、どうすればいいですか?
うえだと foo を3回繰り返していますが、これを10回にしたい場合とか。
134名無しさん@お腹いっぱい。:2005/08/30(火) 15:06:31
csh -fc 'repeat 10 echo -n "foo "'t
135名無しさん@お腹いっぱい。:2005/08/30(火) 15:07:10
ケツに変な文字がついたが気にするな。
136名無しさん@お腹いっぱい。:2005/08/30(火) 15:08:20
>>127
へぇー
cpioって使ったことなかった
137名無しさん@お腹いっぱい。:2005/08/30(火) 15:09:36

>>128だった
138名無しさん@お腹いっぱい。:2005/08/30(火) 15:18:36
>>134

shift $#
while [ $# -lt 10 ]; do set "$@" foo; done
echo "$@"
139名無しさん@お腹いっぱい。:2005/08/30(火) 15:43:20
>>134, 138
どうもありがとうございます。
>>138 サンのものがこちらの要望に近かったので、活用させていただきました。
140138:2005/08/30(火) 15:56:02
>>139
だれも無断で使ってもいいなんて言ってないのだが。
141名無しさん@お腹いっぱい。:2005/08/30(火) 15:59:50
ちゃんと書きこむ時の規約読めよ
142名無しさん@お腹いっぱい。:2005/08/30(火) 16:01:14
aa=`printf "%010d\n"`; echo ${aa//0/foo};
143本当の138:2005/08/30(火) 16:03:40
>>140
お前誰だ、ニセモノよ。こんなスクリプト、中級者なら誰でも考えつくだろ。

>>134 はギャグのつもりで書き込んだんだろ?
csh何か使うなよ。
144名無しさん@お腹いっぱい。:2005/08/30(火) 16:09:10
>>142
bash依存。失格。

それにスペース無しでつながってしまう。
145名無しさん@お腹いっぱい。:2005/08/30(火) 16:18:43
>>144
ふん!
146名無しさん@お腹いっぱい。:2005/08/30(火) 17:07:30
>>126
pax
147名無しさん@お腹いっぱい。:2005/08/30(火) 17:45:14
>>143
>csh何か使うなよ。

スクリプト言語としての csh ではなく、
単に外部コマンドとして利用することも不可ですか。
sh スクリプトから perl のワンライナーを呼ぶのがアリならば
これだってアリだと思うけど。
148名無しさん@お腹いっぱい。:2005/08/30(火) 17:45:39
romana
149名無しさん@お腹いっぱい。:2005/08/30(火) 17:46:15
>>147
宗教の人はそっとしておいてあげなさい
150名無しさん@お腹いっぱい。:2005/08/30(火) 17:51:00
>>149
宗教と哲学は区別しましょう!
151名無しさん@お腹いっぱい。:2005/08/30(火) 17:51:57
>>147
宗教の人は区別してそっとしておいてあげなさい
152名無しさん@お腹いっぱい。:2005/08/30(火) 17:53:22
>>149
差別するニカ?謝罪と賠償をするニダ!
153名無しさん@お腹いっぱい。:2005/08/30(火) 18:30:20
>>147
最近は、cshが最初からアンインスコされているシステムも多い。
154名無しさん@お腹いっぱい。:2005/08/30(火) 18:33:55
>>153
たとえば?
155名無しさん@お腹いっぱい。:2005/08/30(火) 18:44:22
非対話なら、cshの勝っている部分なんて無いに等しいじゃん。
だから、shからawkやperlを呼び出すのとはわけが違う。
156名無しさん@お腹いっぱい。:2005/08/30(火) 18:46:41
>>155
勝っている部分 >>134
157名無しさん@お腹いっぱい。:2005/08/30(火) 18:52:02
(hoge>/dev/null)>error
csh、ダサ。
158名無しさん@お腹いっぱい。:2005/08/30(火) 18:53:41
>>157
?
159名無しさん@お腹いっぱい。:2005/08/30(火) 19:00:04
>>158
にやにや
160名無しさん@お腹いっぱい。:2005/08/30(火) 19:08:30
>>159
にやにや
161名無しさん@お腹いっぱい。:2005/08/30(火) 19:21:14
>>160
にやにや
162名無しさん@お腹いっぱい。:2005/08/30(火) 23:40:05
sqrt(8)=にやにや
163本当の138:2005/08/31(水) 01:19:22
>>153
嘘つくな。
164105:2005/08/31(水) 02:48:31
bashがshのふりをするあれよりはcshにハードリンクされたtcshの方がにやにや。
165名無しさん@お腹いっぱい。:2005/08/31(水) 18:05:15
遠隔にあるテープから、ssh経由でファイルを「こっちに書き戻す時」のコマンドラインはどう書けばよいのでしょう。

遠隔ホストに接続してあるテープに「書き込む時」は、
tar cf - . | ssh [email protected] dd of=/dev/sa0 obs=20b
でうまくいきます。
で、テープドライブをローカルに持っている場合の書き戻しは、普通に
tar xf /dev/sa0
です。
が、遠隔テープから読みだして、sshのパイプで持ってきてディスクに展開するコマンドラインが思いつきません。
どうかけばよいのでしょう。
166名無しさん@お腹いっぱい。:2005/08/31(水) 18:08:06
>>165
cat
167名無しさん@お腹いっぱい。:2005/08/31(水) 18:20:41
>>165
ssh -n [email protected] dd if=/dev/sa0 bs=20b | tar xf -

Ignore >>166 , he may be BAKA.
168名無しさん@お腹いっぱい。:2005/08/31(水) 18:33:25
>167
どうもです。
おお。できたー。

パイプがsshの引数ではなくて、
こっちに戻ってかかるってのがわからなかったです。
これからも精進します。
169名無しさん@お腹いっぱい。:2005/08/31(水) 18:58:29
ssh の 標準入力を抑止するオプション -nは、なくても動作するようです。

まだ慣れないで、
ssh [email protected] "dd if=/dev/sa0 bs=20b" | tar xf -
とsshに渡すコマンドをクオートして使いたいと思います。

ちなみに、
ssh [email protected] "dd if=/dev/sa0 bs=20b |" tar xf -
と間違えると、
ファイルは向うのサーバの~operater/に書き出されるのでけっこう危険でした。


170名無しさん@お腹いっぱい。:2005/08/31(水) 19:07:16
rshの場合はいる。
と、マニュアルには書いてある。
171名無しさん@お腹いっぱい。:2005/08/31(水) 20:37:00
-n を付けなかった場合に不具合が起きるのは、
tar で展開し終ったあとだ。(展開が始まっても即OKではない)
展開後、シェルの標準入力がおかしくなってなければOKだが。
172名無しさん@お腹いっぱい。:2005/09/01(木) 00:00:49
FreeBSDを使用しています。
シェルスクリプトでsuを実行しても、
うまくいきません。どうすればsuできるのでしょうか?
#!/bin/sh
su - xxx
xxxxxx
173名無しさん@お腹いっぱい。:2005/09/01(木) 00:11:13
expect とか
174名無しさん@お腹いっぱい。:2005/09/01(木) 00:29:24
>>173
そもそも君は wheel group に入っているのか?
175名無しさん@お腹いっぱい。:2005/09/01(木) 04:19:23
sudo使いなさい
176名無しさん@お腹いっぱい。:2005/09/01(木) 11:26:40
>>172
#/bin/sh
su - user
whoami

とか書いても、whoamiコマンドはsuの中では実行されないよ。
・・という質問だよね?

だったら、

su - user whoami

複数コマンドの場合は、
su - user 'com1; com2; com3'
みたいな感じ。
177名無しさん@お腹いっぱい。:2005/09/01(木) 11:30:06
>>176
su - -c 'com1; com2; com3'
かと。

いや、>>172 はsu自体のパスワードのこと聞いてるんじゃないか?
それだったらシェルスクリプトに生パス書くのは邪道。
sudoを使うべき。
178名無しさん@お腹いっぱい。:2005/09/02(金) 17:43:44
ipf.conf内にある

allow = {192.168.0.5} の行において、192.168.0.5を

allow.txt内の

192.168.1.5 に置き換えるにはどうしたらよいでしょうか?
179名無しさん@お腹いっぱい。:2005/09/02(金) 17:51:50
sed 's/192\.168\.0\.5/'`cat allow.txt`'/' ipf.conf
180名無しさん@お腹いっぱい。:2005/09/02(金) 18:08:12
>>178 宿題。

>>179をふまえて、DDNSを利用した動的IPアドレスにも対応するように拡張せよ、
尚、IPアドレス取得法は、各々に任せる。

#例
nslookup
dig

#条件1
DDNSアドレスからIPアドレス取得
#条件2
取得したIPアドレスをallowで指定しているIPアドレスと比較し、
同じであれば終了。異なっていたならば次の動作を。
#条件3
異なっていた場合、指定しているIPアドレスを取得したIPアドレスに置換し、
ipfを再起動
181名無しさん@お腹いっぱい。:2005/09/02(金) 18:09:40
先生!
DDNSって何ですか?
ipfって何ですか?
182名無しさん@お腹いっぱい。:2005/09/02(金) 18:18:44
ダイナミックド素人ネットワークスクリプト
183178:2005/09/02(金) 18:29:42
#!/bin/sh
nslookup hogehoge.dyndns.orz | sed -e 's/^.\{9\}//;' | head -6 | tail -1 > /etc/allow.log

if ホゲホゲ
then sed 's/192\.168\.0\.5/'`cat /etc/allow.log`'/' /etc/ipf.conf
else exit;
fi

ipfctl -p /etc/ipf.conf

done;

こんなかんじですか?
184名無しさん@お腹いっぱい。:2005/09/02(金) 18:46:59
あーもう、駄目駄目です。(byアズラエル
185名無しさん@お腹いっぱい。:2005/09/02(金) 20:01:04
ipf て、まだ使ってる香具師いたんかね
186名無しさん@お腹いっぱい。:2005/09/02(金) 20:12:55
あれ?Sol10でデフォルトになってなかったっけ?
187名無しさん@お腹いっぱい。:2005/09/02(金) 21:10:45
>>185
FreeBSDにも最初から入ってるぞ
188名無しさん@お腹いっぱい。:2005/09/02(金) 21:56:19
ふりーびーえすでー的にはpfがぶ−む?
どっちもあったきがするな
189名無しさん@お腹いっぱい。:2005/09/02(金) 23:02:55
ipfwもipfもpfも最初から入っている
190名無しさん@お腹いっぱい。:2005/09/03(土) 00:56:36
>>189
FreeBSD5ではGENERIC kernelでipfw/ip6fw使えないだろ。

6系では試してないけど。
191名無しさん@お腹いっぱい。:2005/09/03(土) 01:11:31
>>190
kldload ipfw
192名無しさん@お腹いっぱい。:2005/09/03(土) 12:45:58
UNIX初心者ですが、プログラムを実行したら時間が
かかりすぎて困ってます。

(要件)
aaa.txtファイルをbbb.txtに変換したい。

aaa.txtの中身は
222
4444
999
と、各行5文字前後の文字列です。
それを
222
4444
999
と、全部で32バイトになるように頭に空白を詰めたいのですが・・・
193名無しさん@お腹いっぱい。:2005/09/03(土) 12:51:39
意味不明。そして宿題は自分で。
194名無しさん@お腹いっぱい。:2005/09/03(土) 13:13:08
あ、半角スペースは潰れるんだった・・・

入力ファイル
222
4444
999

を、

出力ファイル
       222
      4444
       999
(各行32バイト)に
変換したいのです・・・

スクリプトは書けたのですが、
実行してみたら5時間もかかるので
使い物になりませんでした・・・
どなたかご教授いただけるとありがたいです。
195名無しさん@お腹いっぱい。:2005/09/03(土) 13:15:00
自分で書いたスクリプトを晒さないのは宗教とか契約上の問題なの?
196名無しさん@お腹いっぱい。:2005/09/03(土) 13:19:03
行数が多くて実行時間に問題あるなら、
シェルじゃなくてperlなどにすべきだな。
197名無しさん@お腹いっぱい。:2005/09/03(土) 13:19:47
printf "%032s\n" "222"
198名無しさん@お腹いっぱい。:2005/09/03(土) 13:21:39
>>192

while read line
do
 printf '%32s\n' "$line"
done < aaa.txt > bbb.txt

でいいんじゃないの。
何行あるファイルか知らないけど、5時間もかからないだろ。
printfもシェル組み込みコマンドだし。
外部コマンドを一切使わないのがポイントかも。
199名無しさん@お腹いっぱい。:2005/09/03(土) 13:25:52
awk '{ print " ",$0}' input > output
200名無しさん@お腹いっぱい。:2005/09/03(土) 13:34:01
>>199
ハァ? ネタのつもり? リアルヴァカ?
201195:2005/09/03(土) 13:45:58
みなさん、お返事ありがとうございます。
>>195
あまりに下らないのですが下に書いておきます・・・

>>197-198
ありがとうございます。試してみます。

>>199-200
実は私もawkを使ってました・・・

別端末なので不正確ですが

while read line
do
 i=($line の文字数数えて、32から引く。)
 until i -ge 32
 do
  line=`echo $line | awk '{print ","$0}'` (みたいな感じ)
 done
done < aaa.txt

変数の頭に半角スペースを格納すると
潰れてしまうので、カンマを入れた苦肉の策でした
(最後にsedで一括変換するつもりだった)
202名無しさん@お腹いっぱい。:2005/09/03(土) 13:59:32
>>190
firewall_enable="YES"
ipv6_firewall_enable="YES"

GENERIC だとモジュールになってるってだけで、普通に使えるけど。
203名無しさん@お腹いっぱい。:2005/09/03(土) 14:02:08
>>201
aaa.txt の中にカンマが入ってたらどうすんだとかは置いといて、
それで5時間もかかるのは until ループの中で i が変化してなくて
無限ループしてるだけってオチじゃないだろうな。
204名無しさん@お腹いっぱい。:2005/09/03(土) 14:46:12
>>203
あ、書き忘れましたが大丈夫です。
プロセスも見てみたし。

10万行もあるんですよ・・・
205名無しさん@お腹いっぱい。:2005/09/03(土) 14:58:14
>>201
ゲーッ
んなことやってりゃ遅くて当然だろ

シェルに行読みさせてそれを毎行毎行awkプロセス作成させて
awkに渡すぐらいなら
最初から素直にawkに読ませろよ
206名無しさん@お腹いっぱい。:2005/09/03(土) 15:32:23
>>205
お前は偉そうだ。
207名無しさん@お腹いっぱい。:2005/09/03(土) 15:36:17
>>206
それが気き食わないならコンサルタントを雇うべきです。
208名無しさん@お腹いっぱい。:2005/09/03(土) 15:43:19
気き食わない
209名無しさん@お腹いっぱい。:2005/09/03(土) 15:47:15
>>208
コンピューターの相手ばっかりしていないで、現実の人間と触れ合うべきです。
210名無しさん@お腹いっぱい。:2005/09/03(土) 15:55:34
実行速度で言うと

typeset -R32 LINE
while read LINE ; do
  echo "$LINE"
done < aaa.txt > bbb.txt

が一番速いんじゃないかな。
>>198もいいけど外部コマンドprintfを10万回も呼んじゃうからね。
どうせ外部コマンド使うなら>>205の言うように

awk '{printf("%32s\n", $0)}' aaa.txt > bbb.txt

にするべき。
これと上のとどっちが速いかは微妙。誰か試して。
211名無しさん@お腹いっぱい。:2005/09/03(土) 16:12:44
>>210
ただの直感だが、後者のが速そうだなあ。
awk一回の起動分の時間は、帳消しになる程度の誤差でしょ。
212名無しさん@お腹いっぱい。:2005/09/03(土) 16:23:46
>>210
だからぁ、printfは内部コマンドなんだよ。>>198も書いてる通り。
213名無しさん@お腹いっぱい。:2005/09/03(土) 16:30:19
typeset: not found
214名無しさん@お腹いっぱい。:2005/09/03(土) 16:30:33
>>210
typeset -R32 LINE ってどこのシェルの文法だよ?
bashですら動かないよ。
215名無しさん@お腹いっぱい。:2005/09/03(土) 16:49:11
>>210
shでprintfが使えるなんて初めて知った orz
216名無しさん@お腹いっぱい。:2005/09/03(土) 17:53:16
誰かsedでやって
217名無しさん@お腹いっぱい。:2005/09/03(土) 17:57:47
sed 's/^/ スペース32個 /;s/\(...ピリオド32個...\)$/\1/'


ところで printf がビルトインの sh ってどこにあるの?
bash のビルトインなのは知ってるけど。
218名無しさん@お腹いっぱい。:2005/09/03(土) 18:02:05
>>216
sed 's/^/                /
s/.*\(................................$\)/\1/
' aaa.txt > bbb.txt

全角スペースは半角スペース2つに直してね。
219名無しさん@お腹いっぱい。:2005/09/03(土) 18:05:40
>>217 はちょっと間違ってる。
>>218 が正解。

>>217
printfは、Solaris:sh以外、大抵ビルトイン。
FreeBSDとかでもね。
220名無しさん@お腹いっぱい。:2005/09/03(土) 18:13:00
solarisの/bin/shにはないな。
221名無しさん@お腹いっぱい。:2005/09/03(土) 18:15:02
FreeBSDの/bin/shにもないな
222名無しさん@お腹いっぱい。:2005/09/03(土) 18:27:04
>>221
あるよ。試してからカキコ汁!

% sh
$ type printf
printf is a shell builtin
223名無しさん@お腹いっぱい。:2005/09/03(土) 18:32:33
>>222
まさにその通り試してから書いたんだが
$ /bin/sh
$ type printf
printf is /usr/bin/printf
224名無しさん@お腹いっぱい。:2005/09/03(土) 18:37:43
>>223
uname -sr 希盆。

少なくとも4.11-RELEASEにはある。
225名無しさん@お腹いっぱい。:2005/09/03(土) 18:47:46
man builtinを読むと
4系列にはある
5.4以降にはない
226名無しさん@お腹いっぱい。:2005/09/03(土) 18:48:32
まちがった5.0以降ね
つまり5.0から分離されたんでしょう
227名無しさん@お腹いっぱい。:2005/09/03(土) 18:55:33
つまり
#/usr/bin/awk -f
で最初からawkスクリプトにしとけってこと?
228名無しさん@お腹いっぱい。:2005/09/03(土) 18:56:31
>>224
>>223ではないんだが...
% sh
$ uname -sr
FreeBSD 7.0-CURRENT
$ type printf
printf is /usr/bin/printf
$
で, /usr/src/bin/sh/builtins.def を見ると
#printfcmd printf
となってる.
229名無しさん@お腹いっぱい。:2005/09/03(土) 18:58:02
>>226
それって退化じゃん。外部コマンドにした理由教えて。
230名無しさん@お腹いっぱい。:2005/09/03(土) 19:05:24
理由を知る前から退化って言うじゃん?
231名無しさん@お腹いっぱい。:2005/09/03(土) 19:08:42
5.0リリースノートより
> sh(1) no longer implements printf as a built-in command because it was
> considered less valuable compared to the other built-in commands (this
> functionality is, of course, still available through the  printf(1)
> executable).
printfってさー、他のビルトインコマンドと比べて価値なくね?いらないべ
まーおまいらは外部コマンドのprintfでも使ってろよwww
と判断したもよう
232名無しさん@お腹いっぱい。:2005/09/03(土) 19:17:17
>>231
うーん。だとすると積極的な理由じゃないな。
printfが組み込みだと何らかの不具合が出るとか、
そういう理由がないと納得できん。

less valuable とは俺は思わないけどな。

たとえば、時々話題になるechoコマンドの非互換性を吸収するためにも
printfは重要だったのだけど、
組み込みじゃないと遅くなるから使えなくなる。
233名無しさん@お腹いっぱい。:2005/09/03(土) 19:25:32
printfを削ることでどれぐらいサイズが減るんだろう
削ることによる恩恵ってそんだけだよね?
234名無しさん@お腹いっぱい。:2005/09/03(土) 19:30:33
俺は外でも中でもどっちでもいいと思うけど、
/bin/shのような重要な部分に対して、自分たちが決めた最初の仕様を、
簡単に変えてしまったという点で、FreeBSDの連中は、アホだと思う。
235名無しさん@お腹いっぱい。:2005/09/03(土) 19:35:21
それがFreeBSDクオリティ。前から思ってたけどやっぱりあいつら馬鹿だよな。
236名無しさん@お腹いっぱい。:2005/09/03(土) 19:43:18
printf が消えたことぐらい、大騒ぎするほどの変更じゃないと思うけど。
大きな影響のある仕様変更は安易にやっちゃいかんだろうが、
初期に決めた仕様をずっとかたくなに守りつづけるっつーのも進歩の否定でしょ。

FreeBSD は 5 から perl や gawk も消えてシステムをスリムにしてるから、
その方針からすればむしろ一貫してるんじゃないかね。
237210:2005/09/03(土) 19:47:19
ちょっと亀レス気味だけど210に補足。
typeset -R は少なくとも HP-UX の /bin/sh (sh-posix)と
AIX の /bin/sh (ksh)では使える。
そしてこれらのいずれでも printf は外部コマンド。
238名無しさん@お腹いっぱい。:2005/09/03(土) 20:21:26
次のようなフォーマットのファイルで
text=B の次の行を color=FF0000 に
変えるにはどうすればいいでしょうか?

text=A
color=FF0000

text=B
color=00FF00

text=C
color=00FF00
239名無しさん@お腹いっぱい。:2005/09/03(土) 20:28:34
awk '{print} /text=B/ {getline; print "color=FF0000"}' FILE_NAME
240名無しさん@お腹いっぱい。:2005/09/03(土) 20:32:14
s/color=00FF00/color=FF0000/
241名無しさん@お腹いっぱい。:2005/09/03(土) 20:34:01
perl -ne '$_ =~ m/^text=B/ ? do { print $_, "color=FF0000\n"; <> } : print'
242名無しさん@お腹いっぱい。:2005/09/03(土) 20:37:15
>>63 >>65 >>69-72
だからprintfは、梨の奉公って言っただろ!!
243名無しさん@お腹いっぱい。:2005/09/03(土) 20:39:39
sed '/^text=B/,/^color=00FF00/s/00FF00/FF0000/'
244printf:2005/09/03(土) 20:39:44
おまいら俺に何か恨みでも在るのか
245名無しさん@お腹いっぱい。:2005/09/03(土) 20:40:56
>>243
そういう sed の使い方は思い付かなかった。感動した。
246名無しさん@お腹いっぱい。:2005/09/03(土) 20:42:45
#!/bin/sh
while read line
do
echo $line
if [ "$line" = "text=B" ]; then
read line
echo "color=FF0000"
fi
done
247名無しさん@お腹いっぱい。:2005/09/03(土) 20:45:23
>>245
ネタに感動するなよ。
実際、元の行が color=00FF00 になってない限り動かないじゃん。
248名無しさん@お腹いっぱい。:2005/09/03(土) 21:00:03
sedだと

sed '/text=B/ { n
c\
color=FF0000
}'
とかか?
249名無しさん@お腹いっぱい。:2005/09/03(土) 21:01:23
HPUXのprintfがどうなってるか
月曜日に試してみる
250名無しさん@お腹いっぱい。:2005/09/03(土) 21:10:18
>>247
つまらん奴だ。
sed -e '/^text=B/,/^color=/s/color=.*/color=FF0000/'

251名無しさん@お腹いっぱい。:2005/09/03(土) 21:17:30
>>250
その -e オプションって何の意味があるの?
252名無しさん@お腹いっぱい。:2005/09/03(土) 21:20:24
#!/usr/local/bin/python
import sys
line = sys.stdin.readline()
while line:
  print line,
  if line == 'text=B\n':
    sys.stdin.readline()
    print 'color=FF0000'
  line = sys.stdin.readline()
253名無しさん@お腹いっぱい。:2005/09/03(土) 23:27:05
>>239,241,246,248,252
なるほど.
こういうときは1行読んで改めて出力すればいいんですね.

>>240
これだと置換したくない行まで置換されてしまいます.

>>243
sed でこういうアドレス指定もできるんですね.
今回はこの方法を利用させていただきます.

ありがとうございました.
254I'm not 246 nor 248:2005/09/03(土) 23:35:33
>>253
俺は >>246 >>248 の方が美しいと思うが。
255名無しさん@お腹いっぱい。:2005/09/04(日) 00:08:38
>>243>>250以外はロジック一緒なんだから
美しいも糞もないと思うが。
256名無しさん@お腹いっぱい。:2005/09/04(日) 03:00:29
>>248 が一番美しいと思う
それ以外は、普通 or 力技で特筆するものはない
257名無しさん@お腹いっぱい。:2005/09/04(日) 03:44:33
>>256
1行で書けないのがやだ
258not 248:2005/09/04(日) 07:59:14
>>257
1行に書けるよ。↓にすればいいじゃん。

sed '/text=B/{ n; s/.*/color=FF0000/; }'

cをsに変えたけど、動作は同じ。>>248 が美しい。

>>250 は text=Bの行にまで置換動作が入るのが無駄だし、
この場合はいいけどバグを誘発する可能性がある。
259名無しさん@お腹いっぱい。:2005/09/04(日) 11:47:34
俺は250の方が良いと思う。
260名無しさん@お腹いっぱい。:2005/09/04(日) 11:59:10
>>243>>250が少なくとも他のプログラムと挙動/仕様が違うのは
確かだな。

>>243>>250以外は問答無用で次の行を置換する(次の行の内容は
問わない)という仕様だが、
>>250はtext=Bからcolor=までの全行について、置換動作を行う。
261名無しさん@お腹いっぱい。:2005/09/04(日) 12:11:56
フォーマットが拡張された場合に応用が効くのは>>250の方だろう。

>>248は普通かそれ以下で、美しいとは思えん。
262名無しさん@お腹いっぱい。:2005/09/04(日) 12:12:13
どっちも、最初に提示された見えている部分の要求は満たしているから、
どっちがいいとは断言できん。
263名無しさん@お腹いっぱい。:2005/09/04(日) 13:25:13
たとえば、

text=B
color=xxxx
depth=xxxx

というような仕様だったとして、
color=の行と、depth=の行の順番は問わない、(どちらが先かわからない)
という場合、

>>258 ならちょっと直せば対応できるが、
>>250 のロジックでは破綻するので使えない。

よって、>>258 がフレキシブルで美しい。
264名無しさん@お腹いっぱい。:2005/09/04(日) 13:35:17
>>263
ポインタが逆では。
265名無しさん@お腹いっぱい。:2005/09/04(日) 13:36:08
>>264
逆じゃないだろ。
266名無しさん@お腹いっぱい。:2005/09/04(日) 13:38:42
どうちょっと直すのかとどう破綻するか書いてみれ。
267名無しさん@お腹いっぱい。:2005/09/04(日) 13:53:10
>>266
しょうがないなぁ、、>>258 は↓でOK。

sed '/text=B/{ n; N; s/color=[^\n]*/color=FF0000/; s/depth=[^\n]*\>/depth=24/;}'

>>250 は置換範囲を特定できないから、このロジックのままでは書けない。
268名無しさん@お腹いっぱい。:2005/09/04(日) 13:58:06
>>250を直すと
sed -e '/^text=B/,/^$/s/color=.*/color=FF0000/'
269名無しさん@お腹いっぱい。:2005/09/04(日) 14:00:01
>>268
それだと、
text=Bセクションのあとに必ず空行があることを
勝手に仮定している。そこでEOFかも知れないから、
それでは駄目。仕様を変えてはいけない。

よって、>>267 がモストエレガント。
270名無しさん@お腹いっぱい。:2005/09/04(日) 14:21:36
空行が嫌なら '^text=' にも出来るし、EOFが来ても別に問題は無い。
釣り?
271名無しさん@お腹いっぱい。:2005/09/04(日) 14:32:49
>>270
EOFじゃなくて、

text=B
depth=8
color=00FF00
text=C
:

とつながっていた場合問題だろ。

'^text=' って何だ? ちゃんと書き直してみろよ。
272名無しさん@お腹いっぱい。:2005/09/04(日) 14:37:04
>>270
次に来るのが text=C のセクションじゃなくて、
置換に全く関係ない file=/hoge とかいう別セクションかも知れない。
なので、やっぱり >>250 では破綻。
273名無しさん@お腹いっぱい。:2005/09/04(日) 14:45:13
やっぱ釣りか。
274名無しさん@お腹いっぱい。:2005/09/04(日) 14:50:49
>>267 でcolor,depth の二つじゃなくて100種類くらいあったらどうするよ。
275名無しさん@お腹いっぱい。:2005/09/04(日) 14:52:33
わかってるとは思うけど、
>>263 で追加した仕様のファイル入力に対し、
color= も depth= も所定の値に置換すること、という意味だよ。

text=以外の、無関係な親セクションもあるかも知れないし、
セクション間では空行が空いているとは限りません。

>>258 系は >>267 と書き直せました。

>>250 を書き直せた方はまだいませんね。
276名無しさん@お腹いっぱい。:2005/09/04(日) 15:05:47
>>267
depth=24
の24って何?どこから来たの?
277名無しさん@お腹いっぱい。:2005/09/04(日) 15:08:49
>>276
>>263 自身が追加した仕様だろ。別に24じゃなくてもなんでもいいだろ。単なる置換例。
278名無しさん@お腹いっぱい。:2005/09/04(日) 15:11:00
横レスだが、元のお題は>>238なんだろ?
なんで depth= やら親セクションやらが出てくるんだ?
自分の主張に有利なように勝手にお題を妄想するのはよせ。
279名無しさん@お腹いっぱい。:2005/09/04(日) 15:13:01
もともと仕様追加のことを言い出したのは>>261で、>>263ではないと思われ。
280名無しさん@お腹いっぱい。:2005/09/04(日) 15:15:32
元のお題よりフクザツな構造だと、S式なのかXMLなのかしらんが
階層構造っぽくなってたりして、どのみちこんな単純な方式では
上手くいかないことが多いと思う。
そういう場合はsedだと荷が重いでしょ、いずれにせよ。
281名無しさん@お腹いっぱい。:2005/09/04(日) 15:17:36
>>278
元の題は >>238 だが、その解が複数あって、そのどちらが美しいかという話になり、

>>261 が、「フォーマットが拡張された場合に応用が効くのは」どちらか?
という題を出したため、

>>263 が仕様を拡張してみたの。

おれは >>267 の方がいいと思うが、 \> が一箇所余分。
sed '/text=B/{ n; N; s/color=[^\n]*/color=FF0000/; s/depth=[^\n]*/depth=24/;}'
だな。
282名無しさん@お腹いっぱい。:2005/09/04(日) 15:26:08
283名無しさん@お腹いっぱい。:2005/09/04(日) 15:28:31
284名無しさん@お腹いっぱい。:2005/09/04(日) 15:30:17
オナり杉
285名無しさん@お腹いっぱい。:2005/09/04(日) 15:30:30
>>283
構造は全然複雑になってない。
286名無しさん@お腹いっぱい。:2005/09/04(日) 15:33:17
>>274 100種類くらいあっても >>267 方式なら、大変だけど対応はできる。
>>250 方式だと2種類に増えただけで対応できなくなる。
287名無しさん@お腹いっぱい。:2005/09/04(日) 15:35:06
そこでXgawkですよ
288名無しさん@お腹いっぱい。:2005/09/04(日) 15:36:40
>>286
(゚Д゚)ハァ?
289名無しさん@お腹いっぱい。:2005/09/04(日) 15:42:46
>>288
「ハァ」というなら>>250 方式で対応してみろよ。二種類だけでいいから。
290名無しさん@お腹いっぱい。:2005/09/04(日) 15:43:05
sed -e '/^text=B/,/^color=/s/^color=.*/color=FF0000/'
    -e '/^text=B/,/^depth=/s/^depth=.*/depth=24/'
とか数が増えるだけ(で省略不可で重複なし)ならどっちでも対応できるけど
単純置換以上のことをsedでやるのがそもそもBa(ry
291名無しさん@お腹いっぱい。:2005/09/04(日) 15:45:33
うーむ。俺はスクリプトやワンライナーの類って「書き捨て」であって、
要求仕様を過不足無くシンプルなカタチで実現できるものが良い、
と思ってたんだが……
拡張性なんて求めるもんなのか?

こんな1行からせいぜい数行のスクリプト、仕様が変わったら書き直した
方が早いって。
ちなみに俺は、誰も誉めてないが一番最初に出てきた>>239の回答が、
模範的なワンライナーであって、全く問題がないと思った。他より
イイ、かどうかは知らないが、書き直す必要は感じない。
292名無しさん@お腹いっぱい。:2005/09/04(日) 15:47:49
>>290
それだと、先に /^text=B/,/^color=/ のアドレス範囲条件に
引っかかって、/^text=B/,/^depth=/ の範囲に引っかからない
可能性があるから、期待通り動かない。
293名無しさん@お腹いっぱい。:2005/09/04(日) 15:49:04
>>290
だから 24 は上書きするのかと。
294名無しさん@お腹いっぱい。:2005/09/04(日) 15:50:58
250だと重複はアレだが省略は可だな。
295290:2005/09/04(日) 15:53:21
今日は287から参加なんでそんなにつっこまれてもこまるんだが
>>292 試してみた?
>>293 置換の必要がないならdepthの置換は省略できる
296名無しさん@お腹いっぱい。:2005/09/04(日) 15:54:05
>>290
本題に関係ないが、なんでも -e でつなぐくせやめれ。
シングルクォート内で改行または ; でいいんだよ。
297名無しさん@お腹いっぱい。:2005/09/04(日) 15:55:53
>>292 は嘘。動く。
しかし、項目一つあたりの記述量が >>290 の方が多い。
298名無しさん@お腹いっぱい。:2005/09/04(日) 16:04:19
>>294 省略されたアイテムをデフォルト値から変更したい妄想
>>296 くせじゃないんだけど例示するときは少しでも見易いほうがいいかと思って...
299名無しさん@お腹いっぱい。:2005/09/04(日) 16:04:56
>>290 だと、アドレスを取り直してるので、
もはや >>250 の修正とは言えなくなっている。
300名無しさん@お腹いっぱい。:2005/09/04(日) 16:07:18
268と270で充分対応可能。
301名無しさん@お腹いっぱい。:2005/09/04(日) 16:12:52
302名無しさん@お腹いっぱい。:2005/09/04(日) 16:16:17
(text|file)で対応可能。
text,file,hoge,mage... ってセクションが100種類位あったらどうするよってのは
適切なターミネータを設定しないファイル仕様が破綻している。
303名無しさん@お腹いっぱい。:2005/09/04(日) 16:27:14
>>302
それって拡張正規表現?
GNU sed 4.0.5 では動かなかった。

それに、置換対象の text= 以外の file=とかの仕様によって影響を受けるのは
美しくない。
304名無しさん@お腹いっぱい。:2005/09/04(日) 16:29:10
>>303
いくらなんでもカッコ、コッカだの分岐だのは対応してるだろ。
カッコ、コッカだの|だのに\エスケープがいるとかじゃねえの?
305名無しさん@お腹いっぱい。:2005/09/04(日) 16:31:17
正規表現の話題は、
正規表現
http://pc8.2ch.net/test/read.cgi/unix/1039165754

sedの話題は、
sed
http://pc8.2ch.net/test/read.cgi/unix/1085730992

に書き込めとあれほど・・

お前ら、シェルスクリプトの話をしようぜ。
306名無しさん@お腹いっぱい。:2005/09/04(日) 16:33:54
結論。
sedなどの外部コマンドを使わず、
シェルだけで処理している >>246 が一番美しい。
307名無しさん@お腹いっぱい。:2005/09/04(日) 16:37:33
俺は>>291に同意なんだがこのスレ的な結論は>>306でいいよ。
308名無しさん@お腹いっぱい。:2005/09/04(日) 17:33:21 BE:387941696-
>>306
`[' は外部コマンドなんですけど。
309名無しさん@お腹いっぱい。:2005/09/04(日) 17:37:49
>>308
確認した?
310名無しさん@お腹いっぱい。:2005/09/04(日) 17:38:24
仕様の拡張の仕方によって変わるだろ。
なんで、こっちがいいとか決め付けられるんだろうね。
311名無しさん@お腹いっぱい。:2005/09/04(日) 17:42:01
>>308
昔はたしかに外部コマンドだったけど、
いまでも test を内蔵してない sh ってあるの?
312名無しさん@お腹いっぱい。:2005/09/04(日) 17:51:39
>>308
現存するOSの/bin/shで、[ が外部コマンドしかないものは存在しない。
それに、嫌なら case文を使えばいいだけのこと。
313名無しさん@お腹いっぱい。:2005/09/04(日) 17:59:40
なんかプロジェクトがトラブるネタ見るようで面白かったな。
RFPに書いてない内容は多様に変化しうる。

お客のほうの説明能力の欠如を指摘しないとまずいだろ(藁
314名無しさん@お腹いっぱい。:2005/09/04(日) 18:10:20 BE:344837186-
>>312
「現存するOS」の一覧ヨロシコw
315名無しさん@お腹いっぱい。:2005/09/04(日) 18:15:35
>>308 が反例をあげるのが筋かと。
316名無しさん@お腹いっぱい。:2005/09/04(日) 18:23:37
蟹飯&Rob Pikeの「Unix Programming環境」(だったか)には、testは外部コマンドで
効率が悪いからcase使えみたいに書いてあったような気がするな
大昔の話だが……
317名無しさん@お腹いっぱい。:2005/09/04(日) 18:31:43
Solarisでは、外部コマンド版の [ の方は元から存在しません。
外部コマンド版があるのは testのみです。
もちろん、誰かが誤って削除したのでもありません。
318名無しさん@お腹いっぱい。:2005/09/04(日) 19:19:37
>>315
Unix V7
319名無しさん@お腹いっぱい。:2005/09/04(日) 19:20:21
>>317
つSolaris 1.0
320名無しさん@お腹いっぱい。:2005/09/04(日) 19:44:40
>>318-319
確かにどちらも現存しませんね。
321名無しさん@お腹いっぱい。:2005/09/04(日) 22:05:17
>>306 はありえなさすぎ
俺は >>246 じゃないけど、これはネタみたいなもんでしょ?

つーか、マジで言ってるならセンス無いよ
322名無しさん@お腹いっぱい。:2005/09/04(日) 22:14:57
>>320
現存してるよ。
323名無しさん@お腹いっぱい。:2005/09/04(日) 22:15:46
>>317
2.9BSD
324名無しさん@お腹いっぱい。:2005/09/04(日) 22:27:57
>>322 は「現存」の意味を誤解しているようだ。
325名無しさん@お腹いっぱい。:2005/09/04(日) 23:52:21
>>324は「現存」の意味を誤解しているようだ。
326名無しさん@お腹いっぱい。:2005/09/05(月) 00:04:56
所詮シェルスクリプト。移植性の問題であんまり悩んでも禿げるだけだぞ。
327名無しさん@お腹いっぱい。:2005/09/05(月) 00:06:23
>>321
別にネタってわけでもないんじゃないの。
俺なら絶対 sed か awk を使うけれども。
328名無しさん@お腹いっぱい。:2005/09/05(月) 00:35:02
>>327
つperl
329名無しさん@お腹いっぱい。:2005/09/05(月) 00:52:13
>>328
sed や awk で同じぐらいラクに書ける仕事ならそっちを使う俺がいます。
まあ、perl の -i オプションが便利だったりすることは多いけれども。
(GNU の sed にはついてるんだっけ?)
330名無しさん@お腹いっぱい。:2005/09/05(月) 00:54:00
>>322
今現在、実際にそのOSを稼働・運用していて、
シェルスクリプトを外から持ち込むことがあって、
その互換性を気にしなければならない状態でにあるのでなければ、
「現存している」とは言えない。

もちろん、コレクター趣味的とか、博物館的に
稼働させているものは除く。
331名無しさん@お腹いっぱい。:2005/09/05(月) 00:56:26
数年前の話だけど、SonyのNEWSあたりなら平気で稼動してるのを見たこと
あるよ。今はどうだか知らないけどね。
332名無しさん@お腹いっぱい。:2005/09/05(月) 01:09:32
>>331
NEWS-OSの、4.2.1でも、
[ は/bin/shの組み込みコマンドだったよ。
333名無しさん@お腹いっぱい。:2005/09/05(月) 01:22:44
>>330
もちろん、「今現在、実際にそのOSを稼働・運用していて、
シェルスクリプトを外から持ち込むことがあって、
その互換性を気にしなければならない状態」ですよ。
334名無しさん@お腹いっぱい。:2005/09/05(月) 07:10:57
>>333
ほう、おもしろい。で、OSは?
UNIX V7 かい? それとも 2.9BSD かい?

あ、言っとくけど、Solaris 1.0 なら [ は /bin/sh builtin だよ。
335名無しさん@お腹いっぱい。:2005/09/05(月) 07:54:17
if /bin/test $a -eq 0
とすれば悩まなくていいよ
336名無しさん@お腹いっぱい。:2005/09/05(月) 11:38:22
>>335
流れ欲嫁。
testが外部コマンドのOSが今でも使われているかどうかを議論してるの。
testが外部コマンドだと遅いので、そいう場合については
testの代わりにcaseを使うと >>312 がすでに言ってる。
337名無しさん@お腹いっぱい。:2005/09/05(月) 14:13:03
>>334
いやMINIX2.0
338名無しさん@お腹いっぱい。:2005/09/05(月) 15:25:58
外部コマンドかどうかなんて速度にしか影響しないだろ。
速度を出す必要のあるスクリプトを何でわざわざシェルスクリプトで書かなきゃならんのだ。
perlでも使っとけ。
339名無しさん@お腹いっぱい。:2005/09/05(月) 15:38:24
340名無しさん@お腹いっぱい。:2005/09/05(月) 16:03:07
>>337
やっぱりネタだったか。
結論: testおよび [ は内部コマンドと仮定して問題なし。
341名無しさん@お腹いっぱい。:2005/09/05(月) 17:21:37
そういう想定って美しさとか関係ないじゃん。
342名無しさん@お腹いっぱい。:2005/09/05(月) 20:10:39
testがとうとか、はっきりいってどっちゃでもいいよな。

自分で組むなら、最悪を想定してcaseを使うが、
他人のプログラムなら動けばそれでいいよ。
343名無しさん@お腹いっぱい。:2005/09/05(月) 23:32:07
caseをどう使うんだ?
344名無しさん@お腹いっぱい。:2005/09/06(火) 07:34:13
>343
>312
345名無しさん@お腹いっぱい。:2005/09/06(火) 12:37:23
>>344
(゚Д゚)ハァ?
`case WORD in [ [(] PATTERN [| PATTERN]...) COMMAND-LIST ;;]... esac'
これのどこに test の条件文を書くところがあるのですかって質問なんですが。
わかってないならレスするなよ。
346名無しさん@お腹いっぱい。:2005/09/06(火) 12:44:57
248が発狂したか。
347名無しさん@お腹いっぱい。:2005/09/06(火) 12:47:06
>345
流れ読めよ。

>>246みたいな
if [ "$line" = "text=B" ]; then XXX; fi
程度なら、testがもし外部だった時のことも考えると、caseを使って
case x$line in xtext=B) XXX; esac
ってやるって話だろ。

それ以上複雑な処理はcaseじゃできね〜よ。
348345:2005/09/06(火) 13:53:46
すまないニダ。火病をおこしてしまったスムニダ。
349名無しさん@お腹いっぱい。:2005/09/06(火) 15:52:29
>>347
横レスすまそ。
case文の場合は case x$line in ... とか頭にx付ける意味ないよ。
case "$line" in ... でよい。
というか、x$line だと、$lineの中身にスペースがある場合、回避できないので、
ダブルクォートの方が重要。

それと、イマドキのtestでは、
[ x$hoge = xhage ] みたいにする必要なし。
[ "$hoge" = hage ] でよし。
たとえ $hoge の内容が = とか -f とか、
testを混乱させそうな文字列だったとしても
イマドキのtestは混乱しない。
350名無しさん@お腹いっぱい。:2005/09/06(火) 16:26:49
更新スクリプトを作りたいんだけど。

/home/eva.txtにかかれている。
*
neon genesis 00
*
を取得して。

/home/neon-genesis.txtにかかれている
*
neon genesis 01
*
をneon genesis 00に書き換えたいだけど

数字の値は常に変わるとして、文字列を探し出して、
その行を削除&書き換えするにはどうすればよいの?
351347:2005/09/06(火) 16:29:26
>349
お外は暴風域。通販が届きません。;;

xつけてるのは変数が空だった時の処理をするためね。
test -z $line || XXXをcase x$line in x) ;; *) XXX;; esacみたいに。
あの例じゃ別に要らないんだけど手が勝手にxつけるのです。

""はどうだっけ。testなら必須だけど、caseの場合は
x$lineって抜き出してから$lineを置き換えるから
必要なかった気もするんだけど。まあ、最悪の
可能性を考慮するんなら、あったほうがいいだろうね。
352名無しさん@お腹いっぱい。:2005/09/06(火) 16:35:34
>>351
case で頭に x 付けなくても、変数が空だった場合の処理は
期待通り正しくされる。試してみればわかる。
353名無しさん@お腹いっぱい。:2005/09/06(火) 16:36:06
>>351
わかっていないならレスするな
354名無しさん@お腹いっぱい。:2005/09/06(火) 16:46:56
>>351
case x$line in x) ;; *) XXX;; esac
なら、

case "$line" in '') ;; *) XXX;; esac
で桶。

さらに、やり方を変えて、
case "$line" in ?*) XXX;; esac
の方が美しい。
355名無しさん@お腹いっぱい。:2005/09/06(火) 16:49:03
>352
ああ、言葉が足らなかったな。

case $line in "") ;; *) XXX;; esacと
case x$line in x) ;; *) XXX;; esacで、
俺は後者のが格好いいと思うからxをつけるわけだ。
case $line in ) ;; *) XXX;; esacじゃパースエラーだしね。

>353
ふ〜ん。
356名無しさん@お腹いっぱい。:2005/09/06(火) 16:51:27
>>355
>>354 の下から3行分
357名無しさん@お腹いっぱい。:2005/09/06(火) 16:52:06
>354
ああ、?*)でよかったのか。気付かなかった。
ナイスだ。こんどからそっち使おう。thx
358名無しさん@お腹いっぱい。:2005/09/06(火) 17:00:30
>>350
pat1="neon genesis"
line=`grep "$pat1" /home/eva.txt`;
pat2=`echo $line | sed -e 's/ *[0-9]* *$//'`
echo "/$pat2/
s/.*/$line/
w
q" | ed /home/neon-genesis.txt

ってのと

pat1="neon genesis"
line=`grep "$pat1" /home/eva.txt`;
pat2=`echo $line | sed -e 's/ *[0-9]* *$//'`
perl -niorig -e "s/$pat2.*/$line/" /home/neon-genesis.txt

のどっちがいい?

後、どっちのファイルでも同じ文字列を検索すればいいのなら、
pat2=...はpat2=$pat1ですむね。
359名無しさん@お腹いっぱい。:2005/09/06(火) 17:55:40
>>358 サンク、 前者を使わせていただきます。
360名無しさん@お腹いっぱい。:2005/09/06(火) 18:44:54
bash依存かどうかってどうやれば調べられますか?
361名無しさん@お腹いっぱい。:2005/09/06(火) 19:13:04
>>360
そのスクリプトを Solarisで動かしてみる。
362名無しさん@お腹いっぱい。:2005/09/06(火) 19:31:18
Solaris の bash で動かしてしまうという罠。
363名無しさん@お腹いっぱい。:2005/09/06(火) 19:45:26
bash依存じゃなくても他のコマンドがネックになっている罠。
364名無しさん@お腹いっぱい。:2005/09/06(火) 19:47:14
HTML lintみたいな感じでshell script lintとか作ったら神になれるんじゃないの?
非対応OSとかが分かるようなやつ。
365名無しさん@お腹いっぱい。:2005/09/06(火) 19:57:43
>>364
いいね。
がんばれ!
366名無しさん@お腹いっぱい。:2005/09/06(火) 20:37:44
完璧ではないが、vimだとある程度わかるぞ。
367名無しさん@お腹いっぱい。:2005/09/07(水) 12:53:17
364氏誕生の瞬間に立ち会えて幸せです
368名無しさん@お腹いっぱい。:2005/09/08(木) 03:21:40
>>340
ネタじゃないよ。アマチュア無線のパケットのルータ兼サーバとして現用中。
ログの整理/監視などにスクリプトは欠かせない。

なんとかして否定したいのだろうが、世の中古いものが結構現役で利用されて
いたりするものだよ。だいたいきみらが言う「現存」の定義が激しくあいまい
だしな。
369名無しさん@お腹いっぱい。:2005/09/08(木) 03:23:39
というわけでtestおよび [ は内部コマンドとは限らないので
できるだけ使うなw
370名無しさん@お腹いっぱい。:2005/09/08(木) 07:26:21
>>368
minixって、たしかシンボリックリンクも使えないやつだろ。
状況が特殊過ぎる。やっぱり test [ は builtin前提で問題ない。
もともと、testでもcaseでも書ける場合はなるべくcaseで書くという
習慣は残っているから、それで十分。
371名無しさん@お腹いっぱい。:2005/09/08(木) 10:15:19
MINIX is obsolete
372名無しさん@お腹いっぱい。:2005/09/08(木) 10:30:28
外部コマンドでも別に使えるからいいだろう。
内部コマンドと仮定するのは間違ってるが。
373名無しさん@お腹いっぱい。:2005/09/08(木) 11:01:18
>>372
>外部コマンドでも別に使えるからいいだろう。
外部コマンドなら使いたくない状況がある。

>内部コマンドと仮定するのは間違ってるが。
間違っていない。

漠然と「testって外部コマンドですよね?」と聞かれた時、
「アフォか。イマドキtestは内部コマンドだ。」と言い切って問題ない。
testは内部コマンド前提で書いて問題ない。
374名無しさん@お腹いっぱい。:2005/09/08(木) 11:15:45
同じ事繰り返して言ってるだけじゃん。
お前のような奴が「イマドキshはbashだ。」とか言い切るんだ。
375名無しさん@お腹いっぱい。:2005/09/08(木) 11:24:36
そんなに外部コマンドを使いたくなければ、
[ ] じゃなくて [[ ]] を使えばいい。
[[ ならば外部コマンドはあり得ない。
376名無しさん@お腹いっぱい。:2005/09/08(木) 11:40:53
>>374
イマドキじゃないFreeBSDユーザーです
377名無しさん@お腹いっぱい。:2005/09/08(木) 11:57:41
「イマドキtestは内部コマンドだ」と「testは内部コマンド前提で
書いて問題ない」というのは似てるようでまったく別の話だ。

373が勝手にイコールで結ぶのは構わんが、
それを一般化するな。迷惑だ。
378名無しさん@お腹いっぱい。:2005/09/08(木) 13:01:31
素朴な疑問なんだけど
testが外部コマンドだと困るってどんな状況?
379名無しさん@お腹いっぱい。:2005/09/08(木) 14:26:18
>>378
i=1
while [ $i -lt 10000 ]; do
:
とかの場合だろ。
380名無しさん@お腹いっぱい。:2005/09/08(木) 15:05:29
>>379
この場合って、どうせexpr呼ぶから、[ が外部かどうかにかかわらず重そうだ
381名無しさん@お腹いっぱい。:2005/09/08(木) 15:09:45
>>380
i=$(($i + 1))
382名無しさん@お腹いっぱい。:2005/09/08(木) 15:25:54
383名無しさん@お腹いっぱい。:2005/09/08(木) 17:11:26
>>381
「bash依存!」と書こうとしたら、、、なんだ、
/bin/shでも使えてしまうじゃないか、、
今度から expr の代わりにそう書こう。
384名無しさん@お腹いっぱい。:2005/09/08(木) 18:35:02
/bin/sh -c 'i=1; while [ $i -lt 10000 ]; do i=`expr $i + 1`; done'
   13.08s user 16.48s system 109% cpu 26.998 total
/bin/sh -c 'i=1; while [ $i -lt 10000 ]; do i=$(($i + 1)); done'
   0.18s user 0.02s system 99% cpu 0.200 total
/bin/sh -c 'i=1; while /bin/test $i -lt 10000; do i=$(($i + 1)); done'
   7.75s user 7.56s system 109% cpu 13.923 total
/bin/sh -c 'i=1; while /bin/test $i -lt 10000; do i=`expr $i + 1`; done'
   19.68s user 24.30s system 107% cpu 40.945 total

expr重!!

番外
perl -e '$i=1; while ($i < 10000) { $i=$i+1; }'
   0.01s user 0.01s system 12% cpu 0.118 total
385名無しさん@お腹いっぱい。:2005/09/08(木) 19:18:52
結論:シェルスクリプトはうんこ
386名無しさん@お腹いっぱい。:2005/09/08(木) 21:01:19
[ が内部か外部かって話してるときに、$((...)) があるのを前提にされてもなぁ
387名無しさん@お腹いっぱい。:2005/09/08(木) 21:03:25
やっぱり、かなり違うんだな。
388名無しさん@お腹いっぱい。:2005/09/08(木) 21:08:11
>>386
何か問題でも?
389名無しさん@お腹いっぱい。:2005/09/08(木) 22:23:21
>386
まあ、そんな感じはあるよなあ。

1: bash派。存在するオプションは何でも使い、現在の実装が仕様。好きなUNIXはLinux。
 座右の銘:testは内部コマンド前提
2: 歴史的仕様追従派。歴史的なオプション、実装を仕様とする。好きなUNIXはBSD。
 座右の銘:test -nって昔からあったっけ?←自分の使わないオプションには懐疑的

>388
2番に属する人間からみると、testが内部として実装された後に実装された、
なおかつ昔のshellだとエラーになる構文である$((...))を前提にされてもねえ
って感じなわけだ。

例えるならこんな感じ。

383: bash嫌悪派。bashを憎みbashにしかないコマンドを利用する奴を憎む。
 座右の銘:/bin/shにあるならいっか

383よ、お前はbashが嫌いなだけで本当はLinux好きだろう!!!みたいなw
390名無しさん@お腹いっぱい。:2005/09/08(木) 22:30:38
結局業務だとHP-UXとかまだまだ健在で
しかもデフォルトインストール以外のアプリ禁止とかあるからなぁ
391名無しさん@お腹いっぱい。:2005/09/08(木) 22:31:31
$((...))がPOSIXで規定されてると知ってて言ってるんだろうな。
392名無しさん@お腹いっぱい。:2005/09/08(木) 22:32:15
>>389
そういうふうに分類するなら、俺は

3: POSIX派。 POSIXの仕様↓を尊重する。
ttp://www.opengroup.org/onlinepubs/009695399/utilities/contents.html
座右の銘:オリジナルBourne shellのことはもう忘れろ。

だな。
393名無しさん@お腹いっぱい。:2005/09/09(金) 02:28:09
$(())なんて構文作らずに、
testと同じようにexprを内部コマンドにしちまえばよかったんだよ。
394名無しさん@お腹いっぱい。:2005/09/09(金) 07:39:40
>>393
確かにそうなんだけど、計算式のところがちょっとシンプルになってこれはこれでよさげだぞ。

$ i=2; i=`expr $i \* 3`; echo $i
6

c-yan@YUMI ~
$ i=2; i=$((i*3)); echo $i
6
395名無しさん@お腹いっぱい。:2005/09/09(金) 09:24:05
386と389は出直してこい派
396名無しさん@お腹いっぱい。:2005/09/09(金) 11:42:32
>>384
1万回ループなら↓が基本。

for i in 0 1 2 3 4 5 6 7 8 9; do
for j in 0 1 2 3 4 5 6 7 8 9; do
for k in 0 1 2 3 4 5 6 7 8 9; do
for l in 0 1 2 3 4 5 6 7 8 9; do
:
done; done; done; done

test内部、$((...))使用のwhileループより約5倍速い。
397名無しさん@お腹いっぱい。:2005/09/09(金) 11:53:26
12345回ループならどうするよ
398名無しさん@お腹いっぱい。:2005/09/09(金) 11:55:05
素数の方がいいか
399名無しさん@お腹いっぱい。:2005/09/09(金) 11:58:32
勝手に基本とか言うなと。
400名無しさん@お腹いっぱい。:2005/09/09(金) 12:17:30
for i in `yes | head -12345`; do
...
done
401名無しさん@お腹いっぱい。:2005/09/09(金) 13:01:20
yesコマンドってSolaris9で復活したんだっけ?
Solaris8にはyesは無いなぁ。
402名無しさん@お腹いっぱい。:2005/09/09(金) 15:14:27
$(Φ)
403名無しさん@お腹いっぱい。:2005/09/09(金) 16:48:25
>>400
何回目か取得できん
404名無しさん@お腹いっぱい。:2005/09/09(金) 17:18:19
じゃ yes '' | cat -n | head -12345 で。
405名無しさん@お腹いっぱい。:2005/09/09(金) 20:58:03
$ time sh -c 'for i in `yes "" | cat -n | head -10000`; do echo $i; done >/dev/null'
real 0m0.415s user 0m0.293s sys 0m0.113s

$ time awk 'BEGIN { for (i = 1; i < 10000; ++i) { print i } }' >/dev/null
real 0m0.166s user 0m0.157s sys 0m0.008s

$ time perl -e 'for ($i = 1; $i < 10000; ++$i) { print "$i\n" }' >/dev/null
real 0m0.210s user 0m0.202s sys 0m0.008s

意外なほどshが健闘
406名無しさん@お腹いっぱい。:2005/09/09(金) 21:23:01
そりゃ外部コマンドをガンガン呼び出してりゃ負けるわ。
やっぱPerlってawkより重いのね。
407名無しさん@お腹いっぱい。:2005/09/09(金) 21:27:49
>>406
いや、負けるのは分かりきっていたんだが、この程度の差で済んでいたのが
意外だった。
408名無しさん@お腹いっぱい。:2005/09/09(金) 23:51:37
>>405
うちのFreeBSD-5.3で、ループを10万にしてテストすると
  sh: 0.40u
  awk: 0.17u
  perl(5.8): 0.13u
こんな感じだった
409名無しさん@お腹いっぱい。:2005/09/10(土) 00:12:20
良く見ろ、shだけループ回数が1回多いぞ。
shが一番おそいのは、これが原因に違いない!!!
410名無しさん@お腹いっぱい。:2005/09/10(土) 00:22:23
jot 10000でも使ってみる
411名無しさん@お腹いっぱい。:2005/09/10(土) 06:17:34
シェルスクリプトで適当な乱数が必要ならjotを使うというのを最近知った


412名無しさん@お腹いっぱい。:2005/09/10(土) 09:18:26
>>401
yes がないと厳しいな

$ time sh -c 'i=0; while [ $i -lt 100000 ]; do echo $i;i=$((i+1));done>/dev/null'

real 0m21.687s
user 0m21.187s
sys 0m0.468s

$ time sh -c 'for i in `while :;do echo;done|cat -n|head -100000`;do echo $i;done>/dev/null'

real 0m17.320s
user 0m15.387s
sys 0m1.761s

$ time sh -c 'for i in `yes ""|cat -n|head -100000`;do echo $i;done>/dev/null'

real 0m8.821s
user 0m8.136s
sys 0m0.714s
413名無しさん@お腹いっぱい。:2005/09/10(土) 10:24:22
>>412
だから yesがない場合、>>396 方式が基本なんじゃない?
414名無しさん@お腹いっぱい。:2005/09/10(土) 10:43:07
yesもどきぐらい書けよ
while :; do echo ''; done | cat -n
415名無しさん@お腹いっぱい。:2005/09/10(土) 11:10:32
>>414
while :; do echo; done | cat -n
416名無しさん@お腹いっぱい。:2005/09/10(土) 11:17:57
>>414-415
欲嫁!

>>412 はその「yesもどき」をすでに使っている。
で、その「yesもどき」では遅いから「yes がないと厳しいな」と
言っている。

それに対して >>413 が、「yesがないなら」(yesもどきを使わずに)
>>396 使え、と言っている。

結論: >>414-415 は流れを読まずに反応したヴァカ。
417名無しさん@お腹いっぱい。:2005/09/10(土) 11:33:14
396はそんなに構って欲しいのか。
418名無しさん@お腹いっぱい。:2005/09/10(土) 11:54:05
puts("y");
より
putchar('y');
putchar('\n');
のほうが早いんだな
yesのソースはputs()しか使ってないけど
419名無しさん@お腹いっぱい。:2005/09/10(土) 12:25:35
シェルスクリプトを書くとき、emacsは何モードにすればいいのでしょうか?
420名無しさん@お腹いっぱい。:2005/09/10(土) 12:27:58
男は黙ってcatとedで。
421名無しさん@お腹いっぱい。:2005/09/10(土) 12:34:42
>>419
fundamental-mode
422名無しさん@お腹いっぱい。:2005/09/10(土) 12:45:10
ふつーに shell-script-mode があるでしょ。
わしゃ vi を使うけど。
423名無しさん@お腹いっぱい。:2005/09/10(土) 12:52:44
interpreter-mode-alist
424名無しさん@お腹いっぱい。:2005/09/10(土) 13:18:28
>>412
yes "" | cat -n | head -100000
よりも、
printf %100000s "" | tr " " "\n" | cat -n
の方が速い。
意外だ。

seq 1 100000
よりも、
printf %100000s "" | tr " " "\n" | cat -n
の方が速い。
さらに意外だ。

ということで、printf %100000s "" | tr " " "\n" | cat -n 推奨。
425412:2005/09/10(土) 14:20:11
>>424
nice hack!!

$ time sh -c 'for i in `printf %100000s ""|tr " " "\n"|cat -n|head -100000`;do echo $i;done>/dev/null'

real 0m8.357s
user 0m7.605s
sys 0m0.856s

printf は posix 標準に入っているけど、seq は入っていないのでそういった意味でも printf のほうが良いですね。
426名無しさん@お腹いっぱい。:2005/09/10(土) 14:24:47
>>425
最後のheadは余計なんじゃないのか
427412:2005/09/10(土) 14:32:41
>>426
確かにそうでした、消し忘れ(^^;
あってもなくても大差はないですけどね(^^;

$ time sh -c 'for i in `printf %100000s ""|tr " " "\n"|cat -n`;do echo $i;done>/dev/null'

real 0m8.200s
user 0m7.543s
sys 0m0.730s
428名無しさん@お腹いっぱい。:2005/09/10(土) 14:42:26
ベンチマークはもういいよ。シェルスクリプトに動作速度なんて求めてない。
ウザい。
429名無しさん@お腹いっぱい。:2005/09/10(土) 16:06:12
↑ゲームに勝てないとこんなん出来なくても生きていけるとか言うタイプ。
430名無しさん@お腹いっぱい。:2005/09/10(土) 16:22:32
vimじゃなくてvi?
431名無しさん@お腹いっぱい。:2005/09/10(土) 16:23:16
ごめ。430は>>422へのレス
432名無しさん@そうだ選挙に行こう:2005/09/10(土) 17:11:18
入力ファイルから1行ずつ読み込んで

ある文字列1が含まれる行が来るまでまでの行は読み捨てて
その文字列1が来たらある文字列2が含まれる行が来るまで出力
文字列2が含まれる行が来たら処理終り

というスクリプトはどう書いたらいいのでしょうか?
Cで書いたらこんな感じです

while ((fgets (buf, SIZE, stdin)) && !strstr (buf, AAA));
if (!feof (stdin))
do
fputs (buf, stdout);
while ((fgets (buf, SIZE, stdin)) && !strstr (buf, BBB));
433名無しさん@お腹いっぱい。:2005/09/10(土) 18:01:45
>>432
sed -n -e 1,/文字列1/b -e /文字列2/q -e p
434名無しさん@お腹いっぱい。:2005/09/10(土) 18:05:20
>>432
あ、文字列1,2自体も出力に含まれてしまっていいならもっと簡単。
sed -n -e /文字列1/,/文字列2/p
435名無しさん@そうだ選挙に行こう:2005/09/10(土) 18:06:39
>>434ぐらいなら良く使うが
>>433ぐらいになると思いつかない俺はヘタレだ……
436名無しさん@お腹いっぱい。:2005/09/10(土) 18:09:35
>>432

echo \
'while ((fgets (buf, SIZE, stdin)) && !strstr (buf, AAA));
if (!feof (stdin)) do fputs (buf, stdout);
while ((fgets (buf, SIZE, stdin)) && !strstr (buf, BBB));
' | gcc -xc - ; ./a.out; rm a.out
437名無しさん@そうだ選挙に行こう:2005/09/10(土) 18:13:49
>>433
すごい、できました。ありがとうございます。
文字列1の行が表示されませんが、そこはいらなかったのでこれで大丈夫です。

でも暗号にしか見えない。
やっぱり一回勉強しないとだめですね。
438名無しさん@そうだ選挙に行こう:2005/09/10(土) 20:42:08
俺の場合、まずawkで考えちゃうなぁ。
awk '/文字列1/{f=1;next} /文字列2/{f=0} /.*/{if(f==1){print}}' Input-file
sedの方が確かにシンプルだな。
439名無しさん@そうだ選挙に行こう:2005/09/10(土) 20:53:54
>424
俺的には
for i in `yes "".....`; do ... doneのほうが
yes ""...| (while read i; do ... done)より速かったのが
なんか悔しい。
440422:2005/09/10(土) 22:49:32
>>430
たいていは /usr/bin/vi で十分。
別途インストールすることもあるが、jvim3 であって、vim6 はいらん。
441名無しさん@そうだ選挙に行こう:2005/09/10(土) 22:55:32
ふつーnvi(+m17n)じゃないのかと。
vim系はオリジナルviと非互換なところが馴染めない。
442名無しさん@そうだ選挙に行こう:2005/09/10(土) 23:02:53
vi の話題は vi スレでどうぞ
443名無しさん@そうだ選挙に行こう:2005/09/10(土) 23:36:38
nvi が純vi志向かというと、
変な拡張してたりしてそうでもないよね。
444名無しさん@そうだ選挙に行こう:2005/09/11(日) 00:00:31
でもvimよりはマシ。
445名無しさん@そうだ選挙に行こう:2005/09/11(日) 00:22:05
入力モードでカーソル移動できるってトンデモだけど
モード切替の必要性が減るので
日本語入力するときは正直便利だと思った
で、それ使うと、nviだと行頭あたりでするっと編集モードに戻っちゃうことがある
のがヤだ

まあviで日本語入力なんてそもそも外道、てことなのかな
446名無しさん@そうだ選挙に行こう:2005/09/11(日) 00:33:47
windows 版の gvim だと IME オンのまま
ESC して普通に hjkl で移動できるよ。
447名無しさん@そうだ選挙に行こう:2005/09/11(日) 00:37:42
>>446
そうなんだ、ならgvimにしようかなあ
ただのvimをつかってたわ
448名無しさん@そうだ選挙に行こう:2005/09/11(日) 00:56:33
>>412
time sh -c 'for ((i=0;i<100000;i++)); do echo $i; done>/dev/null'
449not 412:2005/09/11(日) 01:00:09
>>448
Syntax error: Bad for loop variable
450412:2005/09/11(日) 01:38:12
>>448
bash なら動くけど sh では動かないね。

$ time bash -c 'for ((i=0;i<100000;i++)); do echo $i; done>/dev/null'

real 0m12.763s
user 0m12.171s
sys 0m0.609s
451名無しさん@そうだ選挙に行こう:2005/09/11(日) 02:22:48
>>450
>>448
bash独自の文法だね。
分かりやすいけど >>427 より遅いのか。
勉強になるなぁ。
452名無しさん@そうだ選挙に行こう:2005/09/11(日) 05:49:27
いや遅い遅くないは実装にもよるので…君 何年生?
453名無しさん@そうだ選挙に行こう:2005/09/11(日) 14:49:03
>>452
何の実装?
中学生にも分かるように教えて。
454名無しさん@そうだ選挙に行こう:2005/09/11(日) 15:13:40
>>452
実装も含めて実際に速いかどうかの話をしてるんだろ。
「実装にもよるので」と言ったところで何の解決にもならない。

たしかに、bash: for ((;;)) という専用の文法がわざわざあるのに、
printf | tr | cat ←オプション省略 方式より遅いのは意外。
455名無しさん@そうだ選挙に行こう:2005/09/11(日) 15:46:52
bashのfor (())が遅いって?
ああ、そうだなfor (())も遅いな……
             ~~~
bash -c 'for ((i=0;i<100000;i++)); do echo $i; done>/dev/null'
  3.37s user 0.31s system 96% cpu 3.825 total

bash -c 'for i in `printf %100000s ""|tr " " "\n"|cat -n`;do echo $i;done' >
  2.65s user 0.20s system 100% cpu 2.843 total

/bin/sh -c 'for i in `printf %100000s ""|tr " " "\n"|cat -n`;do echo $i;done'
  0.69s user 0.15s system 101% cpu 0.823 total
456名無しさん@そうだ選挙に行こう:2005/09/11(日) 15:46:56
>>454
100000回ループ一点だけで結論付は早すぎる。forのレイテンシーが大きいだけかも。
457名無しさん@そうだ選挙に行こう:2005/09/11(日) 15:52:22
forの「レイテンシ」が遅いから、実際に遅いんだろ?
ていうか、ここで「レイテンシ」って用語が正しいか知らないが。
458名無しさん@そうだ選挙に行こう:2005/09/11(日) 16:25:08
ジェット戦闘機とF1の競争かもね。
459名無しさん@そうだ選挙に行こう:2005/09/11(日) 16:37:39
内部でやってるのに外部コマンドとパイプに負けてるようじゃやくたいなしってこった
460名無しさん@そうだ選挙に行こう:2005/09/11(日) 17:40:38
>>455
ウホっ bash遅すぎ
461名無しさん@そうだ選挙に行こう:2005/09/11(日) 17:43:47
bashのコンセプトはその「やくたいなし」ってことだな!
存在するだけで迷惑だし、「やくたいなし」そのものだ。
462名無しさん@そうだ選挙に行こう:2005/09/11(日) 17:49:50
bashのforは汎用のforだから
foreach的な単純ループと比べたらそりゃ分が悪いっしょい
それより、10万も数字出力したら500kbくらいメモリ食うけど
そのへん気にする人は…いないか。
463名無しさん@そうだ選挙に行こう:2005/09/11(日) 17:53:36
Linuxだとこんなにデカくて重くて遅いbashが/bin/shなんだろ?
正気の沙汰とは思えんな
464名無しさん@そうだ選挙に行こう:2005/09/11(日) 19:28:34
パイプはアスキーデータの流れだから巨大データでパンクする。
465名無しさん@そうだ選挙に行こう:2005/09/11(日) 20:03:32
>>462
メモリ使用量を少なくしたいなら
while と expr を使った方がいいってことになるのかな?
466名無しさん@そうだ選挙に行こう:2005/09/11(日) 20:15:53
readで受ければいいじゃん。
467名無しさん@そうだ選挙に行こう:2005/09/11(日) 21:01:05
>>464
gzip -c
468名無しさん@そうだ選挙に行こう:2005/09/11(日) 21:24:54
>>466
それはなんかunixっぽいな。

1万も10万もループして実際に何かを処理するなら
どの方法も大した違いはないと思うんだけど、
それ以前に用途が思い付かない。
469名無しさん@そうだ選挙に行こう:2005/09/11(日) 21:27:07
>462
bashはforeach的なループの時も遅いんだわさ。もうね。

>462、>465-466
やくたいなしのbashはしらねーけど、普通の/bin/shは`....`の時も
パイプで受けてるのでパイプの実装依存かな。readにしたから
メモリ消費がおとなしくなるってのはないと思われ。

試しに実験。メモリ量はvszとrssね。`...`を使うと、
10万回で208 840で0.71s user 0.18s system 103% cpu 0.860 total
100万回で4036 4692で7.15s user 1.46s system 100% cpu 8.596 total
pipeで渡してwhile readを使うと
10万回で144 776で0.97s user 0.78s system 101% cpu 1.723 total
100万回で144 776で10.60s user 6.34s system 100% cpu 16.941 total
だめじゃんback-quote!!!
470名無しさん@そうだ選挙に行こう:2005/09/11(日) 22:03:19
そんな大量の処理をシェルにはやらせないから全く無問題。
471名無しさん@そうだ選挙に行こう:2005/09/11(日) 22:05:42
速度重視 for in
メモリ重視 while read
ってことですな。

それだと特別な場合を除いて for in になりますなあ。
472名無しさん@そうだ選挙に行こう:2005/09/11(日) 23:14:03
俺はwhile read。

そもそも速度いらんからshで書くわけだし、
書いて残しとくと誰かが大量の処理を通さないとも限らないしね。

昨日まではこのスレ見てこれからはfor inかなとか呟いてたのは秘密だw
473名無しさん@お腹いっぱい。:2005/09/12(月) 00:10:10
そんな処理の場合、実際に何十万回も回すループの「中身」に較べたら
ループそのものの所要時間なんて無視できる程度のものなんじゃないのかなあ。
空ループを回すスクリプト書くわけじゃないもの。
474名無しさん@お腹いっぱい。:2005/09/12(月) 00:32:40
>>473
メモリは足りなくならなければどんだけ使ったっていーの。200MB使おうが、300MB使おうが1GB余っていれば全然問題なし。
それに比べて、たとえループの処理時間が全体の例えば1%、10秒だったとしても10秒得をするならそっちを選ぶよ。
475名無しさん@お腹いっぱい。:2005/09/12(月) 00:44:25
>>474
占有して使っていいWSならそうだけど…
476名無しさん@お腹いっぱい。:2005/09/12(月) 01:48:50
富豪的プログラミング思想の終焉
477名無しさん@お腹いっぱい。:2005/09/12(月) 03:15:29
なんにせよ、for と while を使い分ける時の
指標がひとつできた事はめでたい。
478名無しさん@お腹いっぱい。:2005/09/12(月) 10:02:58
文字列を末尾から切り取るときどうしてる?
479名無しさん@お腹いっぱい。:2005/09/12(月) 10:22:07
>>478
expr abcde : '.*\(...\)$'
480名無しさん@お腹いっぱい。:2005/09/12(月) 14:47:15
>>478
aa=abcde; echo ${aa:$((-3))};
481名無しさん@お腹いっぱい。:2005/09/12(月) 15:02:45
>>480
Syntax error: Bad substitution

bashうざい。
482名無しさん@お腹いっぱい。:2005/09/12(月) 18:36:51
${parameter%word} みたいなパラメータ置換だの
$(cmd) みたいなコマンド置換だの
$((x+1)) みたいな算術展開だのって全部 bourne shell 的には NG なんだっけ

邪悪度ってどれぐらい?
算術展開は bash 独自仕様ではないと思うんだが
posix 準拠 shell でも実装度はまちまち、と思ったほうがいいの?
483名無しさん@お腹いっぱい。:2005/09/12(月) 19:16:46
>>482
bash独自→邪悪度2
*BSDで動くがSolarisで動かない→邪悪度1
Solarisで動く→邪悪度0

邪悪度2:
${parameter:offset}
${parameter//hoge/hage}
ブレース展開
for((;;))
$[2+3]

邪悪度1:
$(cmd)
export NAME=val
${parameter%word}
${parameter#word}
チルダー展開
算術式展開

邪悪度0:
`cmd`
export NAME=val; export NAME
${parameter:-word}
${parameter:+word}


など。
484名無しさん@お腹いっぱい。:2005/09/12(月) 19:44:39
>>483
トンクス。
*BSDのashっていつのまにか算術式展開できるようになってたんだ……
俺のFreeBSD 4.7 RELEASEの/bin/shでは出来ないっぽ。
485名無しさん@お腹いっぱい。:2005/09/12(月) 20:17:35
>>484
算術式展開できないか?

$ echo $((x+2))
はダメでも、
$ echo $(($x+2))
ならできるんじゃないか?
486名無しさん@お腹いっぱい。:2005/09/12(月) 20:19:27
>>485
その通りですた。
487名無しさん@お腹いっぱい。:2005/09/12(月) 20:21:16
てことは、左辺値を要求されるような式(インクリメントとか)は
ヤバいということですね
488名無しさん@お腹いっぱい。:2005/09/12(月) 23:44:01
Solarisならkshで書くのでは?
489名無しさん@お腹いっぱい。:2005/09/13(火) 07:05:55
>>488
流れ嫁。Solarisの/bin/shを邪悪度判定の基準にしてるんだろ。
ksh必須(ksh依存)の書き方は、>>483 の定義では邪悪度1ということになる。
490名無しさん@お腹いっぱい。:2005/09/14(水) 02:49:24
>>483 は太陽の黒点にでもなって,二度と出てこなければ良いのに
491名無しさん@お腹いっぱい。:2005/09/14(水) 10:48:23
まあ、議論の前提としてどのシェルの話題かを一言入れてからにすれば
いいんじゃねーの?

K&Rあたりがそういうことにこだわってるんならいざ知らず。
shあたりで邪悪度かよー。ジジーぅぜーよ。

このスレはヒストリーチャンネルに併合されそう...





492名無しさん@お腹いっぱい。:2005/09/14(水) 12:19:31
>>491
>>1
・特記なき場合はbourne shがデフォルトです。
493名無しさん@お腹いっぱい。:2005/09/14(水) 16:42:38
$ uname -sir
SunOS 5.8 SUNW,UltraAX-i2
bash-2.03$ echo $SHELL
/usr/bin/bash
$

あはは、逝ってきます。
494名無しさん@お腹いっぱい。:2005/09/14(水) 17:14:04
bourne sh
ってことは、せいぜい、V7までのもののことだな。
Sunのものですら、なしってことだ。
495ヽ(´ー`)ノ ◆.ogCuANUcE :2005/09/14(水) 17:58:42
$ uname -sir
SunOS 5.7 SUNW,Ultra-4
$ echo $SHELL
/usr/bin/bash
$

(´・ω・`)
496名無しさん@お腹いっぱい。:2005/09/14(水) 19:14:58
>>494
今現在はどうだかしらないが
SunがSteve Bourneの書いたコード(あのトンチキなマクロをつかったやつだ)を
shとして保守しつづけていたのは確かだよ
497名無しさん@お腹いっぱい。:2005/09/14(水) 19:15:45
私は大学中の私の課金にloginでした。
そのとき私は私のシェルkshを見つけました。
どのように私はkshからbashへ変わりますか?
498名無しさん@お腹いっぱい。:2005/09/14(水) 19:33:16
>>497
国に帰りなさい。
499名無しさん@お腹いっぱい。:2005/09/14(水) 21:43:39
大量のファイルを削除したいのですが、(SPAMメール)
rmで削除すると、数が多すぎるのかタイムアウトしていまいます。
受信しようとしても、タイムアウトしてしまい、メールが使えません。
鯖はFreeBSDです。

これを何とか処理するスクリプトは作れませんでしょうか?
500名無しさん@お腹いっぱい。:2005/09/14(水) 21:46:08
rm にタイムアウトがあるとは初耳だ。
とりあえず xargs で。
501名無しさん@お腹いっぱい。:2005/09/14(水) 22:09:47
ちょwwwおまえっwww
502名無しさん@お腹いっぱい。:2005/09/14(水) 22:12:37
>>499
つ[IMAP]
503名無しさん@お腹いっぱい。:2005/09/14(水) 22:36:41
bashです。
スクリプトhoge.shに
source /sage/ru/age.sh
と記述して,
source hoge.shと実行した場合,呼び出されたage.shのスクリプトの中で,
どのようなPATHで呼び出されたか知る方法ってあるのでしょうか?
ここでは/sage/ru/age.shを取得したい訳ですが。

historyだと最初に呼び出したsource hoge.shしか分からないようだし,
何かいい方法がありましたら教えてください。お願いします。
504名無しさん@お腹いっぱい。:2005/09/14(水) 22:48:44
>>503
ヒント: $0
505503:2005/09/14(水) 23:21:57
>>504
sourceで呼び出していると$0が-bashとかになってしまいます。
sourceじゃなくて直接呼び出せば$0でOKでした。
source呼び出しだと無理でしょうか?
506名無しさん@お腹いっぱい。:2005/09/15(木) 07:24:16
source って別スクリプトを呼ぶわけじゃないと思うのだが・・・読むだけ
507名無しさん@お腹いっぱい。:2005/09/15(木) 07:29:32
alias source='sourcearg0=$p \source $p'とか?
508名無しさん@お腹いっぱい。:2005/09/15(木) 07:30:14
あ、$pじゃなくて、なんか適当にねw
509名無しさん@お腹いっぱい。:2005/09/15(木) 10:47:54
sourceはbash依存の邪悪度2。
. 使え。
510名無しさん@お腹いっぱい。:2005/09/15(木) 12:09:29
意味不明。邪悪度2なのに使えって???
511名無しさん@お腹いっぱい。:2005/09/15(木) 12:13:57
. <-これみえる?
512名無しさん@お腹いっぱい。:2005/09/15(木) 12:38:35
プロポーショナルなフォントだとマヂで見えんかもしれんなw
513503:2005/09/15(木) 16:59:49
レスしてくだっさた皆様ありがとうございます。
>>507
aliasはちょっと使いたくないです。我侭ですいません。
>>509
.でやってみたんですが結果が変わりません。bashだからでしょうか?
514名無しさん@お腹いっぱい。:2005/09/15(木) 17:18:02
>>503
sourceされるスクリプトにPATHが通っているものとして、
age.shの中で、

type -P age.sh
とやれば、
/sage/ru/age.sh
と標準出力に出る。

取り込みたければ
fullpath=`type -P age.sh`
とすれば良い。

ただし、typeの-Pオプションは邪悪度2だと思ふ。
515503:2005/09/15(木) 20:01:14
>>514
レスありがとうございます。
PATHが通っていればtypeでOKですね。

ところでPATHが通っていない場合はどうでしょうか?
自分的にはhoge.shでage.shを呼び出す前に
history -sして履歴に追加しておけばいいかなと思ったのですが。
516名無しさん@お腹いっぱい。:2005/09/15(木) 20:22:44
source /sage/ru/age.sh /sage/ru/age.sh
で呼び出せ。
すると、age.shの中で$1で参照できる。

ただし、bash限定の方法だが。
517名無しさん@お腹いっぱい。:2005/09/15(木) 21:22:06
呼び出し元をいじれるんなら、適当に変数にぶちこんどけばいいじゃん
518名無しさん@お腹いっぱい。:2005/09/15(木) 22:04:39
>>516
うぉー、確かに、この方法で行けますね。目から鱗です。サンクスコ。
519503:2005/09/15(木) 22:42:04
>>516
なるほど。こういう手もありましたか。ありがとうございます。

>>517
まぁそうなんですが。なるだけ変数使わない方がスマートかなと思いまして。

ところで
>>509で指摘されていることなのですが,
bashのsourceのどういったところがいけないのでしょうか?
シェル変数をシェルスクリプト親子で共有できて便利だなと思っているのですが。




520名無しさん@お腹いっぱい。:2005/09/15(木) 22:49:45
bash$ /bin/sh
$ source hoge.sh
source: not found
$
521名無しさん@お腹いっぱい。:2005/09/15(木) 23:05:15
>>516 でよしとする邪悪野郎にはどうでもいいってことだ
522名無しさん@お腹いっぱい。:2005/09/15(木) 23:06:42
>519
ちなみに509がsourceが邪悪っていったのは
sourceが/bin/shには存在しないってだけの話。

でも、君、邪悪杉www

>シェル変数をシェルスクリプト親子で共有できて便利

それは実際には親子じゃないから。

シェルスクリプト呼び出しだと、シェルが子プロセスを作り、
シェルを読み込み最初から実行しその上でスクリプトを実行する

sourceや . だと使ってるシェルがスクリプトを読んで実行してる。
スクリプトが死ぬと、使ってるシェルも死ぬ。

また、シェル変数を共有できて便利だなってのは幻想。実際は逆。
共有していると副作用が邪魔で困るというのが真実。

例えば、MS-DOSで呼び出されたスクリプトがcdすると
呼び出しがシェルの環境までcdされてしまうなんてのが
いい実例。

sourceを使いたいから使うってのならしょうがないけど、
一度本当にそれが必要か、良い実装か、考えたほうがいい。
523503:2005/09/15(木) 23:08:59
>>520
これ以外でもなにかありますでしょうか?
524503:2005/09/15(木) 23:16:50
>>522
レスありがとうございます。
行き違いになってしまった。

そうですね。勘違いしていました。
親子とはよべないですね。

確かににシェル変数が一緒くたになってしまうと
今度は管理に手間がかかるだけですね。

525名無しさん@お腹いっぱい。:2005/09/15(木) 23:29:36
まあコンフィギュレーション用のスクリプトみたいのを
.で読み込んで設定取り込んだりみたいな使い方ならありふれてると思うが
526503:2005/09/16(金) 00:19:39
なるほど。

ところで
shでbashのsourceのようなことをしたい場合は
どのようにするのでしょうか?
基本的すぎるかもしれませんが、教えてください。

527503:2005/09/16(金) 00:20:24
あれなんか質問がおかしいな...
528503:2005/09/16(金) 00:25:47
単にそういうことが発生しないようにすればいいのかな。
529名無しさん@お腹いっぱい。:2005/09/16(金) 04:19:39
だから >>509 って言ってるやん
530名無しさん@お腹いっぱい。:2005/09/16(金) 08:19:54
なんだか典型的な「本当に自分がやりたいこと」が分かってない人だな
.やsourceとコマンド起動の区別がついてなさげ
531名無しさん@お腹いっぱい。:2005/09/16(金) 08:25:33
ところで
基本的すぎると思うのならマニュアル読め。
532名無しさん@お腹いっぱい。:2005/09/16(金) 09:06:48
man sh だと、(日本語でも)難しい書き方がされていてわかりません。
こういうの覚えるのって、サイトとかでできますか?
それとも本買う必要ありますか?
お勧めがあったら教えてください。
533名無しさん@お腹いっぱい。:2005/09/16(金) 09:10:33
テンプレくらい嫁
534名無しさん@お腹いっぱい。:2005/09/16(金) 09:35:27
テンプレのものしかありませんか?
これでもちょっと難しい感じなんですが・・
535名無しさん@お腹いっぱい。:2005/09/16(金) 09:51:54
man bash の source の近所に書いてあるだろ
536名無しさん@お腹いっぱい。:2005/09/16(金) 09:53:22
sourceだけじゃなくて、基本的に勉強したいんですが。
537名無しさん@お腹いっぱい。:2005/09/16(金) 09:57:44
自助努力のできない人は何やってもムダだと思うよ。
538名無しさん@お腹いっぱい。:2005/09/16(金) 10:41:50
>>537
おススメを知らないなら答えてくれなくていいです。
知っている方いませんか?
539名無しさん@お腹いっぱい。:2005/09/16(金) 10:45:39
俺は知っている。超知っている。だが教えてやらない。
540名無しさん@お腹いっぱい。:2005/09/16(金) 11:14:45
UPEちょーおすすめ。でももう売ってないから中古探せ
541名無しさん@お腹いっぱい。:2005/09/16(金) 11:48:09
FreeBSD 5.4R をインスコしたんですが、
この前話題になっていた printf だけでなく、
testコマンドまで外部化されているようです。

% /bin/sh
$ which test [
/usr/bin/test
/usr/bin/[

そんなはずはない、と、何度も再インストールしましたが、
状況は変わりません。
testを内部コマンド化するには、何か設定が必要なのでしょうか?
542名無しさん@お腹いっぱい。:2005/09/16(金) 11:52:37
which which してみろ
543名無しさん@お腹いっぱい。:2005/09/16(金) 12:01:10
>>541
ギャグだろ
544名無しさん@お腹いっぱい。:2005/09/16(金) 12:01:42
>>542
% which which
which: shell built-in command.

>>541 は曖昧な記憶で書いてしまいました。
/usr が余計でした。

$ which test [
/bin/test
/bin/[

です。
545名無しさん@お腹いっぱい。:2005/09/16(金) 12:12:53
>>541
type test
man which

>>544
> % which which
> which: shell built-in command.
% /bin/sh
$ type which
546名無しさん@お腹いっぱい。:2005/09/16(金) 13:55:05
test が外部にあるのは一向にかまわないんだが、
FreeBSD は cd やら alias も /usr/bin にあるんだよな。

% pwd
/home/hoge
% /usr/bin/cd /
% pwd
/home/hoge

意味ねーよ。何のためにあるんだかよくわからん。

中身は↓

#!/bin/sh
# $FreeBSD: src/usr.bin/alias/generic.sh,v 1.1 2002/07/16 22:16:03 wollman Exp $
# This file is in the public domain.
${0##*/} ${1+"$@"}
547名無しさん@お腹いっぱい。:2005/09/16(金) 14:09:37
>>546
> FreeBSD は cd やら alias も /usr/bin にあるんだよな。
Solaris もそだよ.
548名無しさん@お腹いっぱい。:2005/09/17(土) 00:57:20
sh の内部コマンドは一通り /usr/bin にあるようだね。
(hard link でどれも同じファイルになってる)

549名無しさん@お腹いっぱい。:2005/09/17(土) 10:19:15
本当に何のためなの。

pwdやcdもない、あるいは悪意で改竄された環境でも
それらのコマンドが使えるように、とか?
550名無しさん@お腹いっぱい。:2005/09/17(土) 11:32:57
俺のFreeBSDには入ってないな。/usr/bin/cdって最近の話?

>>549
そんなわけがあるか

外部コマンドとしてcdを用意しても全く機能しないんだし
cdが改竄されてる=shが改竄されてるのと同義なんだから
コマンド用意しても無駄
551名無しさん@お腹いっぱい。:2005/09/17(土) 12:14:00
manにはこう書いてある(Solaris)

/usr/bin/cd ユーティリティは、cd ユーティリティ自身だけの 現
在のディレクトリを変更します。これは、後述するシェル組み込み
の cd とは対照的です。/usr/bin/cd はプロセスの呼び出しには影
響しませんが、あるディレクトリを現在のディレクトリとして設定
できるかどうかを決定するのに使用できます。

test -d dirとどう違うのか気になるなあ。
chroot/zone/jail環境のため? うーん…
552名無しさん@お腹いっぱい。:2005/09/17(土) 13:55:31
>>551
パーミッションで禁止されたディレクトリかも知れないから、
test -d dir
というより、
test -d dir -a -x dir
にほぼ相当するかな。

でも、わざわざ /usr/bin/cd などとフルパスで書いて呼び出すわけないし、
どうしても cd でチェックだけしたい場合は、
(cd dir) 2> /dev/null
echo $?
でいいと思う。manの記述はこじつけっぽい。

で、cdはいいとして、/usr/bin/aliasは?
ほとんど、aliasの文法チェックくらいにしか使えん。
これも、(alias hoge) 2> /dev/null と書けるし、存在意義不明。
553名無しさん@お腹いっぱい。:2005/09/17(土) 14:15:14
/usr/bin/cdでぐぐったら一発で分かった。
「UNIX 98 standards comformance」のためだそうだ。意味ねぇーw
/usr/bin/aliasもそれ関係で入っているらしい。
554名無しさん@お腹いっぱい。:2005/09/19(月) 09:18:59
a 10
a 20
a 30
b 100
b 120
c 300
のようなファイルを集計して
a 60
b 220
c 300
のように出力してくれるコマンドありますか?

とりあえずRubyで一行書いて済ませてしまいましたが。
555名無しさん@お腹いっぱい。:2005/09/19(月) 09:24:39
rubyでええやん。
556名無しさん@お腹いっぱい。:2005/09/19(月) 11:22:53
>>554
シェルスクリプトでできる。試しに書いてみた。
evalとか駆使して変数処理する。
expr以外、外部コマンドは使わない。(シェル算術式が使えるなら完全内部OK)
いざ書けてみると結構良さそうなスクリプトになったので、
ここで公開するのが惜しくなった。
俺自身、何かのネタで使うので、、、
まあ、evalがヒントだから自分で考えてみて。
557名無しさん@お腹いっぱい。:2005/09/19(月) 11:37:38
>>554
初心者のおれが作るとこうしか思いつかんけど、2,3行で済ませられるの?

#!/bin/sh

while read Char Num
do
if [ "$Char" = "a" ] ; then
a=`expr $a + $Num`
elif [ "$Char" = "b" ] ; then
b=`expr $b + $Num`
elif [ "$Char" = "c" ] ; then
c=`expr $c + $Num`
fi
done < data.dat

echo "a $a"
echo "b $b"
echo "c $c"
558名無しさん@お腹いっぱい。:2005/09/19(月) 11:40:10
苦労して、ェルで作っても、使えないものの典型だな。
awkなどのスクリプト言語の方が手軽且つ応用も利くし、パフォーマンスもいい。
559名無しさん@お腹いっぱい。:2005/09/19(月) 12:08:20
>>557
それ、汎用性が全然ないぞ。
560名無しさん@お腹いっぱい。:2005/09/19(月) 12:08:40
誰でも思いつくけど、eval使うならこんな感じ
#!/bin/sh
while read x y
do
  eval "$x=\`expr 0\$$x + $y\`"
done < data.txt

echo "a $a"
echo "b $b"
echo "c $c"
561名無しさん@お腹いっぱい。:2005/09/19(月) 12:11:26
強引な手でやってみた。多分もっとマシに書けるだろう。
が、なんにせよ全然お勧めはしない。

while read key val
do
    eval "${key}_val=`expr \${key_val:-0} + $val`"
    keys="$keys $key"
done

for i in `echo $keys|tr ' ' '\n' | sort -u`
do
    eval "echo ${i} \$${i}_val"
done

awkでやれば無論一行で済む話。

$ awk '{ tab[$1] += $2; } END { for (s in tab) { print s, tab[s] } }'
562名無しさん@お腹いっぱい。:2005/09/19(月) 14:47:24
>>561
そのシェスルクリプトの方、動かないよ。
実際に試してないでしょ。

3行目、
eval "${key}_val=`eval expr \\${${key}_val:-0} + $val`"
じゃないか?
563名無しさん@お腹いっぱい。:2005/09/20(火) 01:11:00
shes llcript
564名無しさん@お腹いっぱい。:2005/09/20(火) 17:35:04
cat file.dat |sed -e "s/\(.*\) \(.*\)/let \1=\1+\2; echo \1 $\1/;" |bash
565名無しさん@お腹いっぱい。:2005/09/20(火) 19:32:14
>>564
ばかもん、bashに食わせてどうする。
しかも、途中の合計まで表示されるし、
あと、最初のcatは無駄だし。
566名無しさん@お腹いっぱい。:2005/09/20(火) 20:46:21
もちろん564はコマンドラインでも
cat foobar.txt | less
567名無しさん@お腹いっぱい。:2005/09/20(火) 21:06:14
>>564
改良版
cat file.dat |sed -e 's/\([^ ]*\)[ ]*\([^ ]*\)/let \1=\1+\2; var=\${var\/\/ \1\/}\" \"\1;/; $ a \
for aa in \$var; do echo \$aa \$((aa)); done;' |bash
568名無しさん@お腹いっぱい。:2005/09/20(火) 22:05:42
>>567
file.datの中に、

a 10 rm -rf /

という行が入ってたら面白いな。
あと、改良版でもcatは外さないのか?
569名無しさん@お腹いっぱい。:2005/09/20(火) 22:48:38
遅ればせながら
>>562 正直、スマソかった
570名無しさん@お腹いっぱい。:2005/09/20(火) 23:09:46
>>568
最初にデータファイルの中身を見てスクリプト書くから最初はcatになる。

var=\${var\/\/ \1\/}\" \"\1; は我ながら気に入った。
let "\1 = \1 + \2"; が良かったかも。

perl厨は驚いただろう。
571名無しさん@お腹いっぱい。:2005/09/20(火) 23:26:22
自画自賛キター

つか俺が上司ならまず間違いなく >>567はポイ。
かわりにawkのワンライナーを使う。
572名無しさん@お腹いっぱい。:2005/09/21(水) 02:50:48
まずawkのワンライナーを晒してみろや
573名無しさん@お腹いっぱい。:2005/09/21(水) 04:12:45
$ awk '{ tab[$1] += $2; } END { for (s in tab) { print s, tab[s] } }'
574名無しさん@お腹いっぱい。:2005/09/21(水) 07:21:32
>>570
>最初にデータファイルの中身を見てスクリプト書くから最初はcatになる。
最初にデータファイルの中身を見ることと、
パイプラインの先頭に無駄なcatを配置することは
無関係なわけだが?

で、データファイルに rm -rf / が仕込まれていた場合の問題は
どう対処するの?

いずれにしても、パイプでシェルに食わせる書き方は危険だし邪道。
しかも、bashに食わせてるから別の意味でも邪道。
${var//key/} もbash依存だし。
575名無しさん@お腹いっぱい。:2005/09/21(水) 07:24:25
>>570
let "\1 = \1 + \2";
にしても、rm -rf / 問題は防げないよ。やってみればわかる。
576名無しさん@お腹いっぱい。:2005/09/21(水) 08:14:09
もともと整理されたデータファイルを作った時点で合計なんか計算済み。
577名無しさん@お腹いっぱい。:2005/09/21(水) 08:19:36
>perl厨は驚いただろう。

570はfind2perlとか知らないperl厨でつか?

正規表現を多用したループ回数の多いループみたいに
実行時の最適化のオーバーヘッドが気にならない場合は、
スクリプトを動的に生成して実行時コンパイルで最適化を
かけるのがperlの基本。
578名無しさん@お腹いっぱい。:2005/09/21(水) 08:24:24
↑スレ違いなPerl厨
579名無しさん@お腹いっぱい。:2005/09/21(水) 08:29:33
>>571
おまいは部下を潰すタイプだから上司にならない方がよい。
580名無しさん@お腹いっぱい。:2005/09/21(水) 08:34:09
>>579
>>571 は部下を潰すかもしれないが、>>567 のようなスクリプトを書く
奴は会社を潰す。
581名無しさん@お腹いっぱい。:2005/09/21(水) 08:37:33
たしかに、>>567 のスクリプトでは rm -rf / が実行できてしまうから、
会社を潰しますな。
WebのCGIの中で使ってたら鯖がやられるし。
582名無しさん@お腹いっぱい。:2005/09/21(水) 08:45:11
find2perlなんてのがあるんだ


うちのHPUX11には無かった orz
583名無しさん@お腹いっぱい。:2005/09/23(金) 04:11:18
aaa
bbb
ccc
と書かれたfileがあって、$ cat file | command bbb とすると
bbb
aaa
ccc
$ cat file | command ccc とすると
ccc
aaa
bbb
というように指定された文字列が上に来るようにしたいのですが、可能でしょうか?
584名無しさん@お腹いっぱい。:2005/09/23(金) 04:42:57
grep bbb file > hoge
grep -v bbb file >> hoge
585名無しさん@お腹いっぱい。:2005/09/23(金) 09:59:50
>>584
それだと、入力fileを「標準入力から」読めません。
(2回オープンが必要になります)
標準入力から読めるようにできませんか?
586名無しさん@お腹いっぱい。:2005/09/23(金) 10:39:32
teeと組み合わせて使うとかすれば?
なぜ不都合があるかまでわかるならそれを解消する手段くらい講じられるだろ。

587名無しさん@お腹いっぱい。:2005/09/23(金) 11:24:32
>>586
teeでは無理だろ。
もしかして、「標準出力」と勘違いしてる?
588名無しさん@お腹いっぱい。:2005/09/23(金) 11:46:12
cat > /tmp/hoge.$$
grep bbb /tmp/hoge.$$ > hoge
grep -v bbb /tmp/hoge.$$ >> hoge
rm /tmp/hoge.$$
589名無しさん@お腹いっぱい。:2005/09/23(金) 11:51:12
>>588
だからぁ〜、
中間ファイル作っちゃダメ。
パイプだけでやる方法はないですか?
590名無しさん@お腹いっぱい。:2005/09/23(金) 12:00:23
新しい要求を持ち出しながら、だからもないものだ。

591名無しさん@お腹いっぱい。:2005/09/23(金) 12:02:32
まったくだ。seekablepipe でも入れときなされ。
592名無しさん@お腹いっぱい。:2005/09/23(金) 12:13:03
seekablepipeとか中間ファイルとか使わなくてもできるよ。

ほれ↓

#!/bin/sh

sed '
/bbb/{
s/^/1 /
b
}
s/^/2 /
' | sort | sed 's/^..//'
593名無しさん@お腹いっぱい。:2005/09/23(金) 22:19:03
583は仕様を理解してないだろ。

aaaなりbbbなりを最初に出力するには、それ以外の行を全て
バッファリングしなきゃいけないわけ。入力が500万行で各行平均
40byteあれば、それだけで190MB。おとなしく中間ファイルつくっと
けって。588の方法ならO(2n)で済む。

592なんかしたらO(n^2)くらいかかるぞ。とか思ってたら最近の
sortはquick sortじゃなくてradix sortなのね on NetBSD。それなら
もうちょっとオーダーへるかな。でも俺的にはそういうの考えたり
検証したりするの面倒だから、やっぱ中間ファイル作るのがお薦めかな。
594名無しさん@お腹いっぱい。:2005/09/23(金) 22:35:57
どんな仕様かは状況依存じゃないの。
シェルスクリプトで済ませられる処理なら、性能が必要とされていなかったり、
データ量が十分に少ないという条件かもしれない。
595名無しさん@お腹いっぱい。:2005/09/23(金) 23:26:21
それ以前に、583はスクリプティングについて理解してないだけだと思うよん。

588をstdinから読むスクリプトhoge.shにして sh hoge.sh file とすれば
中で中間ファイル作ろうがドワーフが金槌を振り回そうが知ったことではあるまい。
596名無しさん@お腹いっぱい。:2005/09/23(金) 23:40:09
>>583
書いている範囲の仕様なら中間ファイルもパイプも不要だ。
チェックしないなら if 文も要らんな。

if grep -q "$1" file
then echo -e "$1\n`grep -v $1 file`"
fi
597名無しさん@お腹いっぱい。:2005/09/24(土) 07:48:27
>>596
それだと、fileを標準入力から読めない。
>>584 と同じミスを犯している。
(標準入力から読まなくていいなら中間ファイルもパイプも要らないのは当たり前)

しかも、>>596 だと、「bbbを含む行全体(複数)」じゃなく、
「bbbだけ」が先頭に1回出力されるだけなので、
そもそも仕様を満たしていない。
(さらに、file中に\があるとecho -eで解釈されてしまって文字化けする)

出直してこい。
598名無しさん@お腹いっぱい。:2005/09/24(土) 09:33:20
>>597
勝手に仕様を変えるなよw

>>583 には
>aaa
>bbb
>ccc
>と書かれたfileがあって、$ cat file | command bbb とすると
しか書いてないぞ。

bbb が複数あるとか、bbbを含む行全体を先頭に出さなければならないとか書いていないぞ。

#!/bin/sh
echo "$1";
grep -v "^$1\$"
599名無しさん@お腹いっぱい。:2005/09/24(土) 09:34:50
うむ、素晴らしい。
600名無しさん@お腹いっぱい。:2005/09/24(土) 09:53:30
>>598
なんか、中国人に開発を任せたらこうなるという見本みたいだ。
601名無しさん@お腹いっぱい。:2005/09/24(土) 10:02:26
>>598
bbbが複数あるかどうかの件は100歩譲るとしても、

$ cat file | command bbb
とわざわざ書いてるんだから、
commandは標準入力から読まなければならないと解釈できるはずだ。

やっぱり出直してこい。
602名無しさん@お腹いっぱい。:2005/09/24(土) 10:15:01
>>601

>>508 は標準入力以外に対応していないように見えるが。
603名無しさん@お腹いっぱい。:2005/09/24(土) 10:32:33
>>602
>>508 って関係あるの?

>>598
bbbが含まれていなくてもbbbが出てしまいます。バグです。
604名無しさん@お腹いっぱい。:2005/09/24(土) 11:48:03
>>603
>>583 には
>aaa
>bbb
>ccc
>と書かれたfileがあって、$ cat file | command bbb とすると
しか書いてないぞ。
605名無しさん@お腹いっぱい。:2005/09/24(土) 12:01:08
>>604
だったら、

#!/bin/sh

case "$1" in
bbb)
echo 'bbb
aaa
ccc';;
ccc)
echo 'ccc
aaa
bbb';;
esac

でもいいわけじゃん。
606名無しさん@お腹いっぱい。:2005/09/24(土) 12:44:13
>>601
あ、そうか。
さすがに適当すぎた。

なら、こうか?

#!/bin/sh
while read a
do
if echo "$a" | grep -q "$1"
then b="$b$a"
else c="$c$a"
fi
done
if [ -n "$b" ]
then echo "$b$c"
else echo "$1 not found"
fi
607名無しさん@お腹いっぱい。:2005/09/24(土) 12:50:48
>>605
そんな長く書く必要ないっしょ。
608:2005/09/24(土) 13:44:25
みんなかっこよくってよ
私のためにもっといけてるの書いてくださいませ
609名無しさん@お腹いっぱい。:2005/09/24(土) 13:55:12
もっとツンツンしてください。
610名無しさん@お腹いっぱい。:2005/09/24(土) 14:21:04
配列のやりかたがよくわかんない
#!/bin/sh
line_num=0
while read line; do
  if [ "$line" = "$1" ]; then
    echo "$line"
    i=1
    printf "%${line_num}s" | tr " " "\n" | while read n; do
      eval 'echo "$line_'$i'"'
      i=$(($i + 1))
    done
    while read line; do
      if [ "$line" != "$1" ]; then   # 要求があいまい
        echo "$line"
      fi
    done
    exit 0
  else
    line_num=$(($line_num + 1))
    eval "line_$line_num=\"$line\""
  fi
done
exit 1
611名無しさん@お腹いっぱい。:2005/09/24(土) 14:26:03
あぁi=$(($i + 1))はいらんのか
- printf "%${line_num}s" | tr " " "\n" | while read n; do
+ printf "%${line_num}s" | tr " " "\n" | cat -n | while read i; do
612名無しさん@お腹いっぱい。:2005/09/24(土) 15:01:03
>>610
わざわざ配列使って複雑なだけで、
これなら >>606 の方がまし。
( >>606 の後半のチェックは要らないと思うが・・)
613名無しさん@お腹いっぱい。:2005/09/24(土) 15:12:16
ちょっと前のネタ、蒸し返すわけじゃないけど、
seqコマンドって、そのための専用コマンドなのに、
なんでこんなに遅いの?

time sh -c 'seq 1 100000' > /dev/null
と、
time sh -c 'printf %100000s | tr " " "\n" | cat -n' > /dev/null
とでは、
後者の方が10倍程度も速いんですが?
614名無しさん@お腹いっぱい。:2005/09/24(土) 15:23:46
環境は?
615名無しさん@お腹いっぱい。:2005/09/24(土) 22:05:57
うちじゃseqのほうが速かったな。cat -nの2/3くらいで終わった。
616名無しさん@お腹いっぱい。:2005/09/25(日) 00:03:21
我が家はseqそのものがなかった orz...
ちなみにSolaris10。SUSv3にも入ってない。
617名無しさん@お腹いっぱい。:2005/09/25(日) 00:17:09
うちにはjotくんが
618名無しさん@お腹いっぱい。:2005/09/25(日) 01:23:14
seqの出自ってどこよ?
619618:2005/09/25(日) 01:30:08
GNUのcoreutilsかな?
ttp://savannah.gnu.org/cgi-bin/viewcvs/coreutils/coreutils/src/seq.c?rev=1.88&content-type=text/vnd.viewcvs-markup

ソースを見るかぎり、遅くなる要因はなさそうなんだが。
620名無しさん@お腹いっぱい。:2005/09/25(日) 01:38:19
The seq command first appeared in Plan 9 from Bell Labs.
621名無しさん@お腹いっぱい。:2005/09/25(日) 05:41:19
コンパイラの最適化と,コードあるいはハードとのミスマッチとか...
622名無しさん@お腹いっぱい。:2005/09/25(日) 07:53:38
time yes y |head -10000000 >/dev/null
はかなり速いぞ。
623名無しさん@お腹いっぱい。:2005/09/25(日) 09:44:58
jotだと速いが、同じマシンにcoreutilsのseqを入れると
確かに10倍ほど遅いw
624名無しさん@お腹いっぱい。:2005/09/25(日) 10:20:53
for loop の 制御変数がdoubleなのが効いているのかなあ。
625名無しさん@お腹いっぱい。:2005/09/25(日) 13:19:04
>>622
だからそれだけじゃ連番生成できてないだろ
626名無しさん@お腹いっぱい。:2005/09/26(月) 07:41:14
time yes |head -10000 |cat -n >/dev/null
627名無しさん@お腹いっぱい。:2005/09/27(火) 02:36:55
seqの代わりに、下のコードを使っても、まだ 'printf %100000s | tr " " "\n" | cat -n' に勝てない。

#include <stdio.h>

int main(int argc, char **argv)
{ if (argc != 3) {
printf("usage: \n seq initial target [increment]\n");
exit (1);
}
int i, init, target;
init = atoi(argv[1]);
target = atoi(argv[2]) + 1;

if (init < 1 || target < 1 || target < init){
printf("ERROR: %d:%d:%d\n",init, target);
exit(1);
}

for (i = init; i < target; i++) {
printf("%d\n", i);
}
}
628名無しさん@お腹いっぱい。:2005/09/27(火) 02:53:21
だから環境は?
629名無しさん@お腹いっぱい。:2005/09/27(火) 06:43:55
>>63
いまさらですが、

echo " ^H"$message

でどう。
630名無しさん@お腹いっぱい。:2005/09/27(火) 08:33:32
>>627
\nごとにラインバッファが書き出されるのがもったいないので、
setvbufで_IOFBFにしたほうがよさそうに思います。
631ヽ(´ー`)ノ ◆.ogCuANUcE :2005/09/27(火) 08:39:00
Linux だけど。

bash$ uname -a
Linux hostname 2.6.8-2-686 #1 Thu May 19 17:53:30 JST 2005 i686 GNU/Linux
bash$ type printf
printf is a shell builtin
bash$ time sh -c 'printf %100000s | tr " " "\n" | cat -n' > /dev/null

real 0m0.012s
user 0m0.009s
sys 0m0.003s
bash$ which printf
/usr/bin/printf
bash$ time sh -c '/usr/bin/printf %100000s | tr " " "\n" | cat -n' > /dev/null

real 0m0.013s
user 0m0.007s
sys 0m0.005s
632ヽ(´ー`)ノ ◆.ogCuANUcE :2005/09/27(火) 08:40:16
bash$ cat seq.c
#include <stdio.h>

int main()
{
char buf[100000 * 8];

setvbuf(stdout, buf, _IOFBF, sizeof(buf) / sizeof(buf[0]));

for (int i = 1 ; i <= 100000 ; ++i) {
printf("%d\n", i);
}

fflush(stdout);

return 0;
}
bash$ gcc --version | head -1
gcc (GCC) 3.3.5 (Debian 1:3.3.5-13)
bash$ gcc -std=c99 -O3 seq.c -o seq
bash$ split seq
bash$ time sh -c ./seq > /dev/null

real 0m0.034s
user 0m0.030s
sys 0m0.002s
633ヽ(´ー`)ノ ◆.ogCuANUcE :2005/09/27(火) 08:42:42
ギャー、split してどうするよ(;´Д`)strip だ。

bash$ time sh -c ./seq > /dev/null

real 0m0.031s
user 0m0.031s
sys 0m0.001s

まぁそんなんでは変わらんわけで。
634名無しさん@お腹いっぱい。:2005/09/27(火) 08:50:42
trは内部操作をなるべく配列やリスト操作に留めてますね。
これじゃ、printfベースでじゃ勝負にならなさそうです。
635名無しさん@お腹いっぱい。:2005/09/27(火) 09:05:09
trは、溜め込んだあとまとめてバイナリでBUFSIZ単位でfwrite出力なんですねぇ。
636名無しさん@お腹いっぱい。:2005/09/27(火) 09:45:44
cat -n の static void next_line_num も、実に速そう。さすが、使い込まれてる道具ですね。
637名無しさん@お腹いっぱい。:2005/09/27(火) 09:53:13
$ time sh -c '/usr/bin/printf %100000s | tr " " "\n" | cat -n' > /dev/null
real 0m0.017s
user 0m0.016s
sys 0m0.004s

$ time dd if=/dev/zero bs=100000 count=1 2>/dev/null | tr '\0' '\n' | cat -n > /dev/null
real 0m0.013s
user 0m0.012s
sys 0m0.000s
638名無しさん@お腹いっぱい。:2005/09/27(火) 10:47:35
しかし、わざわざダミーのスペースをパイプに流してtrしてcat -nしていて
無駄が多そうなのに、直接数値を発生させているだけのseqより速いのが
感覚的に納得できん!
639名無しさん@お腹いっぱい。:2005/09/27(火) 12:47:33
そのtimeって何はかってることになるの?
640名無しさん@お腹いっぱい。:2005/09/27(火) 12:56:18
>>639
げげっ
641637:2005/09/27(火) 13:03:09
でもあらためて考えると、パイプ全段、>/dev/nullに捨て終わるのが完了するまで
time直後のプロセスは生きてるんだから、realについては問題ないような.. (user,sysは駄目ですね)

$ time sh -c '/usr/bin/printf %100000000s | tr " " "\n" | cat -n' > /dev/null
real 0m8.159s
user 0m7.832s
sys 0m0.324s

$ time sh -c 'dd if=/dev/zero bs=100000000 count=1 2>/dev/null | tr "\0" "\n" | cat -n' > /dev/null
real 0m7.608s
user 0m7.300s
sys 0m0.308s
642名無しさん@お腹いっぱい。:2005/09/27(火) 13:09:23
>>627
printfは高機能なのでオーバーヘッドが大きい。
643名無しさん@お腹いっぱい。:2005/09/27(火) 13:28:00
そんなのたかが知れてる。
システムコールの全回数の方がよほど効いてくる。

644名無しさん@お腹いっぱい。:2005/09/27(火) 14:39:24
>>630 >>635
標準出力が端末の場合は確かに\nごとに
システムコールwrite()が呼び出されるが、
/dev/nullにリダイレクトしてる場合は
効率良くBUFSIZごとにwrite()されてるよ。

strace seq 1 100000 > /dev/null

で観察してみるとわかる。
なので、seqがなぜ遅いのか依然不明。
645名無しさん@お腹いっぱい。:2005/09/27(火) 15:10:25
見たところprintf(3)のオーバーヘッドしか思いつかんなあ
パイプラインで複数プロセス動かす以上に遅くなるってのは
にわかには信じがたい話ではあるが

printf(3)のかわりにitoa(3)を使ったらどうよ。
646名無しさん@お腹いっぱい。:2005/09/27(火) 15:13:34
あくまで環境は秘密ですか。
647名無しさん@お腹いっぱい。:2005/09/27(火) 15:16:42
648645:2005/09/27(火) 17:39:21
失敬。itoa(3)なんてものは、少なくとも標準では無いな。

俺の環境(FreeBSD 4.7 RELEASE)では、>>627のバージョンのseqは
printf(1)を用いたパイプラインよりも速い。
が、FreeBSDのcatのソースを見ると-nオプションでの出力には
単純にfprintf()を用いているので、そのためと考えられる。

itoa()のソースを適当にパクってきてprintf(3)の替わりに用いてみたが、
あまり変わらないようだ。
649名無しさん@お腹いっぱい。:2005/09/27(火) 18:00:54
ちゃんとgccの最適化オプション付けてる?
あんまり変わらんと思うけど。
650名無しさん@お腹いっぱい。:2005/09/27(火) 18:23:08
>>641
> time直後のプロセスは生きてるんだから、realについては問題ないような..
$ time sleep 1 | sleep 10
とかしてみ
651名無しさん@お腹いっぱい。:2005/09/27(火) 19:26:23
>>650
たしかにそれはreal 1秒でおわりになりました。ですが、sleepでは
標準入力がcloseされるまで待ってくれていないので、 >>637-641 とは
事情が違うような気がいたします。

最終段の cat は入力がなくなるまで・出力が完了するまで終われない、
中間の tr は入力がなくなるまで・出力が完了するまで終われない、
初段の printfやddは出力が完了するまでは終われない。
だからほとんど同時まで全プロセスは生き続けてる→timeが計ってる
初段だけの real は、全部をひっくるめて呼び出したときの real に
だいたい一致してる、と考えたのです。

本論を追ってる皆さん、トーシロがまぎれこんじゃって、ごめんなさい。
652名無しさん@お腹いっぱい。:2005/09/27(火) 20:17:26 0
>>648
割算、剰余の影響かな。
653名無しさん@お腹いっぱい。:2005/09/28(水) 00:28:28
>>638
激しく同意。
だが、俺の知識ではそろそろスレの議論に追いつけなくなりつつある。
654名無しさん@お腹いっぱい。:2005/09/28(水) 00:37:38
zsh
$uname
Linux localhost 2.6.11.10 #1 Sun Jun 5 03:14:07 JST 2005 i686 Intel(R) Pentium(R) 4 CPU 2.40GHz GenuineIntel GNU/Linux
$time (sleep 1 | sleep 10)
(; sleep 1 | sleep 10; ) 0.00s user 0.00s system 0% cpu 10.010 total
$time (sh -c 'printf %100000s |tr " " "\n"|cat -n' >/dev/null )
(; sh -c 'printf %100000s |tr " " "\n"|cat -n' > /dev/null; ) 0.01s user 0.00s system 93% cpu 0.016 total
$time /bin/seq 1 1 100000 > /dev/null
/bin/seq 1 1 100000 > /dev/null 0.13s user 0.00s system 95% cpu 0.134 total
$time ./seq >/dev/null
./seq > /dev/null 0.03s user 0.00s system 99% cpu 0.033 total

655名無しさん@お腹いっぱい。:2005/09/28(水) 01:31:32
>>629
63では無いがダメだった。
が、解決法は見つけた。
環境は Linux + bash ね。

$ message="-n nullpo"

$ echo "$message"
nullpo$

$ echo ''"$message"
-n nullpo
$
656名無しさん@お腹いっぱい。:2005/09/28(水) 02:14:52
$ seq 1 1 100000 > tmp.seq
$ time cat tmp.seq > /dev/null
が最強って事でFA
657名無しさん@お腹いっぱい。:2005/09/28(水) 10:56:56
こんにちは。
シェルスクリプトに
set -x
set +x
を入れてデバッグしているのですが、この出力をどこかに残すことは
できないのでしょうか?
画面に出てすぐに消えてしまって困っています。
658名無しさん@お腹いっぱい。:2005/09/28(水) 11:27:57
>>657
script

659名無しさん@お腹いっぱい。:2005/09/28(水) 12:40:45
>>657
set +x の出力なら、普通に
./hoge.sh 2> logfile
で取れるだろ。
標準出力も一緒なら、
./hoge.sh > logfile 2>&1
で取れる。

>>658
違います。
660名無しさん@お腹いっぱい。:2005/09/28(水) 17:29:47
>>659
別に scriptでも違うくないだろ。
まあ、scriptだとちょっと大袈裟なのと、
行末に^Mが付いちゃうのがウザイけどな。
661名無しさん@お腹いっぱい。:2005/09/28(水) 19:12:11
違いますと断言できる自信はどこから湧いてくるんだろう。自信袋か?
662名無しさん@お腹いっぱい。:2005/09/29(木) 01:51:39
>>657
# オリジナルのstdout/errをコピーしておく
exec 3<&1
exec 4<&2
# stdout/errをファイルへリダイレクト
exec > PATH_TO/log.txt 2>&1
# ここからログ記録開始
set -x

do_something

set +x
# ログ終了。stdout/errを元に戻す
exec 1<&- 1<&3
exec 2<&- 2<&4
663名無しさん@お腹いっぱい。:2005/09/29(木) 03:41:39
標準以外のファイル記述子を有効利用しているのは初めて見た。
そんな使い方があるのか。
664名無しさん@お腹いっぱい。:2005/09/29(木) 03:51:49
665名無しさん@お腹いっぱい。:2005/09/29(木) 04:34:48
>>664
色々参考になったよ。サンクス。

訳文だが "「脳死」した設計" とまで言われる
csh が哀れだ。w
666名無しさん@お腹いっぱい。:2005/09/29(木) 08:31:40
>>662
一応「出力」なんだから、
exec 3>&1 (以下同様)
と書いた方が良くないか?
exec 3<&1
でも動くみたいだけど、なんか気持ち悪い。
(動いてしまうのは実装依存かも)

あと、元に戻す時、
exec 1>&-
とかで一旦クローズする必要あるの?


>>663
標準以外のファイル記述子は、GNU configureスクリプトでバリバリ使われてるけど、
見たことないのかな?
667名無しさん@お腹いっぱい。:2005/09/29(木) 13:30:07
echo "$0: $file が見つかりません" 1>&2
しかし、csh では標準出力を標準エラーにリダイレクトすることはできません。
だから、結局次のようなばかばかしいものを書くはめになるのです。
sh -c 'echo "$0: $file が見つかりません" 1>&2'

これってほんと?tcshとかはできる?
668名無しさん@お腹いっぱい。:2005/09/29(木) 14:28:07
>>667
すべて本当。
tcshでも出来ない。
だからcsh/tcshは糞。
語り尽くされた話題。
669名無しさん@お腹いっぱい。:2005/09/29(木) 15:57:33
それが定期的に投稿されるってんだからw
670名無しさん@お腹いっぱい。:2005/09/29(木) 16:09:03
人恋しい季節って奴か。
671名無しさん@お腹いっぱい。:2005/09/29(木) 22:47:44
>>666
>標準以外のファイル記述子は、GNU configureスクリプトでバリバリ使われてるけど、
>見たことないのかな?

無いっす。
まだまだ修行不足っす。
672662:2005/09/29(木) 23:31:01
>>666
まず、
> あと、元に戻す時、
> exec 1>&-
> とかで一旦クローズする必要あるの?
これは、ファイルをcloseするため。
exec 3<&1
exec 1> file.txt
exec 3>&1
sleep 10
ってスクリプトをバックグラウンドで実行して、fuser file.txtしてみ。
で、その後 exec 3>&1 を、exec 1<&- 1<&3 って変えて同じ事してみると
わかるよ。

> 一応「出力」なんだから、
> exec 3>&1 (以下同様)
> と書いた方が良くないか?

1を閉じるとこれはできないし、1のコピーである3を1にリダイレクトしても
そのままログに出つづける。
exec 3<&1
exec 1> /dev/null
echo test
exec 3>&1
echo test2
ってやると"test2"は出力されない。exec 3>&1をexec 1<&3 に変えてやってみると"test2"が出力されるのがわかる。なぜかは自分で考えましょう。

> (動いてしまうのは実装依存かも)

違うよ。
673名無しさん@お腹いっぱい。:2005/09/29(木) 23:41:40
>>672
あなた、後半、完全に読み間違えてます。

>>666 が言ってるのは、

exec 3<&1 ← ここのことね
hoge; hoge
exec 1<&3 ← ここのことね

とするんじゃなくて、

exec 3>&1 ← ここのことね
hoge; hoge
exec 1>&3 ← ここのことね

と書けと言うことでしょ。

出力なのに、入力のリダイレクトとして、
exec 3<&1
と書いても、
exec 3>&1
と同じ動作をしてしまうのは、
実装依存です。動作は保障されません。
674名無しさん@お腹いっぱい。:2005/09/29(木) 23:57:28
>>672 の前半もトンチンカンなこと言ってるね。

exec 3<&1
exec 1> file.txt
exec 3>&1

じゃなくて、
exec 3>&1
exec 1> file.txt
exec 1>&3
だろうが。。


結局、中途半端な知識で間違ったことカキコしてる
>>662 = >>672 は、初心者を混乱させる元なので、消えてください。

まとめ:

出力系の file descriptor をリダイレクトする時、

3>&1 (1を3に複製)
1>&3 (3を1に複製)

入力系の file descriptor をリダイレクトする時、

5<&0 (0を5に複製)
0<&5 (5を0に複製)

入力か出力かで < と > の向きが違うので、
(実装依存で動いてしまう場合が多いとは言え)
向きは守ってください。
675名無しさん@お腹いっぱい。:2005/09/30(金) 00:29:03
なんか盛り上がってますねw

stdoutとstderrを両方ファイルに落す時、B-shでは、
hoge > file 2>&1
と書きますが、これを、
hoge > file 2<&1
と書いても同じように動作してしまうのです。

>>662 = >>672 は、おそらくこの点を根本的に勘違いしているのでしょう。

2>&1 は、「出力用としてopenされている fd=1 を 2にコピーする」
というのが仕様で、1が入力用でopenされている場合の動作は未定義です。
(>>666 が言うように実装依存です)

でも、実際のshとかでは、単にfdをコピーするだけの動作をするようなので、
2<&1 と書いても 2>&1 と同じ動作になっちゃうんです。

hoge > file 2<&1 なんて書き方しませんね。
良い子は hoge > file 2>&1 と書きましょう。
676名無しさん@お腹いっぱい。:2005/09/30(金) 11:48:32
横レス失礼します、ド初心者です。

>674
出力系の file descriptor をリダイレクトする時、

3>&1 (1を3に複製)
1>&3 (3を1に複製)

>675
2>&1 は、「出力用としてopenされている fd=1 を 2にコピーする」

どっちが正しいんでしょうか。なんか、もう訳わからないです。
677名無しさん@お腹いっぱい。:2005/09/30(金) 11:58:42
man dup2
678名無しさん@お腹いっぱい。:2005/09/30(金) 12:03:49
>>676
両方正しいです。>>674>>675 は、同じことを別の言葉で言ってるだけです。

2>&1 とは、
「出力用としてオープンされている
ファイル記述子1を2に複製。」

2<&1 とは、
「入力用としてオープンされている
ファイル記述子1を2に複製。」← 普通はあり得ない
(しかし、実装依存で 2>&1 と同じ動作になることが多い)

つーことで、大嘘書いた >>662 >>672 は責任とれ!
679名無しさん@お腹いっぱい。:2005/09/30(金) 14:08:49
実際にはdup2(2)で実装されているとすれば、やっているのは単に「ファイル記述子を複製する」
だけのことで、「入力用」「出力用」を区別する必要は無いように思う。

一体bourne shellでは何のためにこういうインタフェース/仕様にしたんだろうか。
680名無しさん@お腹いっぱい。:2005/09/30(金) 21:48:17
とりあえずシェルスクリプト本を適当に(←ぉぃ)2冊買ってきました。
いきなり疑問が・・1冊目では「testコマンド」
2冊目では「test文」と書いてありました。
これはどちらでもいいのでしょうか?
あと、コマンドと文とはどう違うのでしょうか?
681名無しさん@お腹いっぱい。:2005/09/30(金) 22:06:40
通常、「コマンド」というのは「test」というモノを指す。
test -f hogehoge
という一つの式を文と呼んでいるんじゃないの?
testという単独の「モノ」を指して「test文」と言うとは考えにくいんだけど。

で、「test -f hogehogeというコマンドを〜」みたいにいうことはあるかも知れない。
その場合は「モノ」を指す「コマンド」という用語としてよりも、そういう
命令を与える、という感じの使い方だと思う。

「test文」という表現があったら、
「test( -f hogehoge などという、testコマンドを使った)文」
と読めばいいんじゃないのかな。
682名無しさん@お腹いっぱい。:2005/10/01(土) 00:49:45
そんなオレ定義使ってる本は捨ててしまえ
683名無しさん@お腹いっぱい。:2005/10/01(土) 01:59:15
オレ定義というよりは読解不足が問題
684名無しさん@お腹いっぱい。:2005/10/01(土) 02:10:09
突っ込もうかと思ったけど、>>683がにやにやしてそうだから僕もにやにやしておくよ。
685名無しさん@お腹いっぱい。:2005/10/01(土) 06:31:30
じゃあ俺はのまのましておく
686名無しさん@お腹いっぱい。:2005/10/01(土) 12:18:00
一応確認ですが、
「test文」と「testコマンド」の、どちらが「オレ定義」なんですか?
オレ定義の本は今からブコフに売りに行きます。
687名無しさん@お腹いっぱい。:2005/10/01(土) 12:36:56
>>686
文脈によるからそれぞれの書名教えてよ。
688名無しさん@お腹いっぱい。:2005/10/01(土) 12:54:16
「test文」なんて聞いたこともねー
「if文」ならともかく
689名無しさん@お腹いっぱい。:2005/10/01(土) 15:01:56
敢えて日本語にするなら、「test文」ではなくて、「test式」だろうな。
690名無しさん@お腹いっぱい。:2005/10/01(土) 15:24:26
>>688.689
阿呆。
691名無しさん@お腹いっぱい。:2005/10/01(土) 15:44:06
>>690
error: 688 is not defined as a structure
error: missing member 689 in 688
692名無しさん@お腹いっぱい。:2005/10/01(土) 16:58:01
「文」と言うと、シェルの文法上のキーワードを指す。
シェルスクリプトでは「testは文ではなく、コマンドである」ということが
理解の上で結構重要だったりする。
最初に読んだ本の「刷り込み」って結構あとを引くことがあるから、
不正確な本なら捨てて正解。
693名無しさん@お腹いっぱい。:2005/10/01(土) 17:20:07
重箱の墨をつつくような話はやめようや
694名無しさん@お腹いっぱい。:2005/10/01(土) 17:41:23
>680
2冊とも読んで、2冊ともブコフに捨ててくるのが正解。
695名無しさん@お腹いっぱい。:2005/10/01(土) 19:21:04
>>693
重箱の「墨」ならどうでもいいな
696名無しさん@お腹いっぱい。:2005/10/02(日) 18:09:44
>>695 重箱の墨をつつくような話はやめようや
697名無しさん@お腹いっぱい。:2005/10/02(日) 18:30:38
ディレクトリ内のファイルをすべてチェックするshスクリプトで

for i in ${dir}/*; do
# ${i}がディレクトリの時は再帰で再びここに
# ファイルならチェック。
done

と書いてみたのですが、${dir}のディレクトリの中身が空っぽの時に${i}が
/path/to/dir/* とアスタリスクを展開してないものが入ってしまいます。
ディレクトリ内にファイルも何もない時も考慮したものにするには
どうしたらいいでしょうか?
698名無しさん@お腹いっぱい。:2005/10/02(日) 19:03:17
ループの中でtestした方が安全。
どのみち実行開始後にディレクトリに変化が生じた可能性とかあるし。
そもそもファイルだとかディレクトリだとかの種類によって
処理を分けるんだろ?

699名無しさん@お腹いっぱい。:2005/10/02(日) 19:33:54
find 使えばいいんじゃないの?
700名無しさん@お腹いっぱい。:2005/10/02(日) 20:59:07
>>693 >>695
良書は重箱の隅までも気を配ってきちんと書かれています。
701697:2005/10/03(月) 01:10:32
ありがとうございます。

>>698
自分の説明が悪いのととスクリプトを省略しすぎていてすみません。
>>697は関数の中の一部でコメント部分でif testを行って
ディレクトリなら新たな引数で再びこの関数を実行、ファイルなら
いろいろチェックに入るという感じになっています。

>>699
いままんを見たら -empty が使えそうですね。findはなんか重そうな雰囲気があるのと、
ファイルのチェックで新旧の比較を行っていてそこにfindの-newerを使っていましたが、
最近どこかのレスでファイルの新旧の比較はtestの-ntが使えるというのを見かけて
findがすっかり頭から飛んでしまってました。
702名無しさん@お腹いっぱい。:2005/10/03(月) 03:50:53
./dir-A 以下にあるファイル群について、ファイル中の語句aaaをbbbに置換して、
./dir-B 以下にコピーしたいのですが、どうすればいいでしょうか?
./dir-A 以下にもディレクトリはあるので、できればディレクトリ構造も保存したいんですが。
よろしくお願いします。
703名無しさん@お腹いっぱい。:2005/10/03(月) 04:10:01
>>702
find Aのディレクトリのファイル -exec ( やりたいことやって ; Bのディレクトリにコピー )
704名無しさん@お腹いっぱい。:2005/10/03(月) 11:03:48
atコマンドで特定のスクリプトを実行したい場合は通常、

at-f <filename> "13:00 10/22/05"

だけど、これを"at -f"という文字列を使わずに実行することは出来ないだろうか。

つまり上記の「特定のスクリプト」のファイル名がonigiri_shだった場合、
それを定時に動かしたい場合

onigiri_sh "13:00 10/22/05"

ということでatに登録したい場合、どうすればいいのだろう。
705名無しさん@お腹いっぱい。:2005/10/03(月) 11:33:27
onigiri_shの中でat -f $0 $1
706名無しさん@お腹いっぱい。:2005/10/03(月) 12:01:34
#!/usr/bin/at -f
707名無しさん@お腹いっぱい。:2005/10/03(月) 14:26:11
急にスレの流れが早くなったので、今ごろ読んだオレが来ましたよ。
なんか、見過ごせないレスがあったので亀レスします。

>>672

>> あと、元に戻す時、
>> exec 1>&-
>> とかで一旦クローズする必要あるの?
>これは、ファイルをcloseするため。
>exec 3<&1
>exec 1> file.txt
>exec 3>&1
>sleep 10
>ってスクリプトをバックグラウンドで実行して、fuser file.txtしてみ。
>で、その後 exec 3>&1 を、exec 1<&- 1<&3 って変えて同じ事してみると
>わかるよ。

sleep 10の直前の行、
exec 3>&1 じゃなくて exec 1>&3 だろ。
exec 1>&3 さえ書けば、exec 1>&- で一旦closeする必要はない。

あと、最初の行も exec 3>&1 と書いた方がいいな。出力なのだから。

closeするとしても、書くなら exec 1>&- 1>&3 だな。
「exec 1<&- 1<&3」なんて書き方はおかしい。

(つづく)
708名無しさん@お腹いっぱい。:2005/10/03(月) 14:27:13
>>672

>> 一応「出力」なんだから、
>> exec 3>&1 (以下同様)
>> と書いた方が良くないか?

>1を閉じるとこれはできないし、1のコピーである3を1にリダイレクトしても
>そのままログに出つづける。

「exec 3>&1 (以下同様)と書いた方が良くないか?」と言ってるのは、
最初に1を3に退避する時のことであって、
あとで3を1に戻す時の話じゃないだろ。
それに、言ってるのは >& か <& かの、 > の向きのことと思われる。


>> (動いてしまうのは実装依存かも)

>違うよ。

>>672 が「違うよ」と言ってるのが違うよ。
シェルによっては >& と <& の向きが違うとエラーになることがある。

あと、>>672 は全体に勘違いレスだらけ。欲嫁。
709名無しさん@お腹いっぱい。:2005/10/03(月) 20:30:06
もう当事者以外意味不明な議論になってることに気付け
710名無しさん@お腹いっぱい。:2005/10/03(月) 21:30:56
いや、有用な情報じゃないか。
自分が興味ないからといって、勝手にスレ住人を代表するようなことをするな。
711名無しさん@お腹いっぱい。:2005/10/03(月) 22:42:11
激しくスルーしてるだけだと思うけど。
712名無しさん@お腹いっぱい。:2005/10/04(火) 15:54:41
>>704の続きが
http://pc8.2ch.net/test/read.cgi/tech/1112553783/146
にあってテオワロス
713名無しさん@お腹いっぱい。:2005/10/04(火) 20:49:03
shのリダイレクトはちょっと特殊だからねえ。

一応念のために書いとくけど、3>&1も3<&1も1を3にコピーするという動作をします。

1の出力を3にコピーしたいんだからとか思って1>&3とか書くと、
3なんて知らねえとBad file descriptorって怒られます。
これは開かれてない3を1にコピーしようとしてOSに怒られてるわけ。

672はその動作を見て、意味を理解せずに、自分なりの解釈で誤解したまま使ってる。
例えば662で挙げている例のように1>&3と書くと動かなくなるので3<&1と書くとかって感じでね。
つまり彼は1>&3 == 3<&1だと誤解してるんだよね。実際は3>&1 == 3<&1なのです。

そこで、3<&1じゃなくて3>&1って書いたらと誰かが言ったんだけど、それをますます誤解して
672みたいな文章になっちゃったんだよね。707-708もそこを説明せずに間違ってるとだけ
伝えてるので、それを聞いただけでは672の誤解は解けないと思うんだよね。

というわけでしゃしゃり出てきて、ちょっと説明してみました。
3>&1 == 3<&1ですよ〜。間違えないようにね。

例えばmake | tee makelog 2>&1ってのも2の出力を1にコピーしましょうって意味ではなくて、
1にリダイレクトしたtee makelogというプログラムへのパイプを2にコピーすることで、
2の出力もteeに食わせようって意味なんだよね。誤解しないようにね。
714名無しさん@お腹いっぱい。:2005/10/04(火) 21:29:26
>>713
解説tnx。これで >>672 は自らの過ちを認め、成仏できるでしょう。
715名無しさん@お腹いっぱい。:2005/10/04(火) 21:51:53
たまに &> と書いて 1 と言うファイルができてる俺。
716名無しさん@お腹いっぱい。:2005/10/04(火) 22:04:40
bashだと、(( i > 3 )) と書いても 3 というファイルはできないw
717名無しさん@お腹いっぱい。:2005/10/04(火) 22:08:07
>>715
よう、俺。
718名無しさん@お腹いっぱい。:2005/10/05(水) 00:07:59
>>715, >>717
やあ、私。
719名無しさん@お腹いっぱい。:2005/10/05(水) 00:17:28
Bourne?Shell?自習テキスト
ttp://www.tsden.org/takamiti/shText/shText.html
ここの、リダイレクトの説明、思いっきり間違ってるね。
720名無しさん@お腹いっぱい。:2005/10/05(水) 02:08:17
「変更」ってとこ?
721名無しさん@お腹いっぱい。:2005/10/05(水) 08:09:45
>720
  2.3.2 エラー出力を標準出力にマージする
って辺りかな。

  $ make >./make.log 2>&1
の説明として

  リダイレクトのメカニズムを理解する上で大切なことは、コマンドラインで記述されたものが
  「右から左の順に評価」されるということです。エラー出力を標準出力にマージするこの例では、
  まず最初に「2>&1」が評価されてから「>./make.log」が評価されます。

  ですから「2>&1」はファイルディスクリプタ「2」を「1」に、つまり標準エラー出力を標準出力に
  変更することになります。さらに、「>./make.log」として標準出力が 「./make.log」 にリダイレクト
  されています。結果的に「./make.log」に標準出力とエラー出力がマージされたものが書き出される
  ことになります。

みたいな。リダイレクトをホースを切り替えるみたいな物だと考えてると、
こういう誤解をするんだと思われ。実際はFDをDUPするだけの非常に原始的な
メカニズムだから……
722名無しさん@お腹いっぱい。:2005/10/05(水) 09:05:05
>>721
うわぁー、こりゃひどい。大間違いだ。

>「右から左の順に評価」されるということです。
「左から右の順に評価」が正しい。

>「2>&1」はファイルディスクリプタ「2」を「1」に、
>つまり標準エラー出力を標準出力に変更することになります。
違う。「「1」を「2」に複製する」が正しい。

こんな大間違いな文書、即刻削除してもらいたいな。
723名無しさん@お腹いっぱい。:2005/10/05(水) 09:14:51
>>719-722
この間違いの「Bourne Shell 自習テキスト」を、
>>3 の3つ目のテンプレから外すことを強く希望。

これ以上初心者の被害者を増やすな。
(>>672 も含めてw)
724名無しさん@お腹いっぱい。:2005/10/05(水) 09:33:38
まあ、そのうち直してくれるんじゃないの?
非難するばっかじゃ何もなくなっちゃうよ。
725名無しさん@お腹いっぱい。:2005/10/05(水) 10:18:33
>>724
タイムスタンプから見て、相当昔に書かれた文書だろ。
今更訂正されることはないと思われ。
「非難」なんじゃなくて、こういう正反対の間違いは「害悪」なんだよ。
無い方がマシ。これを読んで間違った知識を得た初心者が、
他の人間に間違いを広めるウィルスのようなもの。

リダイレクトやファイル記述子の概念を理解していないということは、
(抜きとり検査で不良が見つかったのと同じく)
それ以外の文書についても同様の間違いが含まれている可能性が極めて高く、
文書全体を削除するのが最も妥当だと思われる。
726名無しさん@お腹いっぱい。:2005/10/05(水) 10:25:24
>>722,723,725
自演?
727名無しさん@お腹いっぱい。:2005/10/05(水) 11:05:19
そうだとして、それをわざわざ邪推して指摘することに何の意味がある?
昔自演に騙されて赤っ恥でもかいたか?それともこのサイトの作者か?
728名無しさん@お腹いっぱい。:2005/10/05(水) 11:07:59
いや、必死だなぁと思って。
729名無しさん@お腹いっぱい。:2005/10/05(水) 11:23:56
最近よく思うんだ
なんで直接本人に文句を言わないんだろう。連絡先も書いてあるのに。
って。こんなとこで大声出しても無意味なのに。
修正してくれないとしても、ほぼ自由に使っていいと言っているのだから
ここの人達で手を入れていくという道もあるだろうし。
730名無しさん@お腹いっぱい。:2005/10/05(水) 12:57:12
自演くさいな
たかがリダイレクトでなんでそんなに熱くなれるんだろう?
1段落が変だからといって、テンブレから外せとか痛々しくて見てらんない
731名無しさん@お腹いっぱい。:2005/10/05(水) 13:11:31
>>730
一段落じゃなくて二段落(以上)と思うが。
根本的な理解不足が見受けられるので、
リダイレクトだけの問題じゃなくて、
やはり全体的に不正確な文章だから、
テンプレからは削除した方がいいと思うよ。

>>729
本人はどうでもよい。
問題はその文章を読んで被害を受ける人。
本人に直接言っても反映に時間がかかるし、黙殺されるかも知れん。
それより、もともと掲示版で話題が出たなら、
その掲示版に書き込んで、間違いは間違いと指摘するのが先。
732名無しさん@お腹いっぱい。:2005/10/05(水) 14:23:48
「修正案をメールしたけど無視された。
(オプション):勝手に修正するのも拒否された。
テンプレから削除しませう。
(オプション):なんならオレが初心者向けのチュートリアル書いたるで」
ならだれもいちゃもんつけません。
善意の*行動*に期待しています。
733名無しさん@お腹いっぱい。:2005/10/05(水) 16:17:32
名無しにやれやれと言っても無意味なのに。
人に期待するくらいなら自分でやれば?
734名無しさん@お腹いっぱい。:2005/10/05(水) 22:13:31
人情優先か
UNIXらしい...

735名無しさん@お腹いっぱい。:2005/10/07(金) 11:31:34
おしえてえらいひと。

#!/bin/sh
trap "echo trap SIGHUP" 1
sleep 100

これを実行して、kill -HUP %1 のようにジョブ ID を指定してシグナルを送ると
ちゃんと trap の中身が実行されるんだけど、
kill -HUP 1234 のようにプロセス ID を指定しても動きません。
なんでなんでしょうか。
736名無しさん@お腹いっぱい。:2005/10/07(金) 12:30:51
100秒まってみろ。
あるいは、非標準の -T をサポートしてるシェルを使って、親だけ非同期に動かすか、
プロセス番号をマイナスにしてプロセスグループにシグナル送るか。
737名無しさん@お腹いっぱい。:2005/10/07(金) 12:37:31
SIGHUPがsleepに割り込まないってことか
738名無しさん@お腹いっぱい。:2005/10/07(金) 17:01:51
-pid にしたらシグナルを受けてくれた。
でもなんでそうなるのかわからんです。
だれかわかりやすい解説or解説へのポインタください。
739名無しさん@お腹いっぱい。:2005/10/07(金) 21:46:55
>>738
-pidにするとプロセスグループに属するプロセスすべてに
シグナルが送られるので、シェル自身だけじゃなく、
sleepにもHUPが届くから、kill %1と同じ動作になる。
740名無しさん@お腹いっぱい。:2005/10/17(月) 03:25:12
下の簡易ロックみたいのを、複数プロセスからガンガン呼び出していると
動くことは動くのですが、"for f in `ls -1 lock*`" のところで稀に
「ファイルが見つかりません」と言われてしまいます。
自分で touch して必ずファイルはあるはずなのに、なぜなんでしょうか?

touch lock$$

for f in `ls -1 lock*`
do
 if [f != "lock$$"] ; then
  rm lock$$
  exit
 fi
done

<critical section>

rm lock$$
741名無しさん@お腹いっぱい。:2005/10/17(月) 04:47:44
そりゃ rm してるから当然だ、たわけ者。
742名無しさん@お腹いっぱい。:2005/10/17(月) 06:59:14
>>740
一言で書くと>>741の通りなのだが、一応補足。

複数のプロセスがほぼ同時に実行された場合に
最初に if [f != "lock$$"] ; then に辿り着いた
プロセスが他のロックファイルを消してしまうから。
743名無しさん@お腹いっぱい。:2005/10/17(月) 07:34:59
> 最初に if [f != "lock$$"] ; then に辿り着いた
> プロセスが他のロックファイルを消してしまうから。
744名無しさん@お腹いっぱい。:2005/10/17(月) 10:10:19
そもそもfじゃなくて$fじゃないの
745名無しさん@お腹いっぱい。:2005/10/17(月) 12:32:24
スペース空けないと
[f: not found
になると思うのだけど。
746名無しさん@お腹いっぱい。:2005/10/17(月) 17:56:00
>>740
shellがlock*を展開してからlsがforkされるまでの間に
別のプロセスが自分のlockを消してしまうから。
747名無しさん@お腹いっぱい。:2005/10/17(月) 22:43:26
>740
シェルスクリプトのロック作成は、以下じゃなかったっけ?

touch lock.$$
if link lock.$$ lock then
;
else
rm lock.$$
exit
fi

<critical section>

rm lock lock.$$
748名無しさん@お腹いっぱい。:2005/10/17(月) 22:45:02
;が抜けてた。

if link lock.$$ lock; then
749名無しさん@お腹いっぱい。:2005/10/17(月) 22:45:47
ていうか、linkってなんだ。lnだ。orz
750名無しさん@お腹いっぱい。:2005/10/18(火) 01:38:27
>>749
何故にハードリンク?
751名無しさん@お腹いっぱい。:2005/10/18(火) 01:41:28
linkをハードリンクするのにlinkがいる。
752名無しさん@お腹いっぱい。:2005/10/18(火) 09:08:00
touchでファイルを作る。
lnでatomicな操作で、ファイルを作成&作成できたかどうかのチェックをする。
lnで作成できてたらロック成功。できてなかったら失敗なので終了。

別にハードリンクじゃなくても、atomicに作成&作成チェックできるコマンドがあればそれでいい。
creat(3)とかね。
753名無しさん@お腹いっぱい。:2005/10/18(火) 16:42:26
FreeBSD% man 3 creat
No entry for creat in section 3 of the manual
754名無しさん@お腹いっぱい。:2005/10/18(火) 17:04:34
>753
3になきゃ2だろ。

NetBSDだとcreat(3)はopen(2)を呼んでるだけだから3。
755名無しさん@お腹いっぱい。:2005/10/18(火) 17:47:37
3でも2でもいいけど、シェルスクリプトで使うatomicなコマンドとどこが関連するんだか。
756名無しさん@お腹いっぱい。:2005/10/18(火) 18:02:58
そうだったコマンドって言ってたから気になったのに
何やってんだ俺は
757752:2005/10/18(火) 18:42:15
>756
すまんな。

atomicなファイル操作システムコールとしてメジャーなcreatとlink→
linkはコマンドがあるのでln、Cで書くならcreatもあるね。といった感じで
並べて書いただけなんだだよ。
758名無しさん@お腹いっぱい。:2005/10/18(火) 20:48:22
いや、俺は単にハードリンクじゃなくてシンボリックリンクで
いいんじゃないの?と言いたかっただけです。
シンボリックリンクならtouchも不要だし。
759名無しさん@お腹いっぱい。:2005/10/18(火) 23:24:55
スクリプトから使うんなら、mkdirを使うのがいいと思うけどなあ。
FATの上でも使えるし、DOSでも応用できるし。
760名無しさん@お腹いっぱい。:2005/10/19(水) 04:03:34
>>758
Is that atomical operation?
761名無しさん@お腹いっぱい。:2005/10/19(水) 04:22:03
linkじゃなくてln -sだって言っておけばこんな大事にならなかったんだろうね。
762名無しさん@お腹いっぱい。:2005/10/19(水) 09:28:19
>>760
シンボリックリンクもatomicalだよん。
763名無しさん@お腹いっぱい。:2005/10/19(水) 12:07:14
atomicにalつけるな
764名無しさん@お腹いっぱい。:2005/10/19(水) 14:05:30
alatomic
765名無しさん@お腹いっぱい。:2005/10/19(水) 20:12:32
atomicalic
766名無しさん@お腹いっぱい。:2005/10/19(水) 20:15:33
atomicalicish
767名無しさん@お腹いっぱい。:2005/10/19(水) 20:17:24
で、ロックファイルが消え残ってる場合の処理とか
ロックファイル消すためのシグナルハンドラとかも書くのか

うぜえな
768名無しさん@お腹いっぱい。:2005/10/19(水) 21:00:54
やっぱ、ロックファイルは atomicalizationalicish なsymlinkで決まりだね。
シグナルハンドラなんて trapコマンド一発で eleganticalizationalicish に決めよう。
769名無しさん@お腹いっぱい。:2005/10/19(水) 21:04:59
>>760
どうでもいいが、不要な al 以外に、必要な冠詞が抜けてるね。

Is that an atomic operation ?

が正しい。無理せずに日本語で書くべし。
770名無しさん@お腹いっぱい。:2005/10/19(水) 21:08:24
Est-ce que c'est une operation atomique?
771名無しさん@お腹いっぱい。:2005/10/19(水) 21:16:00
予想される展開:

Ist der ein Atombetrieb ?
E quello un funzionamento atomico ?
E aquela uma operacao atomica ?
Es eso una operacion atomica ?
772名無しさん@お腹いっぱい。:2005/10/19(水) 21:42:17
最近は翻訳サイトが多杉てこの手のお遊びは流行らないから次逝こうぜ
773名無しさん@お腹いっぱい。:2005/10/19(水) 21:51:58
Ειναι αυτο μια ατομικη λειτουργια;
Это атомная деятельность ?
這是不可分操作馬 ?

は、想定外ですか?
774名無しさん@お腹いっぱい。:2005/10/19(水) 22:03:59
> 最近は翻訳サイトが多杉てこの手のお遊びは流行らないから次逝こうぜ
775名無しさん@お腹いっぱい。:2005/10/19(水) 22:16:53
De nos jours, ce genre de jeu ne sera pas dedans parce
qu'il y a tant d'emplacements de traduction. Nous devrions aller apres.
776名無しさん@お腹いっぱい。:2005/10/19(水) 22:20:19
真上のカキコを自動的にaltavistaあたりにかけてカキコするスクリプトきぼん
777名無しさん@お腹いっぱい。:2005/10/20(木) 00:13:18
指定したディレクトリ(例:/var/log/squid)配下の
すべてのファイルに対して作成日時から1ヶ月経過しているものは
すべて削除するスクリプトいいのないですか?
778名無しさん@お腹いっぱい。:2005/10/20(木) 00:17:18
>>777 find 使え。
779名無しさん@お腹いっぱい。:2005/10/20(木) 00:57:18
>>777
logに対して使うつもりなら
logrotate + cron もお勧め
780名無しさん@お腹いっぱい。:2005/10/20(木) 01:07:09
squid.conf に残す数を書いて squid -k rotate するのが squid 的なやり方。
781名無しさん@お腹いっぱい。:2005/10/20(木) 01:47:21
>779
このスレ的にはrotate_logじゃないかなと思ったり。

logrotate: Linuxのコマンド
rotate_log: シェルスクリプト
782名無しさん@お腹いっぱい。:2005/10/20(木) 09:13:35
>>781
> logrotate: Linuxのコマンド
> rotate_log: シェルスクリプト

このふたつ、どっちだったか間違えやすいよね。
783名無しさん@お腹いっぱい。:2005/10/20(木) 09:35:44
logrotateやlogadmの書式覚えるの('A`)マンドクセ

自分でスクリプト書いてしまったほうが、ええやん。
784名無しさん@お腹いっぱい。:2005/10/20(木) 10:07:02
logrotate って Linux 以外じゃ動かないの?
785784:2005/10/20(木) 10:09:13
ソース展開したら README.HPUX とか README.Solaris が入ってたよ。
786名無しさん@お腹いっぱい。:2005/10/20(木) 10:31:43
俺はapacheからsquidから全部newsyslogで回してる。
787名無しさん@お腹いっぱい。:2005/10/20(木) 10:59:43
たまたま自分の環境にインストールされていないコマンドの話題になると、
何でも「Linuxのコマンド」にしてしまう人がいる件について。
788名無しさん@お腹いっぱい。:2005/10/20(木) 11:05:09
logrotate(8)には、"4th Berkeley Distribution"と書いてあるな。
789名無しさん@お腹いっぱい。:2005/10/20(木) 11:41:57
Linux由来かどうかに固執する人がいる件について。

もしくは他人がそれについて間違うと嫌味を言わなくては
気がすまない人がいる件について。

毎度毎度しょーもな。
790名無しさん@お腹いっぱい。:2005/10/20(木) 12:06:21
 ∧_∧
( ´∀`)
(    )
| ||
(__)_)
791名無しさん@お腹いっぱい。:2005/10/20(木) 18:27:41
GNU cp を使うと、 cp -l でハードリンクを作れるのですよね。
cp -a の代わりに cp -la とすれば、(バックアップの予備動作などの?)
特定用途では、高速化や省スペース化が図れて面白いと思うんです。
でもそのまま使うと、シンボリックリンクが参照先の本体とのハードリンク
としてコピーされてしまいます。これはあまりうれしくない。
シンボリックリンクをそのままにシンボリックリンクとして、
そうでないファイルをハードリンクとしてコピーするうまい方法を探しています。
792名無しさん@お腹いっぱい。:2005/10/20(木) 18:54:10
このスレにいるんならそれぐらい自分で書け
793791:2005/10/20(木) 18:54:50
cd $sourcedir
for file in `find .`; do
dir="$destdir/`dirname \"$file\"`"
mkdir -p "$dir"
if [ -L "$file" ]; then
cp -af "$file" "$dir"
elif [ -f "$file" ]; then
ln "$file" "$dir"
elif [ -d "$file" ]; then
:
else
echo "SKIPPING: Not a regular file, directory nor symbolic link: " $file >&2
fi
794名無しさん@お腹いっぱい。:2005/10/20(木) 18:57:38
#!/bin/csh
echo "  ∧_∧  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ "
echo -n " (´∀`)< "
echo -n " $* "
# echo -n "$1 "
echo ""
echo " (   ) \________ "
echo ". || | "
echo " (__)_) "
795791:2005/10/20(木) 19:02:59
>>792
おっしゃるとおりで。
そのものズバリなコマンドやユーティリティが存在していたら、
それを使いたかったりします。(そうなるとスレ違いになりますが。)

$destdir が $sourcedir と別なファイルシステムにある場合の判別とかもしてほしいな…
796791:2005/10/20(木) 19:15:27
/bin/cp 互換を目指す場合、可変長引数をとるにはどうすればいいでしょうか?
何度も書き込んですみません。
797名無しさん@お腹いっぱい。:2005/10/20(木) 19:59:32
>796
for i in "$@"; do...; done じゃなかったっけな。

俺はmkshadowdirっていうスクリプトを使ってる。
指定したディレクトリ以下全てのファイルをsymlinkを使ってリンクしてくれる。
ディレクトリは各階層で作成される。また、symlinkの特性を活かす為に、
各階層でSRCというターゲットディレクトリへのsymlinkを作り、間接symlinkに
することで融通性を高めている。

例えばA->{SRC/A}->{{/usr/somwhere}/A}といった2階層でsymlinkされるわけ。
またこうやってつくったsymlinkのメンテにはlwllのrelinkスクリプトを使っている。
どちらもperlスクリプト。
798名無しさん@お腹いっぱい。:2005/10/20(木) 20:24:10
cpio でいいやん。
799名無しさん@お腹いっぱい。:2005/10/20(木) 20:52:32
>>791
pax -rw
800名無しさん@お腹いっぱい。:2005/10/20(木) 20:53:33
>>791
ああ、-lも。
801名無しさん@お腹いっぱい。:2005/10/20(木) 20:56:14
これ、 dpkg-deb --build の前段階に使えたら嬉しいな。
802791:2005/10/20(木) 21:12:36
皆さんありがとうございます。全レスはしませんが

>>797
「最後の引数がディレクトリである」というチェックはどうやってするんだろう。
「最後の引数」を得るにはどうすれば楽かな…

>>799
pax もシンボリックリンクも参照先へのハードリンクになりますね。

>>801 僕です。某パッケージマネージャで使うことを考えています。
803名無しさん@お腹いっぱい。:2005/10/20(木) 22:20:50
>>802
link 関係は良くわからんが、引数の中身を変更せずに
「最後の引数」が欲しいならこれでどう?
引数が一つもないとエラー吐くけど。

#!/bin/sh
LastArg=`shift \`expr $# - 1\`; echo "$1"`

#!/bin/bash
LastArg=$(shift $[$#-1]; echo "$1")
804777:2005/10/21(金) 16:05:45
皆レスサンクス。logrotateは漏れのSolaris8には入ってなかった。
理科大からパッケージ入手してインスコしてみたが上手く動かなかったので
シェル作ってみた。

#!/bin/sh

DEL_DIR=/var/log/squid/

rm `find $DEL_DIR -mtime +31`

このスクリプトをcronで動かせば目的達成できるっぽいんだけど
ログを取りたいんだ。具体的には削除されたファイルと削除した時間をログに記録したい。
上手い方法はありませんか?
805名無しさん@お腹いっぱい。:2005/10/21(金) 16:09:38
Squid なら >>780 でいいじゃん。
806名無しさん@お腹いっぱい。:2005/10/21(金) 23:25:08
あのーすごく簡単なことかもしれないので申し訳ないのだけど、
変数varに文字列が入っていって、そこから正規表現にあった部分だけ
取り出したいのですが、どんなコマンドがいいのですか?
ファイルじゃなくて、変数の文字から抜き出すやりかた。
807名無しさん@お腹いっぱい。:2005/10/21(金) 23:28:54
>>806
expr
808名無しさん@お腹いっぱい。:2005/10/22(土) 00:19:02
>806
var=`*echo $var | sed "s/^.*\(regex\).*$/\1/g"`
こんなんで行くんじゃないの
809名無しさん@お腹いっぱい。:2005/10/22(土) 00:49:53
>>804
#!/bin/sh
DEL_DIR=/var/log/squid/
date >> LOGFILE
rm -v `find $DEL_DIR -mtime +31` >> LOGFILE

あんまりスマートには見えんけど。
810初心者でっす!:2005/10/22(土) 02:32:33
HP-UXでのシェルとシェルスクリプトについての質問なんですが。。。
HP-UXの起動時のプロンプト表示をLinuxみたいにしようとしているんですが
なかなか上手く行かなくて困ってます。。。
Unix :#
Linux :[logname@hostname /]#

システム起動時に"/etc/profile"を見に行ってるのは判明して、
そこに"PS1"に自分の設定したい表示方式を記述してやったら変わる事は分かるんですが
"[ユーザ名@ホスト名 現ディレクトリ名]#"表示にはなるのですが、
ディレクリ移動をすると"現ディレクトリ名"の表示が変わらないのです。。。

Unixのデフォルト"PS1"の中身は以下です。
#echo $PS1 ←コマンド
#       ←"PS1"の中身

あと、"sh"ってサブシェルを読んだりはするのでしょうか?
※Linuxの"bash"は"/etc/bashrc"(サブシェル)を呼んでるみたいに。。。

よろしくお願いします。
811名無しさん@お腹いっぱい。:2005/10/22(土) 04:37:05
>807
>808
ありがとう。
812名無しさん@お腹いっぱい。:2005/10/22(土) 05:18:48
>>810
PS1='[\u@\h \w]\$'
export PS1

とか?
813名無しさん@お腹いっぱい。:2005/10/22(土) 05:31:19
>>810
man sh
814名無しさん@お腹いっぱい。:2005/10/22(土) 09:34:45
素のshで、プロンプトにカレントディレクトリ表示は難しいわな。
つうかできるんか?
cdコマンドにalias設定して、泥臭くやるくらいしか思いつかん。
815名無しさん@お腹いっぱい。:2005/10/22(土) 10:11:03
rootでゴソゴソやんな。
816名無しさん@お腹いっぱい。:2005/10/22(土) 10:26:19
pwdの一つも打てないそんな世の中じゃ
817名無しさん@お腹いっぱい。:2005/10/22(土) 10:30:27
>814
素のsh次第だけどaliasもないshだとどうやってもできないと思われ。
まあ`pwd`とかやっちゃうくらいか?

しかし、rootで何やろうと勝手だけど、rootのプロンプトでcwdとか表示されてたら、
俺はかなり引くな。そんな計算機絶対使いたくねえ。
818名無しさん@お腹いっぱい。:2005/10/22(土) 10:56:34
cdという外部コマンドを作れば、、、
あ、ダメか。
819名無しさん@お腹いっぱい。:2005/10/22(土) 12:05:16
いや、cd() というシェル関数を定義すればできるんだけど、
古い/bin/shでは、シェル関数よりも内部コマンド絶対優先で、
結局無理な場合もある。

rootに限らず、カレントディレクトリをプロンプトで表示するのは
セキュリティ上よくないとされている。
画面を後ろから覗かれた場合、どのディレクトリで作業しているか、
どういう名前のディレクトリが存在するのかバレてしまう。
同様の理由で、ホスト名も表示しない方がよい。
820名無しさん@お腹いっぱい。:2005/10/22(土) 15:08:39
端末がある状況による。
ケースバイケース
821名無しさん@お腹いっぱい。:2005/10/22(土) 15:16:28
そもそもそんなに重要な作業してるなら後ろから覗かせるなと。
822名無しさん@お腹いっぱい。:2005/10/22(土) 16:20:11
もちろん、後ろから覗かせない(部屋に他人を入れない)上で、
さらに何重にも対策するという意味だろ。

物理的に覗かなくても、xauthをクラックして
画面ごとキャプチャーすることもできるわけだし、
余分な情報をプロンプト表示しないに越したことはない。
823名無しさん@お腹いっぱい。:2005/10/22(土) 16:27:48
好きなだけセキュアにしたつもりになってくれ。スレ違いなのでどっかよそで。
824名無しさん@お腹いっぱい。:2005/10/22(土) 17:13:58
>>821 >>823
普段から当たり前のように
カレントディレクトリ、ホスト名、ユーザー名を表示している人が、
弱点を指摘されて暴れてますな。

まあ、必要な時だけ pwd hostname whoami コマンドを打って
確認するのが由緒ある sh の使い方なわけだが。
825名無しさん@お腹いっぱい。:2005/10/22(土) 17:55:37
Xがのっとられてる状態ならキーボード入力ものっとられるような。
826名無しさん@お腹いっぱい。:2005/10/22(土) 18:25:24
シュルの環境の話はよそでやってくれ。
827名無しさん@お腹いっぱい。:2005/10/22(土) 18:55:04
シェルの環境の話はここでやってくれ?
828名無しさん@お腹いっぱい。:2005/10/22(土) 19:10:12
シェルシェルエンジェル
829名無しさん@お腹いっぱい。:2005/10/22(土) 20:26:12
今度シェルを始めようかと思うのですが、
調べてみるとシェルにもいろいろなディストリがあって
初心者には今一ピンと来ません。
まず最初はどのシェルから始めたらいいでしょうか?
できればフリーのものがいいです。
830名無しさん@お腹いっぱい。:2005/10/22(土) 20:32:30
餌の練り方が足りません。
831名無しさん@お腹いっぱい。:2005/10/22(土) 20:51:28
初めてのシェルというならcshだな。
あれで様々な恥辱を味わってこそそれ以外のシェルのありがたさが分かるというもの。
一行で掛けない構文の数々。かといって複数行にすると使いづらいインターフェース。

次はbashだな。あの遅さ、互換性のなさ、GNUっていうディストリビューションに
あぐらを組んだ最低さ。一度は味わっておくべきだ。ついでにGNU patchとGNU ispellも
味わっておくといいぞ。えもいわれぬ味わいだ。

そうやって用意ができたらいよいよshだな。リモートで動かしてコマンド実行すると.profileすら
読んでくれない潔さ。シェル中のsh。その分高速だ。思う存分重い.profileを書いてくれ。

そこから先は好き好きに最近の高機能なsh系列のシェルをどうぞ。
832名無しさん@お腹いっぱい。:2005/10/22(土) 20:56:49
む、なんか俺の歴史を語られているような...
いまとなってはIRIXではじめてさわったtcshがしみじみ懐かしいなぁ。
833名無しさん@お腹いっぱい。:2005/10/22(土) 21:03:34
僕は初めて使ったシェルがktermです。
実は今でもkterm使ってます。
フリーだし、日本語にも対応してるので不便はありません。
友達は「何とかターム」とかいう有料のを使ってるようですが、
別にTCP/IPとかシリアル機能は要らないので、
ktermだけで十分だと思います。
834名無しさん@お腹いっぱい。:2005/10/22(土) 21:05:49
餌の練り方が足りません。
835名無しさん@お腹いっぱい。:2005/10/22(土) 21:08:08
その3になってから激しくレベルの低いもので占められるようになったなあ。
836名無しさん@お腹いっぱい。:2005/10/22(土) 22:28:18
みなさーん、>>835がレベルの高い餌をまいてくれるそうですよー
837名無しさん@お腹いっぱい。:2005/10/22(土) 22:39:31
レベルの高い餌撒かれても836にはいて欲しくない
838名無しさん@お腹いっぱい。:2005/10/22(土) 23:52:39
819はそんなに恥ずかしかったのか。
839名無しさん@お腹いっぱい。:2005/10/23(日) 03:45:55
>>793
[は外部コマンドなので効率が悪いので書き直しなさい。
840名無しさん@お腹いっぱい。:2005/10/23(日) 06:09:41
ええと、 [[ でいいんでしたっけ。
841名無しさん@お腹いっぱい。:2005/10/23(日) 07:04:36
まさかイマドキ [ は内部コマンドだろうと思って
念のため手元の環境で試してみたら、
何と外部コマンドですた(泣)・・

$ which [
/bin/[

しかも、[[ はインストールすらされていません(泣)・・

$ which [[
which: no [[ in (/usr/local/bin:/usr/bin:/bin)


やっぱり、bashとか入れなきゃダメでしょうか?
842名無しさん@お腹いっぱい。:2005/10/23(日) 07:06:04
>>839みたいな妄言は無視しておけばよろしい。
843名無しさん@お腹いっぱい。:2005/10/23(日) 10:34:18
>>841 につっこんだら負けだと思ってる
844名無しさん@お腹いっぱい。:2005/10/23(日) 10:41:54
>843
ぶはは。おれも思ってる。く〜。
845名無しさん@お腹いっぱい。:2005/10/23(日) 10:58:12
おれもおれも
846名無しさん@お腹いっぱい。:2005/10/23(日) 11:00:30
>>791
よくわからんけど、cp -lでとりあえずコピーしてからfindで
シンボリックリンクを探してコピーし直せばいいんじゃないの?
847名無しさん@お腹いっぱい。:2005/10/23(日) 11:19:23
最近このスレに限らず、使い古されたネタを必死に書き込む哀れな奴が居るよね。
848名無しさん@お腹いっぱい。:2005/10/23(日) 17:35:32
シェルで、漢字のファイル名の表示ができなくなりました。

[root@localhost root]# type 新規ファイル.txt
type: 新規ファイル.txt: not found

となります。ググると、シェルではカレントディレクトリには ./ を付ける、
と出てきましたが、type ./新規ファイル.txt でも同じエラーです。

vi だと開くようですが、初心者なのでviの終了方法がわからず、
killして終了するとテラタームがハングします。

どうすればいいでしょうか?
849名無しさん@お腹いっぱい。:2005/10/23(日) 17:38:02
できてたのは別なOSでは。
850名無しさん@お腹いっぱい。:2005/10/23(日) 17:43:22
かなり練った釣りでは。

type を使うところなんか(・∀・)イイ!!感じ。
851名無しさん@お腹いっぱい。:2005/10/23(日) 22:13:56
edlin と ed ってどっちがすごいの?
852名無しさん@お腹いっぱい。:2005/10/23(日) 22:15:28
ざわ…ざわ…
853名無しさん@お腹いっぱい。:2005/10/23(日) 22:38:56
CP/Mのedはバッチファイル(submit)の中で使えたが、
MS-DOSのedlinがバッチファイルの中で使えないのには驚いた。
なにしろ、 a コマンドで入力を始めたら、^Zを入力しない限り入力モードから
抜けられないんだから。
当時のUNIXを知らないわけではなかっただろうに。
とても MS-DOSが普及するとは思えなかった。
854名無しさん@お腹いっぱい。:2005/10/24(月) 10:26:41
bashでインクリメントをきれいにやる方法はないのでしょうか?

i=`expr $i + 1`
echo "$i"
i=`expr $i + 1`
echo "$i"
i=`expr $i + 1`
echo "$i"

のようになるのを計算と表示を一行でやりたいんです。
855ヽ(´ー`)ノ ◆.ogCuANUcE :2005/10/24(月) 10:30:54
> きれいにやる方法
そんなものは主観的な問題なので、誰にでも分かる言葉で説明した方が良い。

echo $((i++))
echo $((i++))
echo $((i++))

つか、これでいいの?
856854:2005/10/24(月) 10:38:13
>>855
即答ありがとうございます!!
というか、「一行でやりたいんです」=「きれいに」と
いう主観の具体化を示してるんですが伝わらなかったでしょうかーー;
何はともあれ、ありがとうございました!!
857名無しさん@お腹いっぱい。:2005/10/24(月) 14:42:44
>>854
for ((i=0;i<3;i++)); do echo $i; done;
こういうことかな。
858名無しさん@お腹いっぱい。:2005/10/24(月) 14:59:56
シェルスクリプトをきれいに書こうと思うのが間違い。
859名無しさん@お腹いっぱい。:2005/10/24(月) 15:19:11
コマンドを実行した時間を取得したいので、.profileに

echo "% \c"
while read line
do
echo "`date +'%m/%d %H:%M:%S'`\t$line" >> $HOME/history.log
eval $line
echo "% \c"
done

を入れてみたのですが、.sh_historyに書き込まれないし、
set -o viが効かずに何も出てきません。
echo "$line" >> .sh_historyを入れたら、.sh_historyそのものもおかしくなってしまいました。
何かいい方法はありますでしょうか。
860ヽ(´ー`)ノ ◆.ogCuANUcE :2005/10/24(月) 15:30:44
>>859
script じゃ駄目かね。-t でタイミングデータも取れるぞ。
861& ◆w8Mu0zR9T2 :2005/10/24(月) 16:02:11
>>860
回答ありがとうございます。
kshなので、-tはありませんでした。
scriptコマンドとプロンプトにdateを入れればできそうですが、
ログが大きくなりそうなこと、exitが2回必要なことがネックになりそうです。
セキュリティ強化の一環で、コマンドの実行開始時間一覧が取得できればそれでいいのですが。
862859:2005/10/24(月) 16:24:56
あれ?変なトリップが・・・
理想の出力は、
10/24 16:10:20 hostname user ls
10/24 16:10:30 hostname user date
10/24 16:10:40 hostname user exit
みたいな感じです
863名無しさん@お腹いっぱい。:2005/10/24(月) 16:38:17
cshにして set savehist=999
864859:2005/10/24(月) 17:57:23
>>863
cshには変えられません。
865名無しさん@お腹いっぱい。:2005/10/24(月) 18:05:55
ヒストリ取ったぐらいでセキュリティ対策になると思っているのであれば、
それは間違いだ。
866名無しさん@お腹いっぱい。:2005/10/24(月) 18:27:09
>>859 >>864
「cshには変えられません」(←その考え自体は正解)と言ってる割りに、
echo "% \c" で、なぜプロンプトを % にするの?
あと、-eオプション無しで \c してるけど、ということは
OSはSolarisかな?

いずれにしても、そのシェルもどきラッパースクリプト中で
sh を起動されたら終り。
で、許可コマンド名をチェックするのかな?
それでも、viとかmoreとか、多くのコマンドで
シェルエスケープできるから、それでコマンド監視しようとするのは無理。
867名無しさん@お腹いっぱい。:2005/10/24(月) 18:34:12
>>859
アカウンティングという機能が大抵のUNIX系のOSにある。
あなたが求めているのはおそらくそれ。
868859:2005/10/24(月) 19:09:45
>>866
OSはAIX5.2です。プロンプトは、単に$以外にしてみただけで、本番ではPS1と同じにする予定です。
>>865の指摘どおりですが、セキュリティ対策というよりは、
何か誤操作をしたときに、いつ何のコマンドを実行したかを確認するためという意味合いが強いです。
厳密にする必要はないです。
>>867
アカウンティングで検索したら、saコマンドがヒットしました。
これを使うのでしょうか。
869名無しさん@お腹いっぱい。:2005/10/25(火) 00:30:52
あるテキストファイルの中の文字を複数同時に変換する方法を探しています。
たとえば、aをzに、sをxに、dをcに。
1文字ならsed 's/a/z/g'みたくやればできるんですが、
複数同時にってのがわかりません。わかるひと教えてください。
870名無しさん@お腹いっぱい。:2005/10/25(火) 00:34:58
>>857
うわうわ、それいいですね!
なんというキーワードで検索すれば詳しい説明にたどり着けますか?

>>869
sed -e s/a/z/g -e s/s/x/g -e s/d/c/g
871名無しさん@お腹いっぱい。:2005/10/25(火) 00:36:32
>>869
man tr
872869:2005/10/25(火) 00:51:07
>>870, 871
ありがとー。
873名無しさん@お腹いっぱい。:2005/10/25(火) 01:35:23
sed でやるにしても、せめて sed 'y/asd/zxc/' としてほしい。
874名無しさん@お腹いっぱい。:2005/10/25(火) 06:05:44
ネットワークにつながっているかを確認する、明快な(短い行数を競う必要はなし)
シェルスクリプトってありますか?
875名無しさん@お腹いっぱい。:2005/10/25(火) 06:58:07
>>870
man bashのfor
876名無しさん@お腹いっぱい。:2005/10/25(火) 07:37:28
>>874
「ネットワークにつながってる」の定義は?
877名無しさん@お腹いっぱい。:2005/10/25(火) 14:39:56
/sbin/ifconfig -a | grep UP | grep -v lo0 > /dev/null
でええんじゃない?
878名無しさん@お腹いっぱい。:2005/10/25(火) 15:04:56
>>873
環境に依存しない方法はない。そもそも、>>876 がいうように、どこからが
「ネットワークにつながってる」状態なのかも分からないし。
879名無しさん@お腹いっぱい。:2005/10/25(火) 15:07:30
すごく意味が分からないんですけど。。。

if [ -d hoge ]; then
mkdir hoge
fi

bash で上記の「hogeディレクトリが無かったら作る」が
正常に動きません。(上のスクリプトを動かすとエラーがでないで終了)
なぜでしょう?スクリプトを実行しているユーザと
ディレクトリを作ろうとしている場所のパーミッションは大丈夫です。
よろしくお願いします。
880名無しさん@お腹いっぱい。:2005/10/25(火) 15:09:39
hogeディレクトリを作ってから動かしてみれば原因がわかるカモ
881名無しさん@お腹いっぱい。:2005/10/25(火) 15:18:25
アッホ!!ごめんなさい。。。(;´ω`)

if [ ! -d hoge ]; then
mkdir hoge
fi

でした_| ̄|○
なんで『あったら』が『なかったら』に
脳内変換されてたのか。。。・゜・(ノд`)・゜・
882名無しさん@お腹いっぱい。:2005/10/25(火) 15:42:25
>881
かわいい
883名無しさん@お腹いっぱい。:2005/10/25(火) 15:53:16
あざとい。
884名無しさん@お腹いっぱい。:2005/10/25(火) 16:40:15
>>881
たんに
mkdir hoge
でなぜいけないの?
885名無しさん@お腹いっぱい。:2005/10/25(火) 17:06:30
hogeというファイルが合った場合に困る
886名無しさん@お腹いっぱい。:2005/10/25(火) 17:20:19
いや状況は変わらんだろ
887名無しさん@お腹いっぱい。:2005/10/25(火) 17:27:40
>>886
$ touch hoge
$ mkdir hoge
$ mv foo/bar hoge
888名無しさん@お腹いっぱい。:2005/10/25(火) 17:38:29
どうも判ってないようだな。
if [ ! -d hoge ]; then
  mkdir hoge
fi

mkdir hoge
は実質変わらんと言っている。
889名無しさん@お腹いっぱい。:2005/10/25(火) 17:39:39
違いはエラーの出方くらいだな。
890名無しさん@お腹いっぱい。:2005/10/25(火) 17:44:59
>>888
げらげら
891名無しさん@お腹いっぱい。:2005/10/25(火) 18:41:50
mkdir -p hoge を知っていて損はない。
892名無しさん@お腹いっぱい。:2005/10/25(火) 19:00:24
>>888
test -d hoge → mkdir hoge
はアトミックじゃないしな。
そのチェック、マジで無意味。

エラーメッセージがウザいんなら、/dev/nullに捨てればいいだけだし。
893名無しさん@お腹いっぱい。:2005/10/25(火) 19:51:00
さて、また公衆オナニーが始まりましたよw
894名無しさん@お腹いっぱい。:2005/10/25(火) 20:30:19
完全にアトミックな動作を求めると
ほとんどのシェルスクリプトがアウトになるのでは。
895名無しさん@お腹いっぱい。:2005/10/25(火) 20:34:58
んなもんシェルスクリプトに求めるな
896名無しさん@お腹いっぱい。:2005/10/25(火) 21:10:20
所詮は殻。
核じゃなくちゃ原子力は使えんということだら。
897名無しさん@お腹いっぱい。:2005/10/25(火) 21:15:11
>>896
つ座布団一枚
898名無しさん@お腹いっぱい。:2005/10/25(火) 21:20:57
俺は普通

if [ -d hoge ]; then
rm -fr hoge
fi
mkdir hoge
899名無しさん@お腹いっぱい。:2005/10/25(火) 21:52:17
>888
その通り。等しく動作するかどうかみたいなテストならあんたが正解。
暗記問題とか得意そうだね。

しかし、881がエラー処理をやるつもりでifを書いたか可能性もあるわけ。
それを短絡してmkdir hogeってやればエラーがでるだけで問題ないんだぜ〜
ってのは不正解。そこらへんは881がやりたいようにやらしときゃいいの。
俺らがでしゃばっても見苦しいだけ。
900名無しさん@お腹いっぱい。:2005/10/25(火) 22:21:49
>>899
mkdir 2>/dev/null || エラー処理
で問題無いのでは?
901名無しさん@お腹いっぱい。:2005/10/25(火) 22:33:22
まとめ。

単に「ディレクトリがなければ作る」ならば、
mkdir dir 2> /dev/null よりも、
mkdir -p dir のほうが美しい。
が、mkdir -p dir では終了ステータスが常に真になる。

終了ステータスが必要な場合、つまり、
mkdirの際に、既にディレクトリが存在していたかどうかで
場合分けする必要がある場合は、

if mkdir dir 2> /dev/null; then
echo ディレクトリは新規作成された
else
echo ディレクトリは既に存在していた
fi
でよい。

いずれにしても、[ -d dir ] のチェックは無駄。
902名無しさん@お腹いっぱい。:2005/10/25(火) 22:34:12
>900
mkdir hoge→お宅のスクリプト実行
touch hoge→お宅のスクリプト実行
rm -rf hoge→お宅のスクリプト実行

ってなテストをしてどれでも正しく動けばそれでいいんじゃねーかな。
903名無しさん@お腹いっぱい。:2005/10/25(火) 22:37:43
899が一番馬鹿っぽい
904名無しさん@お腹いっぱい。:2005/10/25(火) 22:40:00
>>902
いやだから、それならなおのこと
test -d hoge
じゃだめでしょ。
ディレクトリではないhogeというファイルが存在している場合のことを
考えてないんだから。
ちゃんと問題を分かってる?
905名無しさん@お腹いっぱい。:2005/10/25(火) 22:42:25
>>901
if mkdir ...って、それ何シェルですか?
shなら if [ ... ] ですよね?
さっぱり意味が解りません、
解説お願いしてよろしいでしょうか?
906名無しさん@お腹いっぱい。:2005/10/25(火) 22:42:49
バカ発見
907名無しさん@お腹いっぱい。:2005/10/25(火) 22:44:41
今へをした。ニンニク食ったから臭かった。
908名無しさん@お腹いっぱい。:2005/10/25(火) 22:45:09
と思ったら上手が現れたw
909名無しさん@お腹いっぱい。:2005/10/25(火) 22:47:03
>905
if コマンド; thenってのが構文です。
if [ ...]; thenってのは、[ってコマンドを実行するという意味です。
で、[ってコマンドが今では内部コマンドになったと。
910名無しさん@お腹いっぱい。:2005/10/25(火) 22:53:16
>904
別に最初の人が-dしかテストしてなかったからといって、
ファイルが合った場合について考えちゃいけないこたあないでしょ。

ファイルがあったらどうなる?→ああエラー処理でファイルがある場合も考えなきゃいけないんだ
みたいな流れで誘導できれば万々歳だよね。特に元々-dとかやってみてたわけで、
そっから-eにするとか幾らでも流れていけるわけ。

まあ、元々の文面だけを捉えてそれで-dするならmkdir -pでいいじゃんかってのも
一つの答えだろうけどさ、他にも答えは幾らでもあるぞと。そういうこと。
911名無しさん@お腹いっぱい。:2005/10/25(火) 22:55:26
>>910
「ディレクトリを(新しく)作れるかどうか」をもっとも簡便、確実
にテストし、かつアトミックに作成できるコマンドがmkdirなのに、
わざわざ他の手段をすすめるのはなぜ?

やっちゃいかんとは言わないけど、まさに無駄でしかないよ。
912名無しさん@お腹いっぱい。:2005/10/25(火) 22:56:27
>>879
が置いてきぼりになっている予感。
913名無しさん@お腹いっぱい。:2005/10/25(火) 22:56:30
3スレを通じて、もっともバカ >>905
914名無しさん@お腹いっぱい。:2005/10/25(火) 23:03:01
3スレ通じて最もバカというなら、
「3>&1」や「3<&1」の意味を根底から間違えて覚えていた
>>662 が最もバカ。
915名無しさん@お腹いっぱい。:2005/10/25(火) 23:03:37
916名無しさん@お腹いっぱい。:2005/10/25(火) 23:06:56
905=914=最バカ
917名無しさん@お腹いっぱい。:2005/10/25(火) 23:09:50
>911
別にどっちでもいいんじゃん?

ディレクトリを作って作れなかったらエラー表示だけってんなら
mkdir hoge 2>... || echo errorとかでもいいかもね。

大抵は終了とかしたいわけで
if mkdir hoge 2>...; then else echo error; exit; fi
みたいになるっしょ。

ディレクトリをどうしても作るってタイプのエラー処理なら
if [ -e hoge ]; then rm -rf hoge; fi
mkdir hoge
みたいなエラー処理しかないだろうし。

>912
すまんこ。885でやめときゃよかったかな。
でもでしゃばらないでいようと思いつつ、ついついw

>914
NetBSDのman shでも"[n1]>&n2 Duplicate standard output (or n1) to n2."
とかいってるし、間違えるのはしょうがないかなあと。
918名無しさん@お腹いっぱい。:2005/10/25(火) 23:16:12
>>917
>NetBSDのman shでも"[n1]>&n2 Duplicate standard output (or n1) to n2."
マジ?
"[n1]>&n2 Duplicate n2 to standard output (or n1)."
が正しいよね。
919名無しさん@お腹いっぱい。:2005/10/25(火) 23:17:47
というか>>885で少しずれたことを書くから流れが変になった。
別個の問題なのに。
920名無しさん@お腹いっぱい。:2005/10/25(火) 23:18:39
俺ん家のFreeBSDのman shもそうなってるな。
921名無しさん@お腹いっぱい。:2005/10/25(火) 23:20:18
>919
>910
922名無しさん@お腹いっぱい。:2005/10/25(火) 23:26:57
>>920
send-pr汁!

mah shで、n1>&n2 とかの記述が正しいのは
(俺が確認した限りでは)SolarisとLinuxだけか。
あ、Linuxはman bashだけど。
923名無しさん@お腹いっぱい。:2005/10/25(火) 23:27:54
>>917
こういう書き方もある事は知ってるか?

mkdir hoge 2> ... || { echo error; exit; }

後、ディレクトリ作成を最優先するのなら
それこそ if 文は無駄だ。

rm -rf hoge
mkdir hoge
924名無しさん@お腹いっぱい。:2005/10/25(火) 23:28:39
>>910は拡大解釈でしかないと思う。
[-d hoge]でテストしているコードに対して、それはまるっきり無駄であり
mkdirを素直に使え、という直截的なツッコミに対して、
「ファイルがあると困る」ってのは、ハァ?だよ。
いつのまにか彼の脳内には別の仕様とコードがあった訳だ。

結局、>>917で彼は最初にtestする例を一例あげたに過ぎず、大概の
ケースではmkdirを使うのが自然であることを認めている。
その一例にしたって、
mkdir hoge || rm -fr; mkdir hoge
でいいんだけどな。
925924:2005/10/25(火) 23:30:39
ごめん最後の例わやくちゃ。まあいいや。
926名無しさん@お腹いっぱい。:2005/10/25(火) 23:50:24
おお、{ }なんて構文があるのか、最近のshって便利だなあ。
とか言って実は昔からあるとなったら恥ずかしいゾ。

>924
ま、そのとおり。

>923
>rm -rf hoge
>mkdir hoge

わはは。手加減ないな。やる内容は別にrm -rfに限るわけじゃないのにな。
927名無しさん@お腹いっぱい。:2005/10/25(火) 23:53:51
{ }は結構昔からあるが…
928名無しさん@お腹いっぱい。:2005/10/26(水) 00:00:29
思考の制御フローを自然に記述できればなんでもいいよ
おれは事前テストするほうが読み(書き)やすいけど
処理が無駄とかアトミックがどうとかも必要なければ考えたくない
いろんな方法を知っていて、適切に選択できることが重要
条件が未定義なのに議論しても不毛だしね
929名無しさん@お腹いっぱい。:2005/10/26(水) 00:04:24
では、上手くまとまったところで次のネタどーぞ
930名無しさん@お腹いっぱい。:2005/10/26(水) 02:09:00
なむw

$ cvs log sh.1
----------------------------
revision 1.53
date: 2002/12/12 11:50:40; author: uebayasi; state: Exp; lines: +2 -2
`` [n1]>&n2 Duplicate standard output (or n1) _TO_ n2.''
931名無しさん@お腹いっぱい。:2005/10/26(水) 07:11:13
>>930
げっ。それって、2002年にわざわざ間違った修正を加えたってこと?
それを言うなら、
`` [n1]>&n2 Duplicate standard output (or n1) _FROM_ n2.''
だよね。でもこれだと解りにくいから、
" [n1]>&n2 Duplicate n2 to standard output (or n1). "
を希盆。

百歩譲って原文を生かすとしたら、DuplicateじゃなくてRedirectだな。
"[n1]>&n2 Redirect standard output (or n1) to n2."
なら間違いではない。
でもやっぱり、
" [n1]>&n2 Duplicate n2 to standard output (or n1). "
を希盆。
932名無しさん@お腹いっぱい。:2005/10/26(水) 14:29:49
俺は複製よりリダイレクトの方がピンとくるな
933名無しさん@お腹いっぱい。:2005/10/26(水) 15:11:52
>>909
ついこの間リリースされた Minix 3 では [ は外部コマンドでした。
[ は外部コマンドゆえに効率が異常に悪いので使うのは控えてくださいね。
934名無しさん@お腹いっぱい。:2005/10/26(水) 15:17:45
人間の頭では表面上はリダイレクトで考えてるけど、
シェル内部ではファイル記述子の複製になっている。
しかも、リダイレクトと複製では方向が正反対というのが
混乱の原因だな。

しかし、ちゃんと「複製」で理解しておかないと、
例の、
make > make.log 2>&1
の意味が正しく理解できない。

>>3 でリンクされてる「自習テキスト」とやらは、
ファイル記述子の複製を理解していなくて、
しかも、それだと方向が逆になるから、
make > make.log 2>&1 のリダイレクトの実行順番を
「右から左(2>&1が先で >make.logが次)」に行なわれるといった、
勝手なつじつま合わせの間違った解釈をしている。

実際には、「左から右( >make.logが先で2>&1が次」に行なわれるのだから、
これを理解するには複製(duplicate)とはっきり書かないといけない。

よって、
[n1]>&n2 Duplicate n2 to standard output (or n1). が正しい。
935名無しさん@お腹いっぱい。:2005/10/26(水) 15:35:37
ということで、3スレ通して最も馬鹿な記述は、
>>721 がコピペしてくれた
*誤った*リダイレクトの解説文章だな。

(>>721 自身は指摘した人だから馬鹿じゃないよ)
936名無しさん@お腹いっぱい。:2005/10/26(水) 23:52:17
>>930
皿仕上げ。

revision 1.52では、
[n1]>&n2 Duplicate standard output (or n1) from n2.
と正しく記述されていた。

revision 1.53のcommitが間違い。
なんで to に直すのよ?
「標準出力(またはn1)を、n2からの複製とする」
(つまり、「n2を複製して標準出力(またはn1)とする」)
で合っていたんだよ。直すなよ。

俺、NetBSDの関係者じゃないけど、こういうのどこに言えば直してもらえるの?
revision 1.53のcommitを即刻取り消すべきだと思う。
937名無しさん@お腹いっぱい。:2005/10/26(水) 23:57:27
嬉しそうだな。
938名無しさん@お腹いっぱい。:2005/10/27(木) 01:45:04
939名無しさん@お腹いっぱい。:2005/10/27(木) 08:06:20
shの 1>&2 とかの仕様って、shが出来た時から変わっていないわけだから、
仮にman shが間違っていたとしても(←実際には間違っていない)、
その間違いに2002年になるまで誰も気づかないわけがない。

だから、2002年になって、自分が「man shが間違いだ」と思ったとしても、
そう思った自分が間違っている可能性が高いことに気づくべき。

気づいていたらこんな en-bug commitはしなかったはず。

間違いがcommitされても、こんな基本的なことならすぐに誰かから指摘されるはず。

あ、だからこの板で指摘されたのか、、2005年になってしまったけど・・
940名無しさん@お腹いっぱい。:2005/10/27(木) 17:42:09
>>938
そいつは日本語ドキュメント作成で忙しいからだめ。
941名無しさん@お腹いっぱい。:2005/10/27(木) 17:52:02
なんだ私怨か。
942名無しさん@お腹いっぱい。:2005/10/28(金) 02:07:02
>>941
口先だけで何もしない奴は叩かれて当然
943名無しさん@お腹いっぱい。:2005/10/28(金) 04:33:44
亀レス
>>63の問題は解決したんだろうか

yes -n | head -n 1
というのを思いついた.
944名無しさん@お腹いっぱい。:2005/10/28(金) 09:22:36
echo -n "$message"'\n'
945名無しさん@お腹いっぱい。:2005/10/29(土) 01:29:50
946名無しさん@お腹いっぱい。:2005/10/29(土) 07:38:15
>>655 はガセネタなわけだが。
messageが-nだけの場合に動作しない。
しかも、>>655 が書いている通りにもならない。

bashでも、
$ message="-n nullpo"
なら、
$ echo "$message"
は、
-n nullpo
になるし、

そもそも、
$ echo "$message"

$ echo ''"$message"
は、全く等価。
頭に''を付けても意味なし。よって未解決。
947名無しさん@お腹いっぱい。:2005/10/29(土) 09:20:49
とりあえずでてないの
cat << EOF
$message
EOF
つーか63の目的が不明だからどうしようもないゆ
948名無しさん@お腹いっぱい。:2005/10/29(土) 19:58:32
まだ学生だった頃(8年前)に使ってたSolaris2.6にはyesはなかった気が。
(自分で while :;do echo $1 ; done というスクリプトを置いてた。)
第一引数しか繰り返さないyesも使った記憶がある。

とりあえず、expr -- "$message" てのは?
949名無しさん@お腹いっぱい。:2005/10/29(土) 20:02:37
このネタはもういいよ。
950名無しさん@お腹いっぱい。:2005/10/29(土) 21:14:16
よくないよ
徹底的にやるべき
951名無しさん@お腹いっぱい。:2005/10/29(土) 21:36:29
シェルスクリプトでできたメガデモってないの?
952名無しさん@お腹いっぱい。:2005/10/29(土) 22:02:54
メガが埋まるまでシェルスクリプトを書くのも大変だなあ。
今迄書いたシェルスクリプト全部合わせてもメガに届くだろうか……
953名無しさん@お腹いっぱい。:2005/10/29(土) 22:53:21
dateで1日前の日付を出力する方法を教えてください。
954名無しさん@お腹いっぱい。:2005/10/29(土) 23:00:08
manを読め。
955名無しさん@お腹いっぱい。:2005/10/29(土) 23:06:50
>>953
date --date '1 day ago' # with GNU date
or
TZ=JST+15 date

>>63
How about:
$ date +-n
-n
$ message='-n foo bar'
$ date +"$message"
-n foo bar
This is useful if the variable "$message" contains no percents(%).
956名無しさん@お腹いっぱい。:2005/10/29(土) 23:32:47
>>955
HPUXってそれできないんだよねぇ
TZをいじくるとか
957名無しさん@お腹いっぱい。:2005/10/29(土) 23:37:54
>>955
No, date + has less advantage than what printf '%s\n' has.
Scence >>63 says he won't use printf, the echo -n problem is still unsolved.
958名無しさん@お腹いっぱい。:2005/10/30(日) 01:04:29
Since の間違い?
959名無しさん@お腹いっぱい。:2005/10/30(日) 01:42:57
>>957 -nを出力できないechoを使って-nを出力したいという問題は解決しません、
960名無しさん@お腹いっぱい。:2005/10/30(日) 20:11:54
a=`a | b | c | d`

と変数の代入時に複数のコマンドを
パイプでつないでいる時にパイプ内のどこかで
エラーが出たら以降の処理を中断(exit)したいのです。

a=` { a | b | c | d; } > err.txt 2>&1`
if [ -s "err.txt" ] ; then exit; fi

これ以外の、ファイルを出力しない方法はありますか?
961名無しさん@お腹いっぱい。:2005/10/30(日) 20:44:21
set -e
962名無しさん@お腹いっぱい。:2005/10/30(日) 21:23:33
>>961
あ、それが一番簡単でいいですね。

では、即座に終了ではなく、何らかのエラー処理を
したい場合はどんな方法がありますか?
963名無しさん@お腹いっぱい。:2005/10/30(日) 21:27:02
自分で考える。
964名無しさん@お腹いっぱい。:2005/10/30(日) 22:34:16
>>962

if a=`set -e; a | b | c | d`
then
 正常終了
else
 何らかのエラー処理
fi
965名無しさん@お腹いっぱい。:2005/10/31(月) 01:08:53
「目的」全ての行の改行コードを LF -> CR+LF へ変換、
改行コードを含むバイト数を揃えて、最終行はEOF単独行としたい

abc
def
ghi

というデータのファイルがあります。改行コードはLFです。
このファイルの改行コードをCR+LFにしたいのです。

フツーに変換するだけなら、sed -e 's/$/^M/' とかでいいんですが、
最終行のghiの i の次がEOFだった場合、
つまり、ファイルの最後が改行以外の文字だった場合、
上のsedのヤツだと最終行が ghi^M となってしまいます。
iのうしろに改行コードがあってもなくても、ファイルはCR+LFで終わって欲しいのです。

使用したい環境にはnkfもperlも無いので、
sed や tr だけでできる方法を調べていますが、なかなかうまくいきません。
オシャレな解決方法をご存知の方、教えてください。
966名無しさん@お腹いっぱい。:2005/10/31(月) 01:15:49
awk 1 ORS='\r\n'
967名無しさん@お腹いっぱい。:2005/10/31(月) 01:27:32
>>965
echo '' >> file
sed -e 's/$/^M/'

オサレとは言えないが。
968名無しさん@お腹いっぱい。:2005/10/31(月) 02:58:56
sed -e 's/$/\r/; $ s/$/\n/' file  | tr -s '\012'
tr は最終行のためだけに必要という…
969名無しさん@お腹いっぱい。:2005/10/31(月) 03:17:21
$ ed a.txt << EOF
%s/$/^M
wq
EOF
970名無しさん@お腹いっぱい。:2005/10/31(月) 04:27:11
>>965
freebsdのsedはそれで問題ないんだけど、
どこのsedなのかぜひ知りたい。
疑ってるわけじゃなくて、たんなる情報として。
971名無しさん@お腹いっぱい。:2005/10/31(月) 15:29:22
確かHP-UXのsedはLFで終わってない行は>>965みたいな動作になった気がするな。
972名無しさん@お腹いっぱい。:2005/10/31(月) 15:41:01
確かSolarisのsedはLFで終っていない行はその行自体が無視された気がするな。
973名無しさん@お腹いっぱい。:2005/10/31(月) 17:12:44
awkは入ってないの?
974名無しさん@お腹いっぱい。:2005/10/31(月) 17:25:18
確か>>973のカキコは>>973みたいな流れが読めてない動作になった気がするな。
975名無しさん@お腹いっぱい。:2005/10/31(月) 17:29:39
GNU sed は >>965 と同じ挙動をするが、GNU ed はよしなに扱ってくれる。
統一されてないのか。
976965:2005/10/31(月) 23:48:29
みなさん。いろいろありがとう。
>>966でいけました。(実際に使ったのはgawk)

>>967
最初それ考えました。
ただ、パイプで渡ってきた文字列を処理するときに、一時ファイルがいりますよね。

>>968>>969
これらもOKでした。tr の -s や ed って、こう使うんですね。

>>970
ごめんなさい、現場のヤツなんで、また調べてきます。
手元のcygwinのsed (GNU sed) も>>965同じ動きですね。


ちなみに元ネタは、fold -60 で切ったときに、
バイト数がちょうど60の倍数のバイトだと、
EOFの前が改行にならない、というものでした。

勉強になりました。
977名無しさん@お腹いっぱい。:2005/11/02(水) 18:37:48
「シェルスクリプトで出来ないことを語る」で板を立てようとしたら規制されて立てられなかった。
賛同する方立てて下さい。

1の本文は
出来ないことをいつまでも考えるな。時間と金の無駄使いだ。
978名無しさん@お腹いっぱい。:2005/11/02(水) 19:31:55
そんなスレいらない。
979名無しさん@お腹いっぱい。:2005/11/02(水) 19:51:30
>>977
出来ないことをいつまでも考えるな。時間と金の無駄使いだ。
980名無しさん@お腹いっぱい。:2005/11/03(木) 02:59:58
>>979 に座布団一枚
981名無しさん@お腹いっぱい。:2005/11/03(木) 03:20:37
FreeBSDはうんこ過ぎて触る気がしない
982名無しさん@お腹いっぱい。:2005/11/04(金) 01:28:27
なんだ次スレ立ってるじゃん

シェルスクリプト総合 その4
http://pc8.2ch.net/test/read.cgi/unix/1131026501/l50
983名無しさん@お腹いっぱい。:2005/11/04(金) 09:12:25
>>981がウンコすぎてレスする気にならない
984名無しさん@お腹いっぱい。:2005/11/04(金) 15:18:05
してるじゃん
985名無しさん@お腹いっぱい。:2005/11/05(土) 10:40:38
hoshu
986名無しさん@お腹いっぱい。:2005/11/05(土) 17:39:42
987名無しさん@お腹いっぱい。:2005/11/05(土) 18:20:11
988名無しさん@お腹いっぱい。:2005/11/05(土) 18:41:35
  _   ∩
( ゚∀゚)彡
 ⊂彡
989名無しさん@お腹いっぱい。:2005/11/05(土) 21:49:37
#!/bin/sh
990名無しさん@お腹いっぱい。:2005/11/05(土) 22:41:30
びんしゅ
991名無しさん@お腹いっぱい。:2005/11/05(土) 22:49:14
hoge
992名無しさん@お腹いっぱい。:2005/11/06(日) 00:37:16
ちんここちんこちん
993名無しさん@お腹いっぱい。:2005/11/06(日) 03:11:50
ls
994名無しさん@お腹いっぱい。:2005/11/06(日) 09:29:37
次スレ↓
C shell 撲滅委員会
http://pc8.2ch.net/test/read.cgi/unix/1094041299/l50
995名無しさん@お腹いっぱい。:2005/11/06(日) 09:47:05
995
996名無しさん@お腹いっぱい。:2005/11/06(日) 09:47:59
シェルスクリプト総合 その4
http://pc8.2ch.net/test/read.cgi/unix/1131026501/l50
997名無しさん@お腹いっぱい。:2005/11/06(日) 09:55:49
↓お次はこちら
【tc厨が】bash3.0登場!!【嫉妬する】
http://pc8.2ch.net/test/read.cgi/unix/1095753421/l50
998名無しさん@お腹いっぱい。:2005/11/06(日) 10:12:20
998
999名無しさん@お腹いっぱい。:2005/11/06(日) 10:12:32
999
1000名無しさん@お腹いっぱい。:2005/11/06(日) 10:12:47
1000
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。