1 :名無しさん@お腹いっぱい。2010/11/20(土) 08:29:39
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。

□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashなので特に注意。
 FreeBSDユーザは/bin/shの正体がashなので注意。
 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。
  http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
  http://heirloom.sourceforge.net/sh.html
・csh/tcshのシェルスクリプトは推奨されません。
 (理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
 manや参考リンクを見ましょう。
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。

前スレ
シェルスクリプト総合 その16
http://hibari.2ch.net/test/read.cgi/unix/1266642605/
7 :名無しさん@お腹いっぱい。2010/11/20(土) 14:37:39
exec >>1乙
98 :名無しさん@お腹いっぱい。2010/12/27(月) 12:56:09
>>1嫁。勝手に制限を加えるな。
159 :名無しさん@お腹いっぱい。2011/01/10(月) 16:48:44
>>158
-d

>>1
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)
2 :名無しさん@お腹いっぱい。2010/11/20(土) 08:34:51
□関連スレ:
sed
http://hibari.2ch.net/test/read.cgi/unix/1085730992/
正規表現
http://hibari.2ch.net/test/read.cgi/unix/1039165754/
おまえら! shell は何を使っているんですか?
http://hibari.2ch.net/test/read.cgi/unix/1012330865/
Eshell の使い方とか設定とか【Emacs Shell、Lisp】
http://hibari.2ch.net/test/read.cgi/unix/1102921590/

□初心者向けリンク
「誰にでも」シリーズ
ttp://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications/dareUni/
/bin/shプログラミング入門
ttp://freebooks.info.nara-k.ac.jp/archive/ShellProgramming/
シェルを使おう - 導入からプログラミングまで -
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/
3 :名無しさん@お腹いっぱい。2010/11/20(土) 08:35:23
□参考リンク:
UNIXの部屋 (沢山のコマンドの簡単な紹介など)
http://x68000.q-e-d.net/~68user/unix/
POSIX: Shell & Utilities (標準規格)
http://www.opengroup.org/onlinepubs/009695399/utilities/contents.html

□最近のシェルスクリプト本(1)

(2004/03) UNIXシェルスクリプトハンドブック 関根 達夫 (著)
http://amazon.co.jp/o/ASIN/4797326522/
(2004/10) UNIXシェルスクリプト逆引き大全333の極意 中橋 一朗 (著)
http://amazon.co.jp/o/ASIN/4798008842/
(2004/11) 仕事に使えるLinuxシェルスクリプト 千葉 真人 (著)
http://amazon.co.jp/o/ASIN/4822282090/
(2004/12) UNIXシェルスクリプトサンプルブック デイブ・テイラー (著)
http://amazon.co.jp/o/ASIN/4797327286/
(2005/02) シェルスクリプト基本リファレンス 山森 丈範 (著)
http://amazon.co.jp/o/ASIN/4774122610/
(2005/04) LinuxWorldスクリプト 月刊リナックス・ワールド総集編 月刊LinuxWorld特別 (著)
http://amazon.co.jp/o/ASIN/4872802349/
(2005/05) UNIXシェルスクリプトコマンドブック 山下 哲典 (著)
http://amazon.co.jp/o/ASIN/4797330635/
(2005/05) わかる&使える UNIX基礎講座 シェルスクリプト編 中井 獏 (著)
http://amazon.co.jp/o/ASIN/4774123625/
4 :名無しさん@お腹いっぱい。2010/11/20(土) 08:35:37
□最近のシェルスクリプト本(2)
(2005/07) UNIX シェルスクリプト辞典 川井 義治 (著)
http://amazon.co.jp/o/ASIN/4798109231/
(2005/08) シェルスクリプト ポケットリファレンス bash編 宮原 徹 (著), 川原 龍人 (著)
http://www.amazon.co.jp/o/ASIN/4774124818/
(2005/12) 図解でわかるLinuxシェルスクリプト・正規表現 小泉 修 (著)
http://www.amazon.co.jp/o/ASIN/4534040067/
(2006/01)詳解 シェルスクリプト アーノルド ロビンス (著), ネルソン・H.F. ベーブ(著), Arnold Robbins (原著), Nelson H.F. Beebe (原著), 日向 あおい (翻訳)
http://www.amazon.co.jp/o/ASIN/4873112672/
(2007/3) Linuxシェルスクリプトユーザー便利帳―bash2/bash3対応 伊藤 幸夫 (著), 寒川 陽美(著)
http://www.amazon.co.jp/o/ASIN/4798015954/
(2007/9) ゲームで極める シェルスクリプトスーパーテクニック 山森 丈範
http://www.amazon.co.jp/o/ASIN/4774132020/
(2007/10) UNIX/Linuxシェルスクリプトマスタリングハンドブック 野川 准子
http://www.amazon.co.jp/o/ASIN/4798017957/
5 :12010/11/20(土) 08:37:45
テンプレ貼り終了。
関連スレのURL変わってたんで、付け替えますた。
6 :名無しさん@お腹いっぱい。2010/11/20(土) 09:32:01


最近本出てないのかねぇ。
まぁ新しい話題があるわけじゃないのでコンスタントに出るはずはないのだが。
9 :名無しさん@お腹いっぱい。2010/11/23(火) 17:01:26
killしたいプロセスのIDが書かれたファイルaho.txtがあります。

%cat aho.txt

123
456
789
012

このプロセスを順にkillする場合、どのようなシェルスクリプトを書いたらいいでしょうか?
10 :名無しさん@お腹いっぱい。2010/11/23(火) 17:09:59
>>9
for i in `cat aho.txt`; do kill $i; done

または

kill `cat aho.txt`
11 :名無しさん@お腹いっぱい。2010/11/23(火) 21:23:09
>>10
素早いレスありがとうございます!
12 :名無しさん@お腹いっぱい。2010/11/24(水) 00:15:20
何らかの同じ文字が連続していれば、その行を表示したいです。

AABB
ABCD
AADD
だったら AABB と AADD

grepの正規表現でそういうことはできますでしょうか?


17 :名無しさん@お腹いっぱい。2010/11/29(月) 16:00:02
いまでは古典?と言えるが、「UNIXプログラミング環境」も手元に
置いてほしい本。最近の本では、より難しいことも書かれているがこの
本の内容を知らないがために繰り返される基本的質問があまりにも多い。
18 :名無しさん@お腹いっぱい。2010/12/12(日) 07:55:55
>>17
20年近く前に自分が読んだ時点でも既に古さを感じたが、今読むとどう感じるんだろうか
逆に古さを感じないのかもね。当時は UNIX USER が創刊されたばかりで、太田純さんの
連載がシェルスクリプトとの出会いだったなあ
19 :名無しさん@お腹いっぱい。2010/12/14(火) 14:05:48
grepをfgrepに置き換えただけで何10倍も捗ることがあるから
侮れない。「正規表現ってなに?」ってレベルでUnix弄ってるのなら、
grep→fgrepに全部置き換えてしまえばいい
20 :名無しさん@お腹いっぱい。2010/12/14(火) 14:31:21
あとawkとかperlに巨大テキストを食べさせるときも、
前段でfgrepしておくと捗るよ
21 :名無しさん@お腹いっぱい。2010/12/14(火) 17:54:49
20年以上昔には成り立っていたバッドノウハウだな。
今は grepもfgrepも速度はほとんど変わらない。
(むしろfgrepは速そうな名前の割りに遅いことで有名だったんだが)
パイプ前段でfgrepで前処理するのも不要。

昔の常識がいつまでも通用すると思わないことだな。
23 :名無しさん@お腹いっぱい。2010/12/14(火) 19:14:16
>>21
バッドノウハウ(笑)
ちょっと手を動かしてみればすぐに実感できるお
26 :名無しさん@お腹いっぱい。2010/12/14(火) 19:32:18
>>23
最後に何か言いたいことはあるかね?
22 :名無しさん@お腹いっぱい。2010/12/14(火) 18:23:59
Solaris 9 の fgrep(1)
http://docs.sun.com/app/docs/doc/816-5211/6mbcci3bd
> The fgrep (fast grep) utility ...

Solaris 10 の fgrep(1)
http://docs.sun.com/app/docs/doc/821-1461/fgrep-1
> The fgrep (fixed grep) utility ...

修正されてる(笑)
24 :名無しさん@お腹いっぱい。2010/12/14(火) 19:19:55
ちょっと手を動かしてみた。

$ time for i in {1..5000}; do grep localhost /etc/hosts >/dev/null; done

real 0m15.299s
user 0m3.004s
sys 0m5.896s
$ time for i in {1..5000}; do fgrep localhost /etc/hosts >/dev/null; done

real 0m18.646s
user 0m4.784s
sys 0m6.616s
$

実感できなかった。
25 :名無しさん@お腹いっぱい。2010/12/14(火) 19:26:22
速度に関しては、

fgrep < grep < egrep (左ほど遅い)

が常識。

fgrepの存在意義は、^ とか $ とかをエスケープなしで普通の文字列として使えるという
仕様の違いのみ。fgrepよりも egrep使った方が速い。
27 :名無しさん@お腹いっぱい。2010/12/14(火) 20:02:46
% gzip -dc /var/log/messages.72 | wc -l
204269

% time gzip -dc /var/log/messages.72 | egrep Jan | wc -l
55

real 0m3.424s
user 0m3.712s
sys 0m0.025s

% time gzip -dc /var/log/messages.72 | fgrep Jan | wc -l
55

real 0m3.402s
user 0m3.684s
sys 0m0.036s

% time gzip -dc /var/log/messages.72 | awk /Jan/ | wc -l
55

real 0m0.417s   ←ワロス
user 0m0.663s
sys 0m0.050s

% time gzip -dc /var/log/messages.72 | perl -nle '/Jan/&&print' | wc -l
55

real 0m0.392s   ←ワロス
user 0m0.675s
sys 0m0.042s

結論 .?grepはウンコ
28 :名無しさん@お腹いっぱい。2010/12/14(火) 20:32:51
>>27
おまえが測ってるのは gzip -dc の時間だ
29 :名無しさん@お腹いっぱい。2010/12/14(火) 20:35:57
>>28
それは /usr/bin/timeとかの外部コマンドを使った場合の話。

timeは外部コマンドじゃなくて、シェルが直接管理して動くもので、
パイプライン全体の時間を計るようにできてる。
39 :名無しさん@お腹いっぱい。2010/12/15(水) 21:32:58
お、まだやってたのか。
>>38
>>27の各バージョンはこうね。

% grep --version
grep (GNU grep) 2.5.1

% awk --version
GNU Awk 3.1.3
Copyright (C) 1989, 1991-2003 Free Software Foundation.

% perl -v
This is perl, v5.8.7 built for i686-linux
Copyright 1987-2005, Larry Wall

% ldd `which grep`
linux-gate.so.1 => (0xffffe000)
libc.so.6 => /lib/libc.so.6 (0xb7e31000)
/lib/ld-linux.so.2 (0xb7f50000)
% ldd `which awk`
linux-gate.so.1 => (0xffffe000)
libdl.so.2 => /lib/libdl.so.2 (0xb7f5b000)
libm.so.6 => /lib/libm.so.6 (0xb7f37000)
libc.so.6 => /lib/libc.so.6 (0xb7e23000)
/lib/ld-linux.so.2 (0xb7f6a000)

・gzipを外して time grep Jan messages | wc -l のように変えても結果は同じ
・検索条件を Jan → J に変えても結果は同じ。*grepよりもawk,perlの方が10倍速い
・timeが何を測っているかが云々されていたが、体感ではっきり差がわかるレベル。
 *grepは待たされるがawk,perlは瞬間的に終わるから
30 :名無しさん@お腹いっぱい。2010/12/14(火) 20:45:28
$ time sh -c 'echo hoge; sleep 1'| sh -c 'cat; sleep 1'
hoge
1.01 real 0.00 user 0.01 sys

sh 一般の話じゃなくて、また bash 固有の動作?
31 :名無しさん@お腹いっぱい。2010/12/14(火) 20:54:26
>>30
bashだけじゃなくて kshや zshでもそうだよ。

$ time sh -c 'echo hoge; sleep 1'| sh -c 'cat; sleep 1'
hoge

real 0m2.014s
user 0m0.003s
sys 0m0.007s
32 :名無しさん@お腹いっぱい。2010/12/14(火) 21:00:14
ここまで、まとめると、

fgrepが速いと言われていたのは大昔で、今ではgrepより遅い。
さらに、fgrep/grep/egrepよりも awkやperlの方が速い。

よく、grepで前処理してからパイプでawkかperlに食わせてる例を見かけるが、
あれはgrepの処理をawkやperlのプログラム中に吸収して grepをカットした方が速くなる。
35 :名無しさん@お腹いっぱい。2010/12/14(火) 22:42:57
>>32
> fgrepが速いと言われていたのは大昔で、今ではgrepより遅い。

いや、大昔こそfgrepは遅い。
理由は実装が、fgrepは文字列比較、egrepはDFAだったから。
今はどちらもDFAにしているのが多い。
昔のUNIXのソース読んでみて。http://minnie.tuhs.org/cgi-bin/utree.pl
33 :名無しさん@お腹いっぱい。2010/12/14(火) 21:03:23
昔から、fgrepが速いなんてのは神話だ、と言われてたと思うけど
34 :名無しさん@お腹いっぱい。2010/12/14(火) 22:10:21
grep系をawkかperlに渡すwrapperスクリプトで置き換えたほうが10倍捗るってことだな。

ちなみにうちのLinuxは

# file /usr/bin/{e,f,}grep
/usr/bin/egrep: Bourne shell script text executable
/usr/bin/fgrep: Bourne shell script text executable
/usr/bin/grep: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.0.0, dynamically linked (uses shared libs), stripped
#
# cat /usr/bin/egrep
#!/bin/sh
exec grep -E ${1+"$@"}
#
# cat /usr/bin/fgrep
#!/bin/sh
exec grep -F ${1+"$@"}
#

最初からスクリプトに置き換えられていますた(´・ω・`)

36 :名無しさん@お腹いっぱい。2010/12/14(火) 22:46:43
>>34
psedってのがほとんどのperl配布に入ってるから、
psed -n '/ /p'すればいい。
37 :名無しさん@お腹いっぱい。2010/12/15(水) 12:58:57
grep一族の速度差はふーんて感じだが、awkやperlの一行プルグラムの方が10倍も速いって
にわかには信じ難い話しだな。検索しか能のないgrep使う意味ねーじゃんw
使ったgrepの方がバージョンが旧すぎて実装がショボかったとか、そういう落ちなんじゃないの?
38 :名無しさん@お腹いっぱい。2010/12/15(水) 20:44:32
awk の方が grep より早いのが信じれないのでやってみた

$ cat /etc/debian_version
5.0.6
$ echo $SHELL
/bin/bash
$ uname -svrm
Linux 2.6.26.5 #2 SMP Mon Sep 29 14:17:40 JST 2008 i686
$ wc -l testlog
100000 testlog
$ time grep 1 testlog |wc -l
40952
real 0m0.013s
user 0m0.008s
sys 0m0.004s
$ time fgrep 1 testlog |wc -l
40952
real 0m0.012s
user 0m0.012s
sys 0m0.000s
$ time perl -lne '/1/&&print' testlog |wc -l
40952
real 0m0.061s
user 0m0.056s
sys 0m0.004s
$ time awk /1/ testlog |wc -l
40952
real 0m0.142s
user 0m0.132s
sys 0m0.008s

awk 遅いんだが..。対象ファイルや条件次第でここまで変わるのかな〜
40 :名無しさん@お腹いっぱい。2010/12/16(木) 00:43:14
>>38,39
debianのawkは標準だとmawkなはず。
差異の原因かも?
41 :名無しさん@お腹いっぱい。2010/12/16(木) 00:50:10
hoge(){ hoge|hoge& }; hoge

hoge(){ hoge&hoge& }; hoge

fork bombとして使うなら、どっちの方が効果的なんだろうか
スケジューラに詳しい人います?
42 :名無しさん@お腹いっぱい。2010/12/19(日) 20:20:02
中1の時にプログラミングしたいと思って知り合いに聞いてC言語始めたけど2日くらいで挫折した。
けど最近Ubuntuにかなりハマってシェルスクリプトも初めてみた。C言語より簡単で分かりやすかったからタイピングゲームとか作れるようになりたい。
44 :名無しさん@お腹いっぱい。2010/12/19(日) 22:43:45
シェルでタイピングゲームは無理だろ?
45 :名無しさん@お腹いっぱい。2010/12/20(月) 05:39:34
>>44

ゲームで極める シェルスクリプトスーパーテクニック
http://gihyo.jp/book/2007/978-4-7741-3202-0

Chapter 9 ゲームで極めるシェルスクリプト超テクニック【タイピングゲーム編】


現物を見てないから、どんなもんか知らんけど。
46 :名無しさん@お腹いっぱい。2010/12/20(月) 06:47:25
47 :名無しさん@お腹いっぱい。2010/12/20(月) 07:36:36
>>46
クレイジーだな(褒め言ry

動画は保存した。スレチだけど Shibuya.lisp とかでやるヤツ
居ても可笑しく無さそうなネタに見えちまう。

48 :名無しさん@お腹いっぱい。2010/12/20(月) 09:26:22
grep が awk や perl より遅いのはありえんだろ。うちじゃ問題ないな

grep で速度的な問題に直面したのは、何年か前に -i オプション付きだと
死ぬほど遅くなったときだ。locale 周りを見るらしいので、
LANG=C grep とかの alias で凌いだけど。スクリプトも一部書き換えたかな
50 :名無しさん@お腹いっぱい。2010/12/21(火) 11:36:46
シェル関数では $1,$2,... は関数呼び出し時の引数になるけど、
そうじゃなくてスクリプト起動時に与えられた引数を参照する方法ってある?
関数を呼ぶときにいっしょに $@ を渡すしかない?
52 :名無しさん@お腹いっぱい。2010/12/21(火) 12:41:42
うん、bash じゃないんだ。

bash がわざわざ機能を拡張してそういうものを用意してる、ということは、
逆に言えば標準的な方法ではできない、ってことでいいんだよな、やっぱり。
53 :名無しさん@お腹いっぱい。2010/12/21(火) 15:41:27
>>52
直接 $1, $2, ... 参照じゃまずのか?
54 :名無しさん@お腹いっぱい。2010/12/21(火) 16:33:50
>>53
関数の中では $1 $2 は関数の引数を意味してしまう。
そうではなく、スクリプト自体の引数を関数の中で参照したい、ということでは。
56 :名無しさん@お腹いっぱい。2010/12/21(火) 16:42:46
引数の個数は不定だし、純正シェルでは配列が使えないし、
「てけとーな変数にコピー」するのも難しい。
60 :名無しさん@お腹いっぱい。2010/12/24(金) 21:53:25
Linux板のシェルスクリプトが無かったのでこっちで聞く。

両方見るの大変だったからその方が都合いいんだけど
Linux板のシェルスクリプトスレはUNIX板へ統合?
63 :名無しさん@お腹いっぱい。2010/12/24(金) 23:07:26
ねーよ。そういうのを隔離するために板を分けたんだよ。寄ってくんな。
65 :名無しさん@お腹いっぱい。2010/12/24(金) 23:40:25
いやまて、かつてkorn shellスクリプトが許されていたわけではないぞ
66 :名無しさん@お腹いっぱい。2010/12/25(土) 08:39:11
いまどきBashにも対応するのが最低限のマナーでしょ。
「ウチはBashには対応しません」なんて言ってたら取引先に迷惑だよw
69 :名無しさん@お腹いっぱい。2010/12/25(土) 09:51:39
>>66 非力なCPU使った規模の小さい組み込み装置にbashのせるのは犯罪だ
70 :名無しさん@お腹いっぱい。2010/12/25(土) 09:56:49
>>69
乗らないのが悪いと言いたいのだろう
67 :名無しさん@お腹いっぱい。2010/12/25(土) 08:42:58
犬板でやる分には何の文句も出ないわけだが、何故こっちに立てたがるのだ?
68 :名無しさん@お腹いっぱい。2010/12/25(土) 08:44:11
こっちに立てるんじゃなくてこのスレで質問するだけのこと
71 :名無しさん@お腹いっぱい。2010/12/25(土) 11:26:45
>>68
アスペ丸出し。これなら理解できるか? w

犬板のスレなら何の文句も出ないわけだが、何故こっちの板のスレで質問したいのだ?
72 :名無しさん@お腹いっぱい。2010/12/25(土) 11:29:46
>>71
犬板のスレはなくなったの。現状をよく把握してから書こうね。
77 :名無しさん@お腹いっぱい。2010/12/25(土) 11:37:38
>>72
あー、はいはい。w

犬板にスレ立てれば何の文句も出ないわけだが、何故こっちの板のスレで質問したいのだ?
78 :名無しさん@お腹いっぱい。2010/12/25(土) 11:38:17
>>72
そもそもなんでLinux板のスクリプトスレはなくなったの?
立てられないの?
75 :名無しさん@お腹いっぱい。2010/12/25(土) 11:33:44
このスレではもともとbashの質問はOKだよ。
bashだからと言ってLinuxとは限らない。
Linuxの場合でもLinuxと言わずにbashの質問として質問すればOK。
79 :名無しさん@お腹いっぱい。2010/12/25(土) 11:54:54
こっちもそうだが、Linux板のシェルスクリプトスレも段々過疎ってきてた。
挙げ句Linux板のシェルスクリプトスレは立てられなくなってたわけだ。
81 :名無しさん@お腹いっぱい。2010/12/25(土) 12:45:58
>>79
お前がいたから衰退したんだろ。寄ってくんな。疫病神。
82 :名無しさん@お腹いっぱい。2010/12/25(土) 13:15:50
どっちの板にも関係なさそうなキチガイが混じってるな
煽り野郎は近頃減ってたんだが、なぜ湧いた
85 :名無しさん@お腹いっぱい。2010/12/26(日) 16:15:36
bashの話題も何の問題もない。
Linux依存の話はどうかと思うけど、
使っているのがLinuxなのはなんの問題もない。
86 :名無しさん@お腹いっぱい。2010/12/26(日) 16:55:57
bourne shell とそのサブセット以外は禁止
87 :名無しさん@お腹いっぱい。2010/12/26(日) 18:04:33
>>86 ksh や zsh の行き場がなくなるわけだが
90 :名無しさん@お腹いっぱい。2010/12/26(日) 19:20:59
個人的には対象環境を明記する人の質問ならなんでもいい。
93 :名無しさん@お腹いっぱい。2010/12/26(日) 21:07:55
bourne shellのスーパーセットのbashについて質問します。
プロンプトに時刻を入れることはできるのですが、
この時刻をリアルタイムで更新するにはどう設定すればいいでしょうか?
現状では時刻が更新されないため、コマンドを実行開始した時刻ではなく、
そのプロンプトが表示された時刻しかわかりません。

時刻を更新するのは、現在のプロンプトだけでいいです。
(画面の上に流れて行くプロンプトは、そのコマンド実行時点で更新停止)
95 :名無しさん@お腹いっぱい。2010/12/26(日) 22:03:14
screenのステータスなりキャプションなりに時間出したほうが幸せになれそう。
96 :名無しさん@お腹いっぱい。2010/12/26(日) 22:51:51
そもそもshとsedとawkでどこまでできるかという頭の体操スレなんだから
実用性を求めるならperl/ruby/pythonスクリプト書けばいいという話
99 :名無しさん@お腹いっぱい。2010/12/29(水) 01:14:35
前回出力した行を消して、
前回と同じ行に新たに出力するには
どうすればいいのでしょうか?

wgetでダウンロードの進捗を表すプログレスバーのように
テキストアニメーションのようなことがしたいのですが
100 :名無しさん@お腹いっぱい。2010/12/29(水) 01:34:09
man 5 terminfo
man 3 terminfo
man 1 tput
101 :名無しさん@お腹いっぱい。2010/12/29(水) 01:52:25
>>100
なんとかなりそうです。
ありがとうございました!
102 :名無しさん@お腹いっぱい。2010/12/29(水) 06:40:41
>>100
変な誘導するな。1行だけならterminfo使わずにできる。
実際、wgetはterminfo/termcapを使ってない。
103 :名無しさん@お腹いっぱい。2010/12/29(水) 08:44:10
CRを出力して行頭に戻り、行全体を書き直すのが簡単。
106 :名無しさん@お腹いっぱい。2010/12/29(水) 10:18:17
>>105 は日本語読めないのか?

>>103
>CRを出力して行頭に戻り、『行全体を書き直す』
104 :名無しさん@お腹いっぱい。2010/12/29(水) 09:45:55
行消去って端末依存じゃない?
107 :名無しさん@お腹いっぱい。2010/12/29(水) 10:21:13
いや、>>105 はそんなこと知ってるだろ。
>>104 に対して「CRは行消去するわけじゃないよ」と言ってるんだろ
109 :名無しさん@お腹いっぱい。2010/12/29(水) 10:29:35
>>104は、行全体を書き直すためには行頭に戻って、行消去が必要じゃねーの?
でも、行消去って端末依存だよね。

という意味。
111 :名無しさん@お腹いっぱい。2010/12/29(水) 10:32:20
>>109 行消去しないでも上書きすればOK
105 :名無しさん@お腹いっぱい。2010/12/29(水) 10:10:38
CRは行消去しないよ.
端末依存には違いはないけど、CRで行頭に戻らない端末って見掛けたことがないな
108 :名無しさん@お腹いっぱい。2010/12/29(水) 10:25:14
ところで、元質問とは違うが、
端末依存を解消するための tput だったはずなのに、
tputコマンド自体がOS依存なのは何とかならないものか。

FreeBSDではtputがtermcapエミュレーションのため、
tputの引数キーワードがtermcapのキーワードになっていて
他のOSとは異なっている。
110 :名無しさん@お腹いっぱい。2010/12/29(水) 10:32:12
>>108
いまどきtermcapを使ってるようなFreeBSDを捨てればすべて解決。
112 :名無しさん@お腹いっぱい。2010/12/29(水) 12:17:28
termcapはラインプリンタを想定してるからそもそも行消去コマンドは無いんじゃねーか?
113 :名無しさん@お腹いっぱい。2010/12/29(水) 12:26:23
> termcapはラインプリンタを想定してるから
> termcapはラインプリンタを想定してるから
> termcapはラインプリンタを想定してるから
> termcapはラインプリンタを想定してるから
114 :名無しさん@お腹いっぱい。2010/12/29(水) 12:36:57
カーソル行の1行消去なら、ESC [ K
現行端末で、これ以外のシーケンスを見たことがない。
だから ESC [ K 決め打ちで良い。
115 :名無しさん@お腹いっぱい。2010/12/29(水) 17:10:37
例えば、dateコマンドの出力をスペースで区切って変数に代入したい場合、AIXのkshでは
$ date | read DOW MONTH DAY TIME YEAR
$ echo $DOW $MONTH $DAY $TIME $YEAR
Wed Dec 29 16:56:47 JST 2010
というようなことができたのですが、Cygwinではbashでもkshでも同じことができません。

$ date | (read DOW MONTH DAY TIME YEAR; echo $DOW $MONTH $DAY $TIME $YEAR)
とすると表示されますが、以降は変数が空になってしまい使えません。パイプの後の文がサブシェルになってしまったせいで
変数が引き継がれないのかと思いますが、良い回避方法はないでしょうか?
121 :名無しさん@お腹いっぱい。2010/12/29(水) 17:58:54
AIXはそういうもんだと思っていた。
124 :名無しさん@お腹いっぱい。2010/12/30(木) 05:24:13
>>121
そんな屁理屈聞いてんじゃねえんだよ
123 :名無しさん@お腹いっぱい。2010/12/29(水) 18:09:07
みなさん。ありがとうございます。
これまでAIXのkshしかほとんど触ったことがなく、あまりサブシェルの変数の問題で悩んだ
ことがなかったのですが、調べれば調べるほどハマリそうな仕組みですね。
これはこういうものとして気をつけてコーディングしないとならん、ということですね。
125 :名無しさん@お腹いっぱい。2010/12/31(金) 00:35:28
ちょっとまって、なんでウニックス板はID無いの?自演しまくりじゃん?
127 :名無しさん@お腹いっぱい。2011/01/02(日) 21:07:04
定型のメールの本文mail.txtを用意して、
cat mail.txt | mail mail@address -s "Test Mail" のスクリプトでメールは
送れるんですが、
mail.txtにタイムスタンプなどを追加したいんですが、どのように書けば良いでしょうか
できれば、mail.txtには変更は加えたくないです。
ちなみに、タイムスタンプはtime_stamp.sh
#!/bin/sh

YEAR=`date '+%Y'`
MONTH=`date '+%m'`
DAY=`date '+%d'`
HOUER=`date '+%k'`
MINUTE=`date '+%M'`
SECOND=`date '+%S'`
SEND_DATE="発信 : $YEAR年$MONTH月$DAY日$HOUER時$MINUTE分$SECOND秒"
echo $SEND_DATE
みたいな物を考えています。
131 :名無しさん@お腹いっぱい。2011/01/04(火) 08:50:54
>>127
その time_stamp.shは無駄杉。
あと、"HOUER"ってスペル間違ってるしw

#!/bin/sh
date +'発信 : %Y年%m月%d日%k時%M分%S秒'

↑だけで桶。
128 :名無しさん@お腹いっぱい。2011/01/02(日) 21:32:33
タイムスタンプをどこに入れたいかによるけど、先頭か末尾だったらこんな感じでいけるのでは
( time_stamp.sh ; cat mail.txt ) | mail mail@address -s "Test Mail"
129 :名無しさん@お腹いっぱい。2011/01/02(日) 21:43:15
(cat mail.txt; time_stamp.sh) | mail mail@address -s "Test Mail"
で、末尾に入れることができました。
ありがとう、ございました。
130 :名無しさん@お腹いっぱい。2011/01/03(月) 10:26:09
悪いことをしようとしてる奴に教える必要なんか無いぞ
132 :名無しさん@お腹いっぱい。2011/01/04(火) 15:15:33
>>131
まあ、そこまで言ったら、time_stamp.sh 自体無駄ですなw

>>130
sender や envelope from を詐称したりしてないわけで...
133 :名無しさん@お腹いっぱい。2011/01/05(水) 22:31:40
あるディレクトリ内に5秒ごとに
2011_01_05_22_15_10_picture_000000000.jpg
2011_01_05_22_15_15_picture_000000001.jpg
   ・
   ・
のように、ファイルが作成されますが、この内の最新のものだけを残して
古い物を削除した
基本的に、新しいファイルが作成されたタイミングで、一度スクリプトが動かせる
はずなので、新しいものと、古いものの2つのファイルしかないはずなんですが
最新のファイルのみ残せないでしょうか
134 :名無しさん@お腹いっぱい。2011/01/05(水) 22:43:09
>>133

rm `ls -t | tail -n +2`
135 :1332011/01/05(水) 23:00:50
>>134
速攻回答、感謝
136 :名無しさん@お腹いっぱい。2011/01/07(金) 15:28:01
ぐぐりながら初めてのシェルスクリプトを書いております。
bowtieとかsamtoolsとかいうコマンドを逐次実行しているだけなのですが
それぞれbowtieやsamtoolsがスクリーン?に出力したものをファイルに記録したいのですが
どうしたらよいのでしょう。

bowtie | tee test.log
samtools | tee -a test.log

では、test.logファイルは作成されるものの、記録が書き込まれておらず

screen -a -q test.log
bowtie
samtools
exit
では動かなくて、

そろそろお手上げです。
よろしくお願いします。
137 :名無しさん@お腹いっぱい。2011/01/07(金) 15:33:56
>>136
script
138 :名無しさん@お腹いっぱい。2011/01/07(金) 15:37:46
あああ、すいません
screen ではなくてscript でした。

screen-a -q test.log
bowtie
samtools
exit
では何も書き込まれていなかったんです。
139 :名無しさん@お腹いっぱい。2011/01/07(金) 15:42:01
>>138

script -c 'bowtie; samtools' test.log
140 :名無しさん@お腹いっぱい。2011/01/07(金) 15:46:47
あ、うそです。うまくいってました。
でも、exitが効いていない感じです。
scriptがうごいているまま、何度もシェルスクリプトを実行してました。
142 :名無しさん@お腹いっぱい。2011/01/07(金) 21:55:15
たびたびすいません。
scriptにcオプションがなく、
また制御文字ではないと思うのですがへんてこな文字化けも含まれたり、
とあまりうまくいってません。

screenのハードコピーを使ってみようと思い

#!/bin/sh
date='date +s'
echo "test"
screen -X hardcopy ${date}.txt

こんな感じで書いてみたのですが、動きません。。。
最後の一行を
screen -X hardcopy とすると、hardcopy.2というファイルが作られ、
screen -X hardcopy test.txt とするとtest.txtは作られますが
どちらもなぜかlsを実行した結果が保存されています。
145 :名無しさん@お腹いっぱい。2011/01/08(土) 02:04:43
ああああ、
ありがとうございました。

あと、なぞのlsですが、シェルスクリプトが動いている画面ではなく、
いろいろ試したときのscreen2が残っていて、そいつのhardcopyをとっていたようです。
screen2をkillしたら、ただしく、testが${date}.txtに落ちてきました。
これで、希望通りになりました。

あとは、screenが動いていたら余分なscreenをkillするという前処理が
必要なのかもしれないので、またググって頑張ってみます。
147 :名無しさん@お腹いっぱい。2011/01/08(土) 11:49:02
さっき"$*"と$*の挙動が違うことに気づいたんだけど、どっかにまとまったドキュメントか何かあるの?
IFSを挟んで展開されるかどうかが違うだけだと思うんだけど、$*は"$@"に近いというか。
148 :名無しさん@お腹いっぱい。2011/01/08(土) 11:52:42
man bash
149 :名無しさん@お腹いっぱい。2011/01/08(土) 13:09:54
>>148
When the expansion occurs within double quotes, it expands to a single word with the value of each parameter
separated by the first character of the IFS special variable.
のあたりを誤解してました。When以下の節は「'$*'じゃなくて"$*"だよ」って言いたいだけだと思ってました。
150 :名無しさん@お腹いっぱい。2011/01/08(土) 19:04:13
1行の長〜い命令を、複数行に書くことってできますか?
153 :名無しさん@お腹いっぱい。2011/01/08(土) 20:42:56
知らないなら無理に答えなくていいよ。

知ってる方、答をどうぞ
157 :名無しさん@お腹いっぱい。2011/01/08(土) 21:01:01
「おいィ?お前らは今の言葉聞こえたか?」

「聞こえてない」
「何か言ったの?」
「俺のログには何もないな」
158 :名無しさん@お腹いっぱい。2011/01/10(月) 16:46:11
正規表現を使ってlsコマンドを行うと、
カレントディレクトリ直下のディレクトリの中身まで表示されます…
どうすればカレントディレクトリ直下のファイル及びディレクトリだけ表示できるんですか?

教えて(人∀・)タノム
161 :名無しさん@お腹いっぱい。2011/01/11(火) 21:45:21
ワイルドカード、グロビングでくぐれ
162 :名無しさん@お腹いっぱい。2011/01/11(火) 21:47:02
>>161
突然誰に話してるんだ?
163 :名無しさん@お腹いっぱい。2011/01/11(火) 21:54:14
>>162
おまえだよ
165 :名無しさん@お腹いっぱい。2011/01/12(水) 21:29:12
start=12
end=345
みたいに代入されていて、

hoge0001.txt
hoge0002.txt
hoge0003.txt
:
hoge9999.txt
みたいなファイルがあって、

hoge「$startから$endまでの範囲の数字」.txt
というワイマールカードを一発で決めたいんですが、
その命令?はどう打てばいいんでしょうか?
167 :名無しさん@お腹いっぱい。2011/01/12(水) 21:53:22
※ワイマールカード: 市バスが無料、ゲーテハウス、ワイマール新美術館など市内の見どころも無料で、さまざまな割引や特典が付いています。マルクト広場の観光案内所で販売しています
171 :名無しさん@お腹いっぱい。2011/01/12(水) 22:15:55
LANG=de_DE.UTF-8; export LANG
ls -1 hoge????.txt | head -n $end | tail -n +$start
- or -
seq -f "hoge%04g.txt" $start 1 $end
174 :1652011/01/13(木) 06:32:43
>>171
hoge1234.txtとかは1番からすべて順番に存在するわけじゃなくて
飛んでる番号もあります。なので、>>171 の前半はNGです。

>>171 後半も、seqを入れたとしても存在しないファイルまで展開されるのでNGです。

hoge{$start,$end}.txt みたいなワイマールカード一発命令はないんでしょうか?
175 :名無しさん@お腹いっぱい。2011/01/13(木) 07:21:58
条件の後出し禁止

hoge{1,2,3}.txt だって、存在しないファイルまで展開すっぞ
176 :名無しさん@お腹いっぱい。2011/01/13(木) 07:40:52
じゃあ、条件の後出しじゃなくて新たな質問ということで、

詳しい方回答をどうぞ
177 :名無しさん@お腹いっぱい。2011/01/13(木) 10:15:56
> hoge{$start,$end}.txt みたいなワイマールカード一発命令はないんでしょうか?
そんなもん、あるわけねーだろwww
178 :名無しさん@お腹いっぱい。2011/01/13(木) 10:19:52
おまえらスルースキルゼロだな
いかにレベルの低い人間が集まっているかよく分かる
181 :名無しさん@お腹いっぱい。2011/01/13(木) 11:28:05
>hoge0001.txt
>hoge0002.txt
>hoge0003.txt
>:
>hoge9999.txt
>みたいなファイルがあって、

>hoge1234.txtとかは1番からすべて順番に存在するわけじゃなくて
>飛んでる番号もあります。

182 :名無しさん@お腹いっぱい。2011/01/13(木) 11:34:59
>>181
「みたいな」ファイル、という非限定用法が用いられているため、
必ずしも矛盾しているとは認められない。
183 :名無しさん@お腹いっぱい。2011/01/13(木) 13:08:26
マイルーラカードって使ってみたいけど
臭いとか無い?
187 :名無しさん@お腹いっぱい。2011/01/14(金) 10:53:38
sedとピリオドの使い方を教えて

./DIR を ../DIR(カレントを一つ上にしたい)のですが、
sed 's/\.\/DIR/\.\.\/DIR/g' src_file > dist_fileとすると

..../DIRと、ピリオドが4つになって上手くいきません。

誰か教えて
188 :名無しさん@お腹いっぱい。2011/01/14(金) 11:14:07
>>187
スレチなのでこちらへどうぞ

sed
http://hibari.2ch.net/test/read.cgi/unix/1085730992/

ただ、こっちの環境では >>187 でOKだったけど
190 :名無しさん@お腹いっぱい。2011/01/14(金) 12:24:44
最初の \. の前に[^\.]を入れたらどうなる?
191 :名無しさん@お腹いっぱい。2011/01/14(金) 12:37:06
>>190
それ、外してるので。何か言いたければsedスレでどうぞ。
192 :名無しさん@お腹いっぱい。2011/01/15(土) 02:10:15
$cat test.txt

{
jobList = (
813,
814,
815,
816,

834
);
}

です。
ここから、一行ずつ、数字の部分だけ、それぞれ異なる変数に入れるには
どうしたらよいのでしょうか?
$echo "$1 $2 $3"
813 814 815
みたいな感じです。変数の数は、毎回固定の21個のはずです。
201 :名無しさん@お腹いっぱい。2011/01/17(月) 14:22:02
すいません。その先もだめです。実はxgridをやっているのですが、、、、

$ xgrid -h localhost -job attributes -id ほげほげとやると
{
jobAttributes = {
activeCPUPower = 3516;
applicationIdentifier = "com.apple.xgrid.cli";
dateNow = "2011-01-17 14:18:18 +0900";
dateStarted = "2011-01-17 14:09:15 +0900";
dateSubmitted = "2011-01-17 14:09:05 +0900";
jobStatus = Running;
name = "/bin/sh";
percentDone = 0;
taskCount = 1;
undoneTaskCount = 1;
};
}
jobStatusは最終的にFinishedに変わります。
>>192でとりだしたjob idに対して、すべてのjobがFinishedにかわるまで待つという
ことをやりたいのですが、
193 :名無しさん@お腹いっぱい。2011/01/15(土) 08:44:47
sed板なんだろうけど

set - `sed -n '/^[0-9]*,*$/p'`
196 :名無しさん@お腹いっぱい。2011/01/15(土) 08:47:38
>>193
カンマまで代入されるから×。sedスレ池。
200 :名無しさん@お腹いっぱい。2011/01/15(土) 16:06:51
>>193-196
ありがとうございました。
動きました。
197 :名無しさん@お腹いっぱい。2011/01/15(土) 09:18:38
test -d a
はできるけど
[[-d a]]
はできないのはなぜですか?
198 :名無しさん@お腹いっぱい。2011/01/15(土) 09:20:45
>>197
[[ -d a ]]
202 :名無しさん@お腹いっぱい。2011/01/17(月) 14:27:35
#!/bin/sh
xgrid -h localhost - job list | set -- `tr -cd '0-9,' | tr ',' ' '`

for jobid in $*
do
jobstatus=`xgrid -h localhost -job attributes -id $jobid |grep -c Finished`
until [$jobstatus == 1]
do
sleep 120
done
done

次のコマンド
---------------
というシェルスクリプトにしたのですが、すべてのxgrid処理がFinishedに
なっていないのに、次のコマンドが動き出してしまいます。
どう直したらよいのでしょうか???
203 :名無しさん@お腹いっぱい。2011/01/17(月) 14:44:47
>>202
それだと、標準入力はtrに渡らず、set が食っちまうんじゃね?
(というかsetだと組み込みコマンドだから…誰になるんだ? サブシェル?)

set -- `xgrid ... | tr ... ` だとどう?

とりあえず echo $* の結果を確認してみればいいと思う。
204 :名無しさん@お腹いっぱい。2011/01/17(月) 14:44:47
>>202
until [$jobstatus == 1]

until [ $jobstatus = 1 ]
の誤記だろうけど、
これでは1つだけFinishedになったらループが終了するよ。
205 :名無しさん@お腹いっぱい。2011/01/17(月) 14:48:20
>>202
込み入った質問と回答になりますので、通常5インシデント申し受けますが、
ただいまキャンペーン中に付き、3インシデントで承ります。
お取引きの代理店を通じてご用命下さい。
206 :名無しさん@お腹いっぱい。2011/01/17(月) 14:50:42
>>203
私には縮めるのはまだ無理そうなので

#!/bin/sh
xgrid -h localhost - job list >joblist.txt
set -- `tr -cd '0-9,' <joblist.txt | tr ',' ' '`

これで行きます。。。
207 :名無しさん@お腹いっぱい。2011/01/17(月) 15:16:16
>>204
どうしたらよいのか、ヒントをください。。。
208 :名無しさん@お腹いっぱい。2011/01/17(月) 15:18:00
>>207
ご用命、お待ち致します。
211 :名無しさん@お腹いっぱい。2011/01/17(月) 18:45:47
for jobid in $*; do
 while true; do
  $iが終わっていたら、break;
  sleep 120
 done
done
じゃないだろうか?
212 :名無しさん@お腹いっぱい。2011/01/18(火) 11:12:06
ありがとうございます。ありがとうございます。何せ、シェルスクリプト歴2週間のタコ。
breakでググっていきますと、少しずつわかりかけてきました。
>>211です。やりたかたこと。
jobstatusには、Failedもあったので、
さらに欲をかき、以下のようにして動かすことができました。多謝。

xgrid -h 10.64.84.166 -job list > job_view_list_${date}.txt
set -- `tr -cd '0-9,' < job_view_list_$date.txt | tr ',' ' '`

for jobid in $*; do
while true; do
jobstatus=`xgrid -h localhost -job attributes -id $jobid |grep jobStatus`
case $jobstatus in
*Failed*) eval xgrid -h localhost -job restart -id $jobid;;
*Running*) sleep 120;;
*Finished*) break;;
esac
done

done
213 :名無しさん@お腹いっぱい。2011/01/19(水) 16:17:46
tarファイルの中のファイルを削除したいのですが、aixにはdeleteオプションが無いようなので、このオプションを使わずに削除するにはどうすればいいのでしょうか?
214 :名無しさん@お腹いっぱい。2011/01/19(水) 16:18:25
215 :名無しさん@お腹いっぱい。2011/01/19(水) 16:19:35
まずGNU tarを入れます
216 :名無しさん@お腹いっぱい。2011/01/19(水) 16:38:21
>>215
それは難しいと思います。
パイプで渡せば出来そうな気がするのですが。具体的にどう書けばいいのかわかりません、
219 :名無しさん@お腹いっぱい。2011/01/19(水) 16:57:50
>>216 の思考をエスパー
tar xf hoge.tar | grep -v 削除したいファイル | tar cf - hoge_new.tar

で、できるとでも勘違いしてるんだろう
220 :名無しさん@お腹いっぱい。2011/01/19(水) 17:24:34
>>219
じゃあどうすればできるのでしょうか?
221 :名無しさん@お腹いっぱい。2011/01/19(水) 17:26:26
>>220
できない
223 :名無しさん@お腹いっぱい。2011/01/19(水) 19:57:42
>>215
GNU tarならできるのかぁ。
でもどうやってるんだろ。
削除した分って切り詰めるのかな?
224 :名無しさん@お腹いっぱい。2011/01/19(水) 20:10:50
>>215
そしてGNU tarを奇麗にたたみます
228 :名無しさん@お腹いっぱい。2011/01/19(水) 21:15:24
>>223
一般論としては一時ファイル使うのが楽だけど、一時ファイルを使わないのなら
読み込み用と書き込み用のファイル位置を管理しつつ、
読み込み位置にシークして読み込み
→削除対象外のデータなら、書き込み位置にシークして書き込み
最後にtruncateすればいい

Pythonで書くとこんな感じのコード
(正規表現にマッチする行をファイルから直接削除する例)
http://codepad.org/M29pTYa5
217 :名無しさん@お腹いっぱい。2011/01/19(水) 16:44:45
パイプで渡してできると勘違いしてる奴に何アドバイスしても無駄w
229 :名無しさん@お腹いっぱい。2011/01/20(木) 10:17:42
自分のやりたい処理は
gawk '$3!="*"' in.txt>out.txt
なんですが、これを繰り返し処理させたいので
for i in `jot 19` X Y
do
gawk '$3!="*"' in{i}.txt>out{i}.txt
done
とやると{i}が展開されず、

for i in `jot 19` X Y
do
eval gawk '$3!="*"' in{i}.txt>out{i}.txt
done

みたいにやると、$3が変に展開されてしまってうまくいかないです。


何かうまい解決策はないでしょうか?
232 :名無しさん@お腹いっぱい。2011/01/20(木) 10:45:57
>>229
初歩的な質問と回答になりますので、1インシデントで承ります。
お取引の代理店を通じてご用命下さい。
231 :名無しさん@お腹いっぱい。2011/01/20(木) 10:44:18
> 何かうまい解決策はないでしょうか?
shの文法を正しく理解すれば解決する。
233 :名無しさん@お腹いっぱい。2011/01/20(木) 11:03:16
あ”
eval gawk '$3!="*"' in${i}.txt>out${i}.txt
です。写し間違えた。
さらにググり

$cat test.awk
$3!="*"
for i in `jot 19` X Y
do
eval gawk -f test.awk in${i}.txt>out${i}.txt
done

で、うまくいきそうです。
235 :2132011/01/23(日) 15:27:22
仕方ないので自分で作ってみました。指摘ヨロです。
#!/bin/sh
if [ $# -lt 2 ] ; then
echo "Usage: delter.sh tar_file delete_file1 delete_file2 ..."
exit 1
fi
tar_file=$1
if [ ! -f $tar_file ] ; then
echo "tar_fileが存在しません"
exit 1
fi
mkdir dltar_work
cp -p $tar_file dltar_work
cd dltar_work
kind=""
case "$tar_file" in
*.tar.gz)
kind=tar.gz
gzip -cd $tar_file | tar tvf - | sort -k 6 > ../before.txt
gzip -cd $tar_file | tar xvf -
;;
*.tar)
kind=tar
tar tvf $tar_file > ../before.txt
tar xvf $tar_file
;;
esac
237 :名無しさん@お腹いっぱい。2011/01/23(日) 15:36:54
>>235-236
初歩的な質問と回答になりますので、1インシデントで承ります。
お取引の代理店を通じてご用命下さい。
236 :続き2011/01/23(日) 15:28:43
shift
for file in $*
do
find . -name $file -exec rm -f {} \;
done
rm -f $tar_file
if [ "$kind" = "tar.gz" ] ; then
tar cvf - * | gzip > $tar_file
gzip -cd $tar_file | tar tvf - | sort -k 6 > ../after.txt
elif [ "$kind" = "tar" ] ; then
tar cvf $tar_file *
tar tvf $tar_file > ../after.txt
fi
diff ../before.txt ../after.txt
echo "tarファイルを置き換えますか?[yes or no]"
read answer
case "$answer" in
y | yes)
mv -f $tar_file ../
esac
cd ..
rm -rf dltar_work before.txt after.txt
echo done
239 :名無しさん@お腹いっぱい。2011/01/23(日) 16:49:16
execv についてお聞きしたいのですが、
どうして下記コードにおいて eargv[0] = "ls" を書かないと
-al が無効になってただの ls が実行されてしまうのでしょうか。

execv の第 1 引数で ls を指定しているので
eargv[0] で再び ls を指定する必要性がわかりません。

char *eargv[5];
eargv[0] = "ls";
eargv[1] = "-al";
eargv[2] = "/";
eargv[3] = NULL;
eargv[4] = NULL;
execv("/bin/ls",eargv);

初心者なのでとんちんかんな質問かもしれませんが
お返事いただけると嬉しいです
240 :名無しさん@お腹いっぱい。2011/01/23(日) 16:53:21
>>239
エスパーすると、
eargv[0] に "-al" とか指定してるんだろ?
そりゃ無視されて当たり前。
lsコマンド自身は eargv[1] 以降しか引数として認識しない。
eargv[0] は無視される。
ただしコマンドによっては eargv[0]によって動作が変わったりするものがある。
(例: vi と ex とか)
241 :名無しさん@お腹いっぱい。2011/01/23(日) 16:59:02
>>239
それはシェルスクリプトに関する話題ではありません。
と思ったら、OSに依存しない質問スレってないんだね。


> どうして下記コードにおいて eargv[0] = "ls" を書かないと
> -al が無効になってただの ls が実行されてしまうのでしょうか。
書かないというのがどういう意味なのか不明だけど、
多分、eargv[0]がNULLになって以降の引数は渡されないから。
242 :名無しさん@お腹いっぱい。2011/01/23(日) 17:07:25
たとえばログインシェルの起動時は
execvの第1引数が "/bin/sh"、引数配列の最初が "-sh"
だったりするんじゃないの。
243 :名無しさん@お腹いっぱい。2011/01/23(日) 17:35:16
>>240
> エスパーすると、eargv[0] に "-al" とか指定してるんだろ?

説明が悪くて申し訳ないです。そうです。

eargv[0] = "-al";
eargv[1] = "/";
eargv[2] = NULL;
eargv[3] = NULL;
eargv[4] = NULL;

をするとなぜダメなのか、ということが疑問でした。

> lsコマンド自身は eargv[1] 以降しか引数として認識しない。
> eargv[0] は無視される。

そうなんですか! ありがとうございます。勉強不足で……。
試しに >>239 の ls のところを任意の文字に置き換えてみたところ、同じ結果が得られました。
ありがとうございます。NULL ではダメなようですが……。

と思ったら、>>241 さんありがとうございます。
eargv[0]がNULL だと以降の引数は渡されないんですね

>>242 さんもありがとうございました!
244 :名無しさん@お腹いっぱい。2011/01/26(水) 17:55:13
ど初心者の質問で申し訳ないのですが、
catの出力内容やechoでの出力内容を変数に渡す方法ってありますか?
245 :名無しさん@お腹いっぱい。2011/01/26(水) 18:04:56
>>244
それ、シェル初心者からよく聞く質問ですね。
シェルもUNIXも基本が大事。
基本原理を理解していればわかる問題です。
247 :名無しさん@お腹いっぱい。2011/01/26(水) 18:31:04
>>245-246
すみません、ぐぐったらわかりました。
でも全く知らなかったです。ありがとうございます。シングルクオートじゃないんですね。``グレイブアクセント?を使うんですね。
シングルクオートだとただの文字列として解釈されるんですよねたしか。ダブルクオートだと変数名は解釈されるんですよね。
それにグレイブアクセントまたはバッククオートですね、わかりました。ありがとうございます。

でもたしかに基本原理ってなんですか。
248 :名無しさん@お腹いっぱい。2011/01/26(水) 18:45:37
「グレイブアクセント」とはあんまり言わんけどね。

まぁ、まずはシェルスクリプトの本でも読みなよ。
250 :名無しさん@お腹いっぱい。2011/01/26(水) 19:00:05
「アクサングラベ」ともあんまり言わないよ。この辺界隈では。
252 :名無しさん@お腹いっぱい。2011/01/26(水) 19:24:24
「オープニングクォート」とはもっと言わないよ。この辺界隈では。
258 :名無しさん@お腹いっぱい。2011/01/26(水) 20:07:39
A-dev, B-dev....とdevのつくディレクトリがあり
さらに各ディレクトリにpublicディレクトリがあるのですが
全てのpublicディレクトリ内にtest.xml(空ファイルで良い)を置きたいのですが

ls | grep dev
260 :名無しさん@お腹いっぱい。2011/01/26(水) 20:09:50
touch *dev/public/test.xml
262 :名無しさん@お腹いっぱい。2011/01/26(水) 20:14:23
>>260

やってみたか?
264 :名無しさん@お腹いっぱい。2011/01/26(水) 20:16:24
>>262
あーごめん、ぼけてた。
for i in *dev/public; do touch $i/test.xml; done
とかか。
いろいろ穴はあるが。
266 :名無しさん@お腹いっぱい。2011/01/26(水) 20:43:01
>>260 で一発でできるのを無視してまで
>>264 でforループにしたい理由は?
267 :名無しさん@お腹いっぱい。2011/01/26(水) 20:52:45
>>266
一発でできなくね?
シェルによるのかな?
268 :名無しさん@お腹いっぱい。2011/01/26(水) 20:55:50
皆様アドバイスありがとうございます
残念ながら私の環境(CentOS bash)だと
>>260はそんなディレクトリないよと怒られます
261 :名無しさん@お腹いっぱい。2011/01/26(水) 20:13:01
すいません..途中で送信してしまいましたorz

ls | grep dev | xargs

と対象のディレクトリ(〜dev)のリストは入手できたのですが
ここからpublicディレクトリ内にtouchでファイルを作成するところがうまくいきません
対象ディレクトリを引数にして

touch 引数/public/text.xml

のようにできればよいかと考えているのですが
ご教授願います
263 :名無しさん@お腹いっぱい。2011/01/26(水) 20:14:32
>>261
それ、シェル初心者からよく聞く質問ですね。
シェルもUNIXも基本が大事。
基本原理を理解していればわかる問題です。
265 :名無しさん@お腹いっぱい。2011/01/26(水) 20:18:55
>>263
つまんないネタ繰り返すのもうやめない?
270 :名無しさん@お腹いっぱい。2011/01/26(水) 21:15:06
初心者な質問ですみません。
ローカルの/path/以下のファイルを全てをリモートの「/hogehoge/」以下にファイル名変えずアップロードしたいと思いますがうまくいかないので、教えてください。

#!/bin/sh
FDIR=/path

ftp -ivn ftp.exsample.com << _EOF
user username password
bin
passive
cd /hogehoge

for fname in *
do
put $FDIR/$fname $fname
done

bye
_EOF
exit 0

シェルで上記のようにFTPを用いてアップロードする構文を作ったのですが、うまくアップされません。
put $FDIR/$fname $fname
の行を、↓のようにファイル名を直接指定するとうまくいきます。
put $FDIR/test.txt test.txt
271 :名無しさん@お腹いっぱい。2011/01/26(水) 21:16:29
>>270
初歩的な質問と回答になりますので、1インシデントで承ります。
お取引の代理店を通じてご用命下さい。
272 :名無しさん@お腹いっぱい。2011/01/26(水) 21:18:49
>>270
ヒアドキュメントの中で * は展開されない
273 :名無しさん@お腹いっぱい。2011/01/26(水) 21:21:44
>>270
for fname in `echo *`
274 :名無しさん@お腹いっぱい。2011/01/26(水) 21:44:26
>>270
そのftpクライアントって、シェルみたいなfor文を本当に認識するの?
276 :名無しさん@お腹いっぱい。2011/01/26(水) 21:51:55
>>270
(略)

`for fname in *
do
echo put $FDIR/$fname $fname
done`
275 :名無しさん@お腹いっぱい。2011/01/26(水) 21:48:10
インシデント見積り有効期限は24時間以内とさせていただいております。
早めにご用命いただきますよう、お願い致します。
277 :名無しさん@お腹いっぱい。2011/01/26(水) 21:57:59
最終行に改行の含まれていないファイルに改行を付け足して出力するスマートな方法はなんだと思いますか?
最初はこう書いてみたんですけど、
cat ~/file; echo ""
さっき習ったこっちのほうがいいかなと思って下にしてみました。
echo `cat ~/file`
こういう書き方も出来るみたいですが。
echo $(cat ~/file)

好きにしろって言われるのはわかりますが、どういうのがかっこいいですか。俺ならこう格好良く書くってのを教えてください。
278 :名無しさん@お腹いっぱい。2011/01/26(水) 21:59:25
>>277

echo >> file
279 :名無しさん@お腹いっぱい。2011/01/26(水) 22:03:24
>>277
echo `cat file` だと、fileの中の改行や複数のスペースとかがカットされて
表示内容が変わってしまうだろw

cat file; echo
だけでよろし。echoの引数に "" は要らない。
280 :名無しさん@お腹いっぱい。2011/01/26(水) 22:14:20
>>278-279
ありがとうございます。echoの引数が要らないってのは勉強と共に改善点になりました。表示内容が変わってしまうのは気づきませんでした。サンクス。
ファイルに変更は加えたくなかったためcat file; echoでいきます。
281 :名無しさん@お腹いっぱい。2011/01/26(水) 22:18:31
似たような処理で、末尾にl空行がある場合はそのまま、
末尾に空行がない場合だけ空行を付け加えるって、
シェルスクリプトで書こうとすると結構面倒だよね
(たとえば mbox 形式のファイルを処理するときなど)
282 :名無しさん@お腹いっぱい。2011/01/26(水) 22:35:18
そうか?
tacして1行目取ってきて判定→最後に追加だけじゃね?
全行読み込む必要もないし。
285 :名無しさん@お腹いっぱい。2011/01/26(水) 22:57:23
すまん、かぶった。284は >>282 ね
284 :名無しさん@お腹いっぱい。2011/01/26(水) 22:56:39
末尾が空行ではなくて、その行の最後に改行がない場合は?
そういう場合に空行を1行入れるには、改行を2つ追加してやらないといけないが
tacで判定するだけで可能かな?
286 :名無しさん@お腹いっぱい。2011/01/26(水) 23:02:54
最終行に改行がないファイルをtacすると、
最終行とその1つ前の行が結合されて1行目に来てしまう。
それでも空行追加が必要なことは判定できるが、
もともと改行がなかったかどうかは判定できない。

いずれにしても、最終改行がなければ改行追加、の前処理をしてから、
tail -n 1 で判定すれば問題ない。
288 :2812011/01/26(水) 23:17:25
>>286,287
ありがとう。やはり条件判定は複数必要だよね。
なんとなく自信なかったんだけど、これでスッキリした。

> if (ファイルサイズが0バイト) {
なかなかここまで気が回らない。さすがです
287 :名無しさん@お腹いっぱい。2011/01/26(水) 23:04:17
if (ファイルサイズが0バイト) {
ファイルにLFを1つ追加;
return;
}

if (ファイルの最後がLFでない) {
ファイルにLFを2つ追加;
return;
}

if (ファイルの最後からひとつ前がLFでない ) {
ファイルにLFを1つ追加;
}
return;

/* 文字コードはlatin1を仮定(キリッ */
289 :名無しさん@お腹いっぱい。2011/01/26(水) 23:21:57
FILE=file

case `tail -c 2 "$FILE" | wc -l` in
0) echo;;
1) cat "$FILE"; echo;;
*) cat "$FILE";;
esac


ただし、wc -l で頭に余分なスペースが付かない GNU wcを使用のこと。
290 :名無しさん@お腹いっぱい。2011/01/26(水) 23:42:03
>>289
それちょっとおかしいよ。GNU以外のwcでも使えるように修正してみた。



FILE=file

test ! -s "$FILE" && { echo; exit;}

n=`tail -c 2 "$FILE" | wc -l`
n=`echo $n`

case $n in
0) cat "$FILE"; echo; echo;;
1) cat "$FILE"; echo;;
*) cat "$FILE";;
esac
291 :名無しさん@お腹いっぱい。2011/01/26(水) 23:49:18
>>287
ファイルサイズが1バイトでLFのみの場合誤動作する。

>>290
最終行が1文字で改行なしの場合誤動作する。
319 :名無しさん@お腹いっぱい。2011/01/28(金) 12:08:19
>>289,290
case文って何げに使えるよね
293 :名無しさん@お腹いっぱい。2011/01/27(木) 00:09:15
まぁ、当座の課題を解決できればいい質問に
汎用性を求めるのはこのスレの常。
294 :名無しさん@お腹いっぱい。2011/01/27(木) 00:55:59
分岐とか醜いことせず末尾のブランク行全部消してからひとつ付け足した方がスマートに思える。
cat "$FILE" | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'; echo
295 :名無しさん@お腹いっぱい。2011/01/27(木) 01:14:19
それもありかもだけど、そうすると元のファイルを改変することになる
296 :名無しさん@お腹いっぱい。2011/01/27(木) 01:31:29
操作前のデータの末尾にブランク行があったか無かったか判別できなくなってる時点で、元データの保存に意味があるとは思えないが…
298 :名無しさん@お腹いっぱい。2011/01/27(木) 13:18:23
sed '' でどうかな

$ cat /dev/null | sed ''
$ echo | sed ''

$ echo -n a | sed ''
a
$ { echo a; echo b; } | sed ''
a
b
$ { echo a; echo -n b; } | sed ''
a
b
$
299 :名無しさん@お腹いっぱい。2011/01/27(木) 13:23:55
>>298
全然駄目じゃん。空行追加するというお題だぞ
300 :名無しさん@お腹いっぱい。2011/01/27(木) 14:20:28
$mojiretsuに「hogehogefugafuga」が入ってる時

MOJI=`$mojiretsu | sed 's/fugafuga//'`
echo $MOJI
で「hogehoge」が取り出せます。
ところが、訳有りで「`」が使えない場合、どのようにしたら上記と同じ動作が可能でしょうか?
301 :名無しさん@お腹いっぱい。2011/01/27(木) 14:26:47
>>300
echo ${mojiretsu%fugafuga}
302 :3002011/01/27(木) 14:36:32
>>301
回答ありがとうございます。

書き忘れましたが、MOJIに代入してください。
※代入がうまくいかず困ってます
303 :名無しさん@お腹いっぱい。2011/01/27(木) 14:40:19
>>300
>訳有りで「`」が使えない場合
これを具体的に言ったほうがいいよ
304 :名無しさん@お腹いっぱい。2011/01/27(木) 14:41:14
>>302
MOJI=${mojiretsu%fugafuga}
306 :名無しさん@お腹いっぱい。2011/01/27(木) 14:50:47
>>300
どんな訳があるの?
307 :名無しさん@お腹いっぱい。2011/01/27(木) 14:52:11
>>304
できました、ありがとう。

他の煽りの方は放置して失礼します♪
308 :3002011/01/27(木) 15:00:15
>>304
ありがとうございました!

>>306
理由を書くと長くなりますが
大きな「`」の中ですので
311 :名無しさん@お腹いっぱい。2011/01/27(木) 16:12:25
`` の中なら>>304も無理じゃね?
313 :名無しさん@お腹いっぱい。2011/01/27(木) 16:30:50
わざわざ外部コマンドのsed呼び出すより >>304 の方がエレガント
305 :名無しさん@お腹いっぱい。2011/01/27(木) 14:42:04
そんなくだらない「訳有り」な事情を潰す方が健全だと思う
309 :名無しさん@お腹いっぱい。2011/01/27(木) 16:04:59
つまり $() で済む話か。やっぱりくだらない理由だったな。
310 :名無しさん@お腹いっぱい。2011/01/27(木) 16:10:58
>>309
解決後の後出し見苦しい
312 :名無しさん@お腹いっぱい。2011/01/27(木) 16:18:29
>>309
だな。やっぱりだ
315 :名無しさん@お腹いっぱい。2011/01/27(木) 21:15:27
それをさらに入れ子にすると
¥¥` ¥¥`なの?
316 :名無しさん@お腹いっぱい。2011/01/27(木) 21:24:47
>>315
いいえ、3重目のネストは、¥¥¥`¥¥¥` になります。
317 :3152011/01/27(木) 21:29:44
>>316
おぉ、言われてみればその通りだ。
ありがとう。4重目は
¥¥¥¥¥¥¥` ¥¥¥¥¥¥¥`
だね。
320 :名無しさん@お腹いっぱい。2011/01/28(金) 16:13:39
すいません、二つのファイルの比較をして、共通する要素を抽出するのは
どういうコマンドを使ってスクリプトを作ればよいのでしょうか?

ファイル形式はタブ区切りで
一つ目のファイル(リファレンス)には
chr1 20513060 T C
という4つの要素が縦にずらずらっと並んでいます。
二つの目ファイルは
もっと要素も多いです。

やりたい処理は
一つ目と二つ目の要素が完全に一致するものを抽出しファイルに出力する。
出力ファイルの形式は
一つ目のファイルの4つの要素をならべ
その横に二つ目のファイルの3番目以降の要素を並べる、です。

盛りだくさんで書いてしまいましたが、
まずはファイルの要素を比較し、一致した要素を取り出すコマンドが
あれば教えてください。

321 :名無しさん@お腹いっぱい。2011/01/28(金) 16:16:30
>>320
とりあえず一致した要素を取り出すコマンドは
comm
322 :名無しさん@お腹いっぱい。2011/01/28(金) 16:18:49
>>320
盛りだくさんな質問と回答になりますので、2インシデントで承ります。
お取引の代理店を通じてご用命下さい。
323 :名無しさん@お腹いっぱい。2011/01/28(金) 16:19:13
読み返すと意味不明ですね。
一つ目のファイルの要素の例
chr1 20513060 T C
二つ目のファイルの要素の例
chr1 3522454 G R 109 109 60
です。
それぞれのファイルの1番目と2番目の要素を比較する。←知りたいコマンド1
この場合、
chr1 20513060とchr1 3522454は一致しない、となります。

仮に一致した場合
一つ目のファイルの要素の例
chr1 3522454 G A
二つ目のファイルの要素の例
chr1 3522454 G R 109 109 60

出力したいファイルの要素の例←知りたいコマンド2
chr1 3522454 G A  G R 109 109 60

です。検索するキーワードでも教えてもらうだけでも一歩前進です。
よろしくお願いします。
324 :名無しさん@お腹いっぱい。2011/01/28(金) 16:24:38
>>323
そういう処理は awk使った方が楽だが、
あえてシェルでやるなら、
2つのファイルをreadコマンドで1行ずつ読みながら
最初の2つのフィールドのみ比較して
一致していたら要素を並べて echoする。
・・という処理をwhileでループする。
外部コマンドは使わない。
326 :名無しさん@お腹いっぱい。2011/01/28(金) 16:34:53
>>323
ほれ、これでどう?

#!/bin/sh

while read a1 a2 ax
do
while read b1 b2 bx
do
if [ "$a1" = "$b1" ] && [ "$a2" = "$b2" ]; then
echo "$a1" "$a2" "$ax" "$bx"
fi
done < file2
done < file1
327 :名無しさん@お腹いっぱい。2011/01/28(金) 16:46:56
ありがとうございます。ありがとうございます。
>>326は私でも理解できます。
似たようなサンプルがないかawkの解説ページを調べてみます。
perlはやったことがないので今回はやめておきます。
328 :名無しさん@お腹いっぱい。2011/01/28(金) 17:19:28
LLは何か身に付けといた方がいいよ。
シェルスクリプトで苦労してたのがあっさり書けることもある。
330 :名無しさん@お腹いっぱい。2011/01/28(金) 23:07:04
pythonってワンライナーどうやんの?
331 :名無しさん@お腹いっぱい。2011/01/29(土) 01:34:34
>>330
while( life != end ){ do( enjoy ); }
332 :名無しさん@お腹いっぱい。2011/01/29(土) 02:00:57
>>330
ワンライナーは暗黒面。
350 :名無しさん@お腹いっぱい。2011/01/31(月) 02:11:48
>>330
$ python -c 's="hoge";print s'
hoge

最近、いままで perl で書いていたサーバ監視スクリプトなどを
どんどん python にしてる。
perl だと人によって書き方が大きく異なるからメンテナンス性が
悪いな〜と言う事で。
あと、ipython が神。

シェルスクリプトもメンテナンス性でいえば Perl と
似たような感じだけど、十数行のものはシェルスクリプトでも
メンテナンス性をそれほど気にしなくていいし、linuxrc などで
使うことを考えると簡単には捨てることはできない..
351 :名無しさん@お腹いっぱい。2011/02/01(火) 15:02:28
>>350
ループとかifとかどう書くのか知りたいのよ。
333 :名無しさん@お腹いっぱい。2011/01/29(土) 08:10:01
どなたか、鼻毛チェックスクリプトをワンライナーで書いて!
335 :名無しさん@お腹いっぱい。2011/01/30(日) 02:12:16
標準出力の結果をスクリプトで使うにはどうすればいいのでしょうか?
例えば、
telnet (サーバ) 110
stat
とやって、その結果標準出力で出力されるメール数を値として保持しておいて、
その値を元に必要な数だけメールを取得するようにしたいのです。
347 :名無しさん@お腹いっぱい。2011/01/30(日) 11:22:56
perl で NIFTY に telnet 接続してメールや未読記事を取ってくるという
一世を風靡 nifty4u があったね。>>335 が perl でもいいというのなら
参考になるかも。

でも、ふつうに POP クライアントでメール取ってきて、それを
加工すればいいと思うのだけれど、そうじゃなくてわざわざ
POP プロトコルのやりとりをスクリプトでやりたいというのがよくわらかない。
337 :名無しさん@お腹いっぱい。2011/01/30(日) 10:00:18
標準的なものではないんだが、telnetじゃなくてnc(netcat)とかがあれば、それで。
340 :名無しさん@お腹いっぱい。2011/01/30(日) 10:17:19
はいはいexpect expect

ところでexpect以外のtclって生き残っているのだろうか
345 :名無しさん@お腹いっぱい。2011/01/30(日) 10:53:16
>>342
>>340の質問に答えたわけじゃなくて、expectのお題を広げただけなので。
341 :名無しさん@お腹いっぱい。2011/01/30(日) 10:25:17
pyとかrbとかのexpectもあるはず。
zshならソケット作って自分でやりとりもできると思うけどね。
342 :名無しさん@お腹いっぱい。2011/01/30(日) 10:28:56
tcl以外のexpectじゃなくて、
expect以外のtcl
っておっしゃってますが・・
348 :名無しさん@お腹いっぱい。2011/01/30(日) 11:26:56
エスパーすると迷惑メールをPOPで取り込まずにDELEで削除したいとかだろ
STATだけじゃなくてTOPコマンドも併用すると便利
349 :3352011/01/31(月) 01:44:48
みなさんありがとうございます。
与えてくださったヒントを参考にがんばってみます。
迷惑メールとかでは無くて、メーラーを使わずに自分でスクリプトを組んでメールの送受信をできればいいなあ・・・と思ったのです。
352 :名無しさん@お腹いっぱい。2011/02/01(火) 17:02:09
いい加減スレ違いだが……

Pythonはコマンドライン引数だの標準入力だのにアクセスするだけで
import sys
が必要になる時点でワンライナーにはぜんぜん向いてない

向き不向きを無視して可能不可能でいえば、書ける
ただしcompound statement(if, while, for, try, with, defなど)は
セミコロンで区切って一行に書けないので、そうしたものは使えない

もっともifに関しては2.5以降ならif式が使える(それ以前ではand/orで代用)し
ループはmap(), reduce(), 内包表記, ジェネレータ式で代用できる
例外処理はどうにもならないので無理

たとえば
seq 10
をPythonで書くと↓のような感じだ

python -c 'print "\n".join(str(n) for n in range(1, 11))'
353 :名無しさん@お腹いっぱい。2011/02/01(火) 17:37:15
相当なエキスパートじゃないと無理そうだな。使いこなせる人は
すげーわ。
354 :名無しさん@お腹いっぱい。2011/02/01(火) 17:41:40
べつにそんなことはないよ
向いてないのにワンライナーで書こうとすると無理がある、というだけの話
355 :名無しさん@お腹いっぱい。2011/02/01(火) 17:45:31
357 :名無しさん@お腹いっぱい。2011/02/01(火) 17:52:20
>>355
全般に笑えるが、特に例外処理が涙ぐましい&無理やりすぎてワロタw
356 :名無しさん@お腹いっぱい。2011/02/01(火) 17:47:40
ワンライナーの書きやすさとしてはこんな感じでおk?
Perl>>Ruby>>>Python
358 :名無しさん@お腹いっぱい。2011/02/01(火) 17:55:57
ワンライナーで書ける程度の複雑さならawk,sed,sortあたりを
組み合わせた方が楽なことも多いな。
359 :名無しさん@お腹いっぱい。2011/02/01(火) 18:34:30
interfacesなどの設定ファイルの内容を書き換えるスクリプトを作りたいんですが
例えば
address 192.168.10.100
netmask 255.255.255.0
gateway 192.168.10.1
となっていたとして、各項目を置換するにはどういったコマンドを使えば
いいですか?
361 :名無しさん@お腹いっぱい。2011/02/01(火) 18:52:37
>>359
それ、シェル初心者からよく聞く質問ですね。
シェルもUNIXも基本が大事。
基本原理を理解していればわかる問題です。
362 :名無しさん@お腹いっぱい。2011/02/01(火) 19:43:52
>>359
/etc 以下のシェルスクリプトを探してみると
たいていそういう処理をしてるスクリプトが見つかる
363 :名無しさん@お腹いっぱい。2011/02/01(火) 20:09:31
>>361
> それ、シェル初心者からよく聞く質問ですね。
一般的にシェルを作る粋狂なやつはあまりいないから
ほとんどの人がシェル初心者じゃないか?
380 :名無しさん@お腹いっぱい。2011/02/03(木) 18:07:03
>>359
仕事は自分でやれ
364 :名無しさん@お腹いっぱい。2011/02/01(火) 20:11:58
おれ、シェル始めて2週間の初心者だけど、
ハローワールド程度のシェルなら10種類以上作ったよ。
365 :名無しさん@お腹いっぱい。2011/02/01(火) 20:15:43
まぁな
#include <stdio.h>
main ()
{
printf("hello world\n");
}
とか, 書いておいて getty から起動できるようにしておけばシェルだよな
497 :名無しさん@お腹いっぱい。2011/04/09(土) 12:11:51.78
>>496 >>365-373
366 :名無しさん@お腹いっぱい。2011/02/01(火) 20:16:36
それはシェルとは言えないのでは
368 :名無しさん@お腹いっぱい。2011/02/01(火) 20:18:25
>>366 /sbin/nologin もシェルだと思ってるから
367 :名無しさん@お腹いっぱい。2011/02/01(火) 20:16:41
> とか, 書いておいて
コンパイルされたものを <<<< この部分が抜けてた
> getty から起動できるようにしておけばシェルだよな
370 :名無しさん@お腹いっぱい。2011/02/01(火) 20:58:30
ショートコーディング的ワンライナーシェル

s[64];main(){while(printf("> "),gets(s))system(s);}
372 :名無しさん@お腹いっぱい。2011/02/01(火) 22:05:09
/bin/sh利用しないで最低限のシェルにするとこうか? もっと短くならないかな

s[64];main(){while(printf("> "),gets(s))fork()?wait(0):(execlp(s,s,0),exit(1));}
374 :3592011/02/02(水) 21:56:44
>362
具体的に、どんなスクリプトがありますか?
375 :3592011/02/03(木) 11:46:48
分からないままに、書いてみたんですが、添削してください。
#! /bin/sh
# if_rdwr.sh -r address /etc/network/interfaces
# if_rdwr.sh -w address 192.168.12.100 /etc/network/interfaces
if [ $1 != "-r" -a $1 != "-w" ]; then
echo "Second parameter error!"; exit 1
fi
# 引数チェック
if [ $1 = "-r" -a $# -ne 3 ]; then
echo "Wrong parameter"; exit 1
fi
if [ $1 = "-w" -a $# -ne 4 ]; then
echo "Wrong parameter"; exit 1
fi

case $1 in
# Read処理
-r) DATA=(`grep $2 $3`)
VALE=${DATA[1]}
echo $VALE ;;
# Write処理
-w) DATA=(`grep $2 $4`)
VALE=${DATA[1]}
echo -e "%s/$VALE/$3/g\nw" | ed - $4 ;;
esac
376 :名無しさん@お腹いっぱい。2011/02/03(木) 11:50:25
Debian系の/etc/network/interfacesの話なら
書き換えスクリプト自作するより
mappingでも使った方がいいんじゃないの。
379 :名無しさん@お腹いっぱい。2011/02/03(木) 17:55:44
本題と違うけど、引数とパラメータのチェックはcase文のところでまとめて
case $1/$# in
-r/3) ごにょごにょ ;;
-w/4) ごにょごにょ ;;
*) usage ;;
esac
などとやる手がある
386 :名無しさん@お腹いっぱい。2011/02/19(土) 01:18:14
環境はMacなんですが,HandBrakeCLIを使って,あるディレクトリより下(複数階層)の全部のm2tsファイルを違うディレクトリに変換したいです.
その時に,出力先にあるファイルは変換しないようにしたいのです.変換先のファイルは拡張子mp4です.

http://cl.ly/1d0S1e1D0L16261S1U1C

どこだめ?
391 :名無しさん@お腹いっぱい。2011/02/20(日) 11:46:06.85
>>386
> その時に,出力先にあるファイルは変換しないようにしたいのです.

if [ ! -f mp4のパス名 ]; then
 処理
fi
392 :名無しさん@お腹いっぱい。2011/02/22(火) 18:26:12.82
>>391
さすが!!それを聞きたかったのです!!
http://cl.ly/0m0k0B1u323H2n0g411d
かなり短く出来ますたありがとう!!
388 :名無しさん@お腹いっぱい。2011/02/19(土) 11:11:12
板違いでもないと思うが途中ごとに意図した結果になっているか
echoなりcatなりしてみればいいと思う。

sh-bangがzshになってるけどzshの機能はぜんぜん使ってないこととか、
バッチなのに、対話環境用の.zshrcをわざわざ読み込んでいるとことか、
気になった。
389 :名無しさん@お腹いっぱい。2011/02/19(土) 11:44:09
>>388
にゃるほどー・・・zshの機能は全然わかんないですorz
**/*くらいしかw
394 :名無しさん@お腹いっぱい。2011/02/26(土) 09:20:18.93
cat * | grep "xxxx"
でファイル内のxxxx文字列を探したいんですが、ディレクトリやバイナリーを
除外するってできますか
395 :名無しさん@お腹いっぱい。2011/02/26(土) 09:29:00.61
>>394
grep 'xxxx' *
とすれば、ディレクトリやバイナリでも問題ないようにgrepが対応してくれるので、
そもそもディレクトリやバイナリを除外する必要がない。

あと、cat * | grep "xxxx" では、見つかった文字列のファイル名がわからないし、
catが無駄。
396 :名無しさん@お腹いっぱい。2011/02/26(土) 09:31:18.69
>>394
ディレクトリは自動的に除外されるでしょう
バイナリーファイルの除外はGNU grepなら--binary-files=TYPEオプションを使えば可能かと
grep --binary-files=without-match "xxxx" *
399 :名無しさん@お腹いっぱい。2011/03/07(月) 18:51:48.92
bashで書いたスクリプトを、PHPの中からsystemで呼出してたとき、
文字列変数の内容を戻り値として渡すなんて事はできないですよね
400 :名無しさん@お腹いっぱい。2011/03/07(月) 19:04:59.19
UNIXではプログラムの返り値はintです。(ほとんどの場合0-127)
PHPで文字列を受け取りたければ、popenを使いましょう。
401 :3992011/03/07(月) 21:50:03.91
>400
ありがとう、ございます。
スクリプトをsample.shとして
FILE *fd = popen("sample.sh", "r");
while(fgets(str,1024,fp)!=NULL){
printf("%s\n",str);}
みたいにできるんですね。

402 :名無しさん@お腹いっぱい。2011/03/08(火) 14:30:09.29
家族から鯖の電気代でクレームが来たので作ってみた。
クライアントの生死判定をし、鯖をシャットダウン 起動はwolを使用
想定する鯖はsambaを搭載したファイル鯖など
使用方法はcronに登録し、root権限で一定間隔で走らせる
文法はタコなんでかんべんして


#!/bin/sh
NODE=51
LOCKFILE=/var/lock/shutdown
PING_COUNT=2

if test -f ${LOCKFILE}
then
        PING_COUNT=`cat ${LOCKFILE}`
fi

while [ ${NODE} -le 200 ]
do
        ping -c 1 192.168.1.${NODE} > /dev/null 2>&1
        if test $? -eq 0
        then
                if test -f ${LOCKFILE}
                then
                        rm ${LOCKFILE}
                fi
                exit 0
        else
                NODE=`expr ${NODE} + 1`
        fi
done
407 :名無しさん@お腹いっぱい。2011/03/08(火) 15:40:10.31
>>402
俺もエコワット調べでDellのE2180あたりの石が入った
サーバで月に2500円くらい掛かっていたが、5万ほどのI5のノートを
サーバにしたら、月に350円程度になったよ。

当然24時間での話だけどね、W7でファイルサーバを使い
夜半から深夜の遊びようのクライアントにも使い
抱かせたvmwareで稼働したLinuxでファイルサーバやWebサーバに他
昼間は会社からリモートデスクトップとsshで手元に表示させ
為替や株の表示や売買も
他には家屋の周囲の防犯監視カメラ録画ともやってる

電気代は週計測の平均を4倍した感じで誤差はあっても500円程度だろ
そと付けの24インチディスプ2台とか、必要時に随時稼働させる
USBの外付けHDDは勘定だけどね。

下手な小細工より、省エネ機器に交換した方が良いよ
405 :名無しさん@お腹いっぱい。2011/03/08(火) 14:50:16.64
クレーム来るほどの電気代ってペン4でも使ってるのか?
鼻毛あたりに交換すれば24時間通電でも省エネだよ。
406 :名無しさん@お腹いっぱい。2011/03/08(火) 15:27:33.67
>>405
犯人はST31000340NS*2だよ。(ワットチェッカー読み)
ママンはD945GCFL2 2GB
あと電源、アクセスランプがうざいと
409 :名無しさん@お腹いっぱい。2011/03/08(火) 16:08:55.05
こっちもあるよ。

自宅鯖PCにいくら電気代が掛かってるか晒すスレ
http://hibari.2ch.net/test/read.cgi/mysv/1095600824/
410 :4022011/03/08(火) 16:09:51.75
電気代
28日間499kwh@東電

クライアントは

デスクトップ1
E8500+P35 4GB
HD5770
winXP

デスクトップ2(妹所有)
プ530+915P 2GB
9600GT
winXP

ノートPC1
IBM/lenovo
T42p mem 2GB

ノートPC2(使用頻度低)
toshiba E7 418cme
の4台

妹にPC更新しろというが
プーなので3点交換になるので金掛かるので嫌がっている
これが電気食いだろう
411 :名無しさん@お腹いっぱい。2011/03/08(火) 16:19:57.94
>>410
つかクライアントの電気代も考えてるの?
なんか構成と目的が見えないわ

サーバって何を目的にしてるんだろう?
ファイル目的なら、ネットワーク対応のドライブでも下げれ
ば良さそうだし。
412 :名無しさん@お腹いっぱい。2011/03/08(火) 16:33:13.56
>>411
主に稼働しているデーモンは
apache 2.2
proftpd
squid 2.7
dnsmasq
samba
ntp 4.2.4p4
sshd
snmpd
その他管理ツール

おもにISO倉庫になっている
他にも玄箱があるがsquid走らせるにはきつ過ぎる
プロバイタが*.ap.yournet.ne.jpだから403サイトはIP偽装は必須だし
413 :名無しさん@お腹いっぱい。2011/03/08(火) 16:57:29.39
>>412
クライアントの居ないときに消滅させられるなら
クライアントにvmwareでも仕込めば良さそうだがなぁ?

まぁ、いずれにシテもATOM/I3でSSDでいいんじゃねーの?
sambaの用途次第で2.5インチHDD
414 :名無しさん@お腹いっぱい。2011/03/08(火) 17:45:52.70
ぜんぜんシェルスクリプトの話じゃないな。
415 :名無しさん@お腹いっぱい。2011/03/09(水) 01:00:32.19
>>414
シェルスクリプトの話がじゃまされたくないほど
大量にあるなら、ジャンジャンどうぞ
416 :名無しさん@お腹いっぱい。2011/03/09(水) 01:25:58.69
話題がなければ関係ない話をしていいってもんでもないよ。
417 :名無しさん@お腹いっぱい。2011/03/09(水) 14:35:33.41
>>416
俺も喪前も含めて、そういう関係ない部分が保守となり
活性化の助けになるんだよ。

418 :名無しさん@お腹いっぱい。2011/03/11(金) 21:42:37.11
下のようなスクリプトaddress.shをperl/CGIから
$addr = `address.sh -a`
$gate = `address.sh -g` と呼び出すと、-aはデータが得られず、-gはデータが
取得できます。
ターミナルからの実行では、どちらもデータを返しています。
なぜでしょうか?
#!/bin/sh
case $1 in
-a) DATA=$(/sbin/ifconfig eth0 | grep inetアドレス | awk '{print $1}' | awk -F: '{print $2}') ;;
-g) DATA=$(/sbin/route -n | grep UG | awk '{print $2}') ;;
esac
echo $DATA

OSはDebian5 -aはifconfigの出力からIPアドレスを選んでechoします
-gはroute -nの出力からデフォルトゲートウエイを選んでechoします
419 :名無しさん@お腹いっぱい。2011/03/11(金) 22:00:56.54
>>418
LANGによって出力メッセージが変化している。
"inetアドレス"の部分はLANG=Cだと"inet addr"
UGはたまたまLANG=jaでも拾えただけ。
スクリプト内で明示したほうが良いね。
421 :4182011/03/12(土) 14:09:39.29
>>419 420
原因が分かりました。ありがとうございます
422 :名無しさん@お腹いっぱい。2011/03/15(火) 18:20:18.05
シェルで、telnet xxxx 110に接続し、user、passwd、STAT、QUITを
telnetのプロンプトに入力することってできますか?
424 :名無しさん@お腹いっぱい。2011/03/15(火) 19:24:49.82
質問の意図からすると、rshのような感じでできるかどうか訊いているんだろうが、
基本的にはできない。
特別なユーティリティを使って、無理矢理対話させることもできるが、
とてもめんどくさくなるから普通はやらない。
だから、その程度のことをやるときは、Perlなどでソケット通信を使う方が簡単でわかりやすい。
426 :名無しさん@お腹いっぱい。2011/03/15(火) 20:02:09.16
expectのsampleに似た感じのが付いてるから、
それ見て書けばいいんじゃない?

>>424
たぶんtelnetに対するredirectを駆使して出来ないか聞いたんだと思われ
427 :名無しさん@お腹いっぱい。2011/03/15(火) 21:17:22.34
expectって名前くらいしか知らんかったけど、
マニュアル見たら、コネクション維持したまま制御をスクリプトに持ってくるなんてこともできるのか。

>>426
「rshのような感じ」とは、その意味だよ。
432 :名無しさん@お腹いっぱい。2011/03/16(水) 12:22:29.81
telnetじゃないが例えばこんな感じであれば(機能が有効になってたら)可能。
#!/bin/bash

exec 5<>/dev/tcp/localhost/631
echo -en "GET / HTTP/1.1\n\n" >&5
while read line <&5
do {
    echo "$line"
}
done
442 : 忍法帖【Lv=17,xxxPT】 2011/03/16(水) 20:53:11.21
bash は、以下の表にあるようなファイル名がリダイレクトに使用されると、それらを特別に扱います。

/dev/fd/fd
fd が有効な整数ならばファイル・ディスクリプター fd が複製されます。
/dev/stdin
ファイル・ディスクリプター 0 が複製されます。
/dev/stdout
ファイル・ディスクリプター 1 が複製されます。
/dev/stderr
ファイル・ディスクリプター 2 が複製されます。
/dev/tcp/host/port
host が有効なホスト名またはインターネットアドレスで port が整数のポート番号ならば、 bash は対応するソケットに対して TCP 接続のオープンを試みます。
/dev/udp/host/port
host が有効なホスト名またはインターネットアドレスで port が整数のポート番号ならば、 bash は対応するソケットに対して UDP 接続のオープンを試みます。

ファイルのオープンや作成に失敗すると、リダイレクトも失敗します。
---
これか。
>>432試したんだけど自分とこ/dev/tcpが無かった。
433 :名無しさん@お腹いっぱい。2011/03/16(水) 12:44:40.11
OS依存か
434 :名無しさん@お腹いっぱい。2011/03/16(水) 12:51:37.28
>>433
OS依存じゃなくてbash依存。

/dev/tcpネタで恥晒してた回答者が何スレか前にいたの思い出したw
438 : 忍法帖【Lv=17,xxxPT】 2011/03/16(水) 19:46:39.72
>>434
どの辺りがbash依存なのか教えて
bangの部分じゃないよね
439 :名無しさん@お腹いっぱい。2011/03/16(水) 20:03:57.81
440 :名無しさん@お腹いっぱい。2011/03/16(水) 20:13:06.08
>>438
/dev/tcp/とか/dev/udp/は
そういう機能を有効にしたbashであれば利用できる
ってこと

>>439 こっち
http://linuxjm.sourceforge.jp/html/GNU_bash/man1/bash.1.html
441 : 忍法帖【Lv=17,xxxPT】 2011/03/16(水) 20:46:52.61
>>439-440
おぉレス返ってきた!
ありがとう。リンク先読んでじっくり勉強して来ます
436 :名無しさん@お腹いっぱい。2011/03/16(水) 17:22:36.31
でもその方法だと、POPやSMTPなんかでは使えないね。
437 :名無しさん@お腹いっぱい。2011/03/16(水) 19:01:31.50
>>436
いや、できるけど?
<&3, >&3すればいいので。
444 :名無しさん@お腹いっぱい。2011/03/17(木) 04:30:46.33
>>437
セッション維持したまま、応答に対して分岐できるの?
445 :名無しさん@お腹いっぱい。2011/03/17(木) 06:16:05.07
>>444
できる。
だからこそ、最初に exec 5<> とかで同じソケット開きっぱなしにしてるんだろ。
446 :名無しさん@お腹いっぱい。2011/03/17(木) 11:16:15.68
>>444
シェルスクリプトのファイルI/Oを理解出来てないね。
447 :名無しさん@お腹いっぱい。2011/03/18(金) 08:56:39.45
あるディレクトリの一番新しいファイル一個てどうやって抽出できる?
450 :名無しさん@お腹いっぱい。2011/03/18(金) 09:42:02.26
出力がパイプだと端末以外になるから-1がデフォなんで
いちいち書かなくても-tだけでいいよ。
451 :名無しさん@お腹いっぱい。2011/03/18(金) 10:54:08.46
>>450
$ ls -lt | head -1
total 14116088
$ ls -1t | head -1
gonzui.log

'-l'の結果に笑った

ちなみに
$ ls -lt | head -n3
total 14116088
-rw-r--r-- 1 hoge staff 1132 3 15 22:39 gonzui.log
-rw-r--r-- 1 hoge staff 64 3 12 22:42 k.txt
って感じになっている。
464 :名無しさん@お腹いっぱい。2011/03/19(土) 08:47:25.04
>>450
ありがと!!
465 :名無しさん@お腹いっぱい。2011/03/19(土) 15:27:14.48
>>450
BSD由来の機能だからSVR3とか違うUNIXもあるぞw
452 :名無しさん@お腹いっぱい。2011/03/18(金) 14:01:44.16
明示的に -l つければそりゃそれ使うわ。
ls -t | でいいってこと。
453 :名無しさん@お腹いっぱい。2011/03/18(金) 14:07:28.85
-h | --help とオプションつけたいんだけどどうすりゃいい?
外部コマンド使わないと無理?
459 :名無しさん@お腹いっぱい。2011/03/18(金) 18:50:54.63
>>453
たぶんbuilt-inでgetoptsがあるはず
POSIX規定の外部コマンドのgetoptもあるんじゃないか?
471 :名無しさん@お腹いっぱい。2011/03/25(金) 18:01:22.21
>>453
see /usr/bin/autoconf
454 :名無しさん@お腹いっぱい。2011/03/18(金) 14:20:24.77
case "$1" in
-h|--help)
なんだかんだ;
;;
esac
455 : 忍法帖【Lv=18,xxxPT】 2011/03/18(金) 14:52:36.60
>>454
hoge -v -s -x -g -d -h
hoge -v -s -h -g -d -x
460 :名無しさん@お腹いっぱい。2011/03/18(金) 19:03:31.35
getoptsってbashだけじゃなかったっけ?
461 :名無しさん@お腹いっぱい。2011/03/18(金) 19:20:09.48
>>460
SunOSのshにすらある
466 :名無しさん@お腹いっぱい。2011/03/20(日) 19:33:21.00
zshのパス設定はどこで行うべきでしょうか?
bashと同様に、.zprofileで環境設定$PATHに設定すればとりあえず良さそうなのですが、
ネットで調べると、.zshenvでシェル変数pathに設定しているケースをよく見かけます。
それぞれの設定方法の違いや利点などがあれば教えていただけないでしょうか。
467 :名無しさん@お腹いっぱい。2011/03/20(日) 20:11:43.50
468 :名無しさん@お腹いっぱい。2011/03/25(金) 10:46:26.53
複数のディレクトリを処理していくスクリプトを/bin/shで作っています。
既に処理済みのディレクトリをスキップしたいのですが、処理済みリスト
の保持方法で詰まっています。
ファイルに保存してgrepするというのを考えましたが、ダサいし、削除処
理が面倒なので、オンメモリで保持したい。どのように保持すればよいでしょう?

制約:
該当ディレクトリにcookieファイルを作成することはできません。(リードオンリーの場合もある)
/bin/sh限定です。(配列は使用できません)
その他条件:
ディレクトリ数は高々数百です、1000を大きく超えることはありません。
472 :名無しさん@お腹いっぱい。2011/03/25(金) 18:34:39.29
>>468
別の場所にディレクトリ構造のミラーだけつくっといたら

たとえばGNUのdiffなら
diff --brief mirror1 mirror2
でディレクトリ構造の差分が取れると思うので、
LANG=Cで実行して出力をパースすればいいと思う
473 :名無しさん@お腹いっぱい。2011/03/26(土) 00:27:58.51
>>468
単純にリストをシェルのパラメータに保存するのはだめなの?
概念的にはこんな感じで。 linux 環境なんで bash の /bin/sh エミュでしか試してないけど。
注1: ディレクトリ名に改行文字が含まれていないことが前提
注2: sed, grep に渡す $1 は、そこに含まれる正規表現メタ文字をエスケープしといて

#!/bin/sh

NL='
'
LIST=''

list_append() {
 LIST="${LIST}${NL}${1}"
}

list_has() {
 echo "$LIST" | grep "^${1}\$" >/dev/null 2>&1
}

list_remove() {
 LIST="$(echo "$LIST" | sed "\:^${1}\$:d")"
}
469 :名無しさん@お腹いっぱい。2011/03/25(金) 11:52:45.83
checked_ディレクトリ名=1 とかしときゃいいんじゃねーの?
475 :4682011/03/26(土) 11:31:57.59
>>469,473を参考にこうしました。チェックにexprを使ったらarglistの
制限に引っかかったので、caseで逃げました。
# Usage: member elt list
member()
{
local list_name -
list_name="list_$2"
eval case \""\$${list_name}"\" "in *:$1:*) true;; *) false;; esac"
}
# Usage: append_list list elt
append_list()
{
local list_name -
list_name="list_$1"
member "$2" "$1" && return 1 || eval ${list_name}=\"\${${list_name}:-:}$2:\"
}
# Usage: empty_list tag
empty_list()
{
local list_name -
list_name="list_$1"
eval unset "${list_name}"
}
474 :名無しさん@お腹いっぱい。2011/03/26(土) 11:13:25.73
未処理のディレクトリのリストアップだけをする部分と
実際に処理を行う部分をパイプで繋ぐという作りにする。

ことはできないのだろうか。
476 :名無しさん@お腹いっぱい。2011/04/01(金) 19:42:04.11
ルート権限が必要なスクリプトで、スクリプトを実行してるのが
rootかどうかをチェックするにはどうすれば良いですか?
478 :名無しさん@お腹いっぱい。2011/04/01(金) 21:49:05.90
>>476
俺は↓こんな感じで動かしてるわ。

if [ ! `whoami` = "root" ]; then
echo "このプログラムはroot権限が必要です。"
exit
fi
479 :名無しさん@お腹いっぱい。2011/04/01(金) 22:52:59.52
「ルート権限」と書いてあるのでおそらく superuser かどうかを知りたいのだと思うけど、
その場合それを知る律儀な方法はUID(EUID) が 0 かどうかを調べる。
superuser(UID=0) のユーザ名が必ずしも "root" とは限らないから。(まあ99% root だろうが)

posix sh 互換なら [ ${EUID:-${UID}} = 0 ] あたりが無難だろうか。
481 :名無しさん@お腹いっぱい。2011/04/02(土) 13:21:39.17
ルート権限が必要なコマンドでフェイルするからあえて調べない。
必要な場合はスクリプトファイルをchmod go-rxだな。
482 :sage2011/04/03(日) 00:58:03.42
コマンドラインにパイプ等で渡して
バイナリ表示した文字列を復元する方法を教えていただけないでしょうか。

$echo 'あいうえお' | od -Ax -tx1
000000 e3 81 82 e3 81 84 e3 81 86 e3 81 88 e3 81 8a 0a
↑上記を「あいうえお」に戻したいです

すみません
483 :名無しさん@お腹いっぱい。2011/04/03(日) 01:11:56.48
echo 'あいうえお' | od -Ax -tx1 | awk '{ $1 = ""; for (i=2;i<NF;i++) { print $i }}' | while read i; do printf "\x$i"; done
あいうえお
490 :名無しさん@お腹いっぱい。2011/04/03(日) 22:48:02.12
>>483
awkのみで

awk '{ $1 = ""; for (i=2;i<=NF;i++) { printf("%c", strtonum("0x" $i)); }}'
484 :名無しさん@お腹いっぱい。2011/04/03(日) 01:13:07.28
i<=NFの間違い
487 :名無しさん@お腹いっぱい。2011/04/03(日) 01:47:30.95
>>484
たすかりました
485 :名無しさん@お腹いっぱい。2011/04/03(日) 01:26:11.78
cd "$1"
targets=`find . -name "filename" -type d`

if [ ${#targets[@]} = 0 ] then; do
echo "該当するファイルはありません。"
exit
fi

for tmp in ${targets[@]}; do
echo $tmp
done

こんな感じで文字列に該当するディレクトリの一覧を出力したいのですが、
配列の要素数でファイルがない場合を分岐しようとすると該当ファイルがなくても要素数が1になってしまいます。
良い方法はないでしょうか?
486 :名無しさん@お腹いっぱい。2011/04/03(日) 01:36:39.88
if [ -z "${targets[1]}" ]; then
488 :名無しさん@お腹いっぱい。2011/04/03(日) 01:59:14.44
>>486
0オリジンだぜ。
489 :名無しさん@お腹いっぱい。2011/04/03(日) 21:50:28.46
配列の開始索引番号は zsh が 1、bash が 0。
(zsh は ksh_arrays オプションで変更可能)
491 :名無しさん@お腹いっぱい。2011/04/09(土) 09:34:35.16
rcs管理してるファイルに昔書いたけど今は削除してしまったキーワードが書いてあった
バージョンだけさっと取り出すようなシェルってできる?
493 :名無しさん@お腹いっぱい。2011/04/09(土) 11:20:35.26
shellを新たに作るとは精力が余っているのですね
ガンバレー
494 :名無しさん@お腹いっぱい。2011/04/09(土) 11:36:58.18
おまえら「シェル」に突っ込んでるけど、
「シェルスクリプト」って質問に書いてあったら
答えられないんだろww
495 :名無しさん@お腹いっぱい。2011/04/09(土) 11:52:37.00
煽らずに、ごめんなさいして質問しなおせば教えてやったのに。残念だな。
498 :名無しさん@お腹いっぱい。2011/04/09(土) 15:59:51.48
>>495
おれ、質問者じゃなくて回答者の立場だけど、
じゃあ、ちなみに >>495 が知ってる回答を先に答えてみ。
(まあ、知ったかだろうから無理だろうけど)

>>495 がギブアップしたら俺が答えるから。
499 :名無しさん@お腹いっぱい。2011/04/09(土) 16:08:15.63
>>498
素直にごめんなさいすれば、教えてやったのに残念だな。w
500 :名無しさん@お腹いっぱい。2011/04/09(土) 16:12:37.65
>>499
おれ回答者だよ。お前やっぱり知らないんだな。
501 :名無しさん@お腹いっぱい。2011/04/09(土) 16:14:41.27
>>498
はいはい。ギブアップ。お前が教えてやれ。www
496 :名無しさん@お腹いっぱい。2011/04/09(土) 11:59:50.79
用途を限定した簡易版なら、シェルを書くのはそう難しくないんじゃないかな
シェルを作ると言ってる人が一から書き始めるとも限らないし
503 :名無しさん@お腹いっぱい。2011/04/10(日) 01:16:57.74
消えた自称回答者に代わって、まずは叩き台をばばば

for rev in `rlog FILE | grep '^revision ' | cut -d' ' -f 2-`
do
 if co -p$rev FILE 2>/dev/null | grep KEYWORD > /dev/null; then
  echo "KEYWORD found in $rev"
  break
 fi
done
504 :名無しさん@お腹いっぱい。2011/04/10(日) 13:03:24.87
単精度計算を簡単に行う方法について教えてください。
505 :名無しさん@お腹いっぱい。2011/04/14(木) 20:39:04.99
>>504
echo "1.1 * 2.2" | bc
みたいな感じとかは?
508 :名無しさん@お腹いっぱい。2011/04/15(金) 06:38:20.71
>>505-507
ありがとうございます。
507 :5052011/04/14(木) 21:39:13.89
いや任意精度ですね。
$ echo "scale=99;1/7" | bc
.1428571428571428571428571428571428571428571428571428571428571428571\
42857142857142857142857142857142

小数演算がしたいのかと勝手に思い込んだ。厳密に「単精度」「倍精度」を期待してたならスマソ。
509 :名無しさん@お腹いっぱい。2011/04/17(日) 01:23:14.03
引数に渡した文字『あいう』を、『*あ*い*う*』に変換したいのですが、うまくいきません。
スマートに変換できる方法、ありませんでしょうか?
510 :名無しさん@お腹いっぱい。2011/04/17(日) 01:45:19.21
echo "あいう" | sed -e 's/\(.\)/*\1/g' -e 's/$/*/'
511 :名無しさん@お腹いっぱい。2011/04/17(日) 01:54:37.16
>>510
早速試してみます。ありがとうございます!
519 :名無しさん@お腹いっぱい。2011/04/18(月) 23:55:29.21
perlで>>510の正規表現使えば?
512 :名無しさん@お腹いっぱい。2011/04/17(日) 03:53:00.70
Taro and Mary having sex.
なんつうテキストがあったときに、awkでandの前後を拾いたい、
ただしandはANDとかAndとかかもしれない、という状況で、以下の事を知りたいです。
・大文字小文字無関係でandを区切りとしたい場合、
awk -F [Aa][Nn][Dd]
で実現はできたのですが、他によい方法はありますか?
区切りとしたい単語が長くなると、指定が厄介だと思ってます
IGNORECASEを設定しても、/〜/の正規表現の箇所でしか有効でないようです
・区切りの前後の単語を拾うとき、例えば区切りの前を拾うときは
awk -F [Aa][Nn][Dd] '{print $1}' | awk '{print $NF}'
としているのですが、awkを二回使ったりしているあたりが
改善の余地があるのではないかと思ってます
他によい方法はありますか?
513 :名無しさん@お腹いっぱい。2011/04/17(日) 07:43:14.48
>>512
echo a and b c d And e | awk -v RS=" " -v IGNORECASE=1 '!/and/{b=$0}/and/{print b;geline;print}'
a
b
d
e
514 :名無しさん@お腹いっぱい。2011/04/17(日) 13:53:07.68
>>513
なるほど
andでなければ退避、andなら退避したものと次の行を表示、ですね
ありがとうございました
517 :名無しさん@お腹いっぱい。2011/04/18(月) 00:30:16.46
>>514 plus
awk -v NF = substr([a-A],[^n-N],[^d-D]) '{print $1}' | awk -f ... '{print $NF}'
走査確認はして居りませんが・・・
515 :名無しさん@お腹いっぱい。2011/04/17(日) 15:21:21.61
しかしなんつう例文だw
516 :名無しさん@お腹いっぱい。2011/04/17(日) 23:37:18.81
>>515 plus
否、英文で・・・
518 :5112011/04/18(月) 23:11:38.09
2バイト文字が入ったら、うまく判定されませんでした。
echo "あいう" | sed -e 's/\(..\)/*\1/g' -e 's/$/*/'
とやると2バイト文字は判定されるんですが、今度は1バイト文字が判定されません。
なにが問題か、ご教授お願い致します。
520 :名無しさん@お腹いっぱい。2011/04/19(火) 02:32:27.94
いまどき(マルチバイト)エンコーディングに対応してない sed なんてあるの?
523 :名無しさん@お腹いっぱい。2011/04/19(火) 12:40:22.96
sed 's@/lib\(64\)\?/ld@/tools&@g'
と言うスクリプトの場合、@は何の意味?
525 : 忍法帖【Lv=32,xxxPT】 【東電 85.2 %】 株価【E】 ◆BF8VbhPxrY 2011/04/19(火) 12:51:46.55
>>523
man sed

sed 's/\/lib\(64\)\?\/ld/\/tools&/g'
これより見やすいだろ?

次からはLFSスレで聞けよ
550 :名無しさん@お腹いっぱい。2011/04/21(木) 09:13:02.17
>>549
>>523

最初からsedで質問されてますが、、
551 :名無しさん@お腹いっぱい。2011/04/21(木) 09:33:03.02
>>550
死ねクズ。
直近のsedの話題は>>539-543。>>523を追い出したいならアンカー付けろ。
524 :名無しさん@お腹いっぱい。2011/04/19(火) 12:45:46.59
sed 's#そんなことも知らんのか#あほか#'
と言うスクリプトの場合の、#と同じ意味
526 :名無しさん@お腹いっぱい。2011/04/19(火) 13:05:18.92
sed の正規表現を perl と共通にしといてくれよと
思うことは時々ある

# だったら perl 使えよ
529 :5232011/04/19(火) 18:41:53.23
そうかs直後の文字が区切り文字として認識されるのね
どうもです

530 :名無しさん@お腹いっぱい。2011/04/19(火) 19:45:35.17
ファイルの内容を、そっくりそのまま変数に入れたいと考えてます

AAA=`cat /etc/hosts`とすると、変数echo $AAAで内容が確認できたので
この調子でやればよいかと思っていたのですが、ファイル内に書いてある*が
展開される(?)のか、Cのソースを読ませた時はコメントの/*が/usrだの/etcだのに
展開されたり、*がカレントディレクトリのファイル一覧になったりと、
意図した結果が出ずに悩んでいます

対処法って、ありますか?
531 :名無しさん@お腹いっぱい。2011/04/19(火) 19:58:56.42
>>530
echo "$AAA"
532 :5112011/04/19(火) 23:23:03.44
sedのバージョンをアップしたら解決しました。
ありがとうございました。
533 :名無しさん@お腹いっぱい。2011/04/20(水) 19:30:24.29
テキストで、ある単語以降を削除したいと思ってます

イメージとしては
aaa bbb ccc
ddd eee fff
ggg hhh iii
というファイルについて、eee以降を削除して
aaa bbb ccc
ddd
という結果を得たいです

いったん、sed s/eee/?
eee/ と改行させてから、sed /eee/,$dと行単位の範囲削除やってるのですが
何か無駄な気がしてます
552 :名無しさん@お腹いっぱい。2011/04/21(木) 09:37:44.06
>>551
>>533 も最初からsedの質問してるな。
554 :名無しさん@お腹いっぱい。2011/04/21(木) 10:27:32.49
>>552
>>533 は自分はsedを使ってやってみた、と書いてるだけで、
必ずしもsedでの解法を求めているわけではないように見える。
535 :名無しさん@お腹いっぱい。2011/04/20(水) 19:40:58.21
あ、GNU sedだとなくても通ったけど、正しくは、qの後ろにも;がいるかも。
536 :名無しさん@お腹いっぱい。2011/04/20(水) 19:45:03.93
>>535
こういうやりかたがあるのですね

当方AIX5のsedですが、試してみます
537 : 忍法帖【Lv=33,xxxPT】 2011/04/21(木) 00:17:24.25
$ sed 's/eee/{s/eee.*//;q}' test.txt
sed: bad option in substitution expression

$ sed 's/eee/{s/eee.*//;q;}' test.txt
sed: bad option in substitution expression

こうなった
548 :名無しさん@お腹いっぱい。2011/04/21(木) 08:24:13.28
>>537-538
最初の/eee/はsコマンドじゃなくて、アドレス指定だからな。
539 :名無しさん@お腹いっぱい。2011/04/21(木) 00:50:54.36
質問です。

以下のファイルがあるとします。
----------
$ cat hoge.dat
aaa
bbb
ccc
ddd
eee
----------

このファイルを先頭からよんでゆき、最初に見つかったCCCの行から下全部を表示するにはどうしたらいいでしょうか?

よろしくご教示お願いします。
540 :名無しさん@お腹いっぱい。2011/04/21(木) 00:55:23.11
>>539

sed -n '/^ccc/,$p' hoge.dat
541 :名無しさん@お腹いっぱい。2011/04/21(木) 01:00:34.54
>>540
できた!
まじ、ありがとうございます!
544 :名無しさん@お腹いっぱい。2011/04/21(木) 06:17:08.22
sedの話題はsedスレ池。

sed
http://hibari.2ch.net/test/read.cgi/unix/1085730992/
545 :名無しさん@お腹いっぱい。2011/04/21(木) 06:22:55.60
>>544
死ね
546 :名無しさん@お腹いっぱい。2011/04/21(木) 08:02:47.16
>>545
なんで?
549 :名無しさん@お腹いっぱい。2011/04/21(木) 08:55:44.46
>>544
死ねクズ。
質問者はsed一発で出来ると思わなかったからこのスレで質問した。
なんの問題もない。
553 :名無しさん@お腹いっぱい。2011/04/21(木) 09:40:05.63
なら、それにアンカー打て。カス。
555 :名無しさん@お腹いっぱい。2011/04/21(木) 14:04:10.51
>>553
涙拭けよ
556 :名無しさん@お腹いっぱい。2011/04/21(木) 14:13:13.22
ちょっとsedの話題出たからってすぐ誘導するのはいかがなものか?
心の狭いお方だ
559 :名無しさん@お腹いっぱい。2011/04/21(木) 14:30:35.47
誘導するなら質問直後にやれば?
回答が出終わってるんだから黙ってたらいいのに
560 :名無しさん@お腹いっぱい。2011/04/21(木) 14:33:52.19
たまたまその時見てなかっただけじゃない?
誘導ってそんな怒るほどのことなのかな。
564 :名無しさん@お腹いっぱい。2011/04/21(木) 17:16:21.90
>>560
別に怒ってるわけじゃないよ
ただ鬱陶しいだけ
565 :名無しさん@お腹いっぱい。2011/04/22(金) 01:11:15.11
質問です。

以下の形式のファイルを、
----------------------
[2011.04.01]
123
123
[2011.04.02]
333
333
[2011.04.03]
444
444
----------------------

以下のように、3つに分割するシェルスクリプトを書くにはどうしたらよいでしょうか?
----------------------
[2011.04.01]
123
123
----------------------
[2011.04.02]
333
333
----------------------
[2011.04.03]
444
444
----------------------
566 :名無しさん@お腹いっぱい。2011/04/22(金) 01:38:57.62
csplit file.txt '/^\[.*\]/' '{*}'
613 :>>5652011/04/24(日) 01:17:07.38
>>566
回答ありがとうございます。
試してみたところ、以下のようにエラーになります。
$ csplit file.txt '/^\[.*\]/' '{*}'
csplit: *}: bad repetition count

当方、freebsd5.4を使っております。
$ uname -a
FreeBSD japan 5.4-RELEASE FreeBSD 5.4-RELEASE #0: Sun May 8 10:21:06 UTC 2005 root@harlow.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386

マニュアル見るとfreebsdではnumに*を指定することはできないようです。。。
なにか回避策はありますでしょうか
615 :名無しさん@お腹いっぱい。2011/04/24(日) 09:20:33.70
>>613
まず、grep -c "\[.*\]" file.txtで、マッチする数を求める。
その数から2を引いた数を、アスタリスクのかわりに指定する。
567 :名無しさん@お腹いっぱい。2011/04/22(金) 19:42:27.95
$ t1() { echo a; echo b; return; echo c; }
$ t1
a
b
ふむ

$ t2() { echo a; echo b |return; echo c; }
$ t2
a
c
えー!

サブシェル内は別環境って忘れててやられたわ
エラー出ないのは仕様?他のどのシェルもこうなの?

$ bash --version
GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
569 :名無しさん@お腹いっぱい。2011/04/22(金) 20:38:30.06
>>568 は、>>567 の意味を理解してないなw
エラー出ないのは、文法的には間違ってないので、それで仕様。
kshやzshだとパイプがサブシェルにならないから、
パイプ中のreturnで関数から抜けられる。
570 :名無しさん@お腹いっぱい。2011/04/22(金) 23:59:49.99
>>569
理解してないのはお前。バカは黙ってればいいのに。ww

>>567-568の意味は、bashやashはパイプの尻尾がサブシェルになるから(だから
echo cが実行される)、本来functionからの脱出の構文であるべきreturnは構文
エラーになるべき。でも、bashもashも構文エラーにならない。
571 :名無しさん@お腹いっぱい。2011/04/23(土) 00:11:15.91
>>568
ash=dash(Cygwin dash 0.5.6.1-2)のmanには

> The syntax of the return command is

>    return [exitstatus]

> It terminates the currently executing function. Return is implemented as
> a builtin command.

ってあるからfunctionの中限定かと思ったら、確かに終了するね…
だけど

$ return
bash: return: can only `return' from a function or sourced script

普通こうならない?こっちの方がたくさんありそうだが(POSIXモードでもこうなる

>>569
ありがとウサギ! やっぱりサポートしてるシェルもあるんだね
確かに意味的に変な挙動でも、文法的に間違ってない。 そのまま通るから困るんだよなー
こういうときどう書くべきか… 一番いいアイデアをたのむ

# 一時ファイル?パラメータに展開する?場合によるけどいい気がしない
572 :名無しさん@お腹いっぱい。2011/04/23(土) 07:54:06.34
>>570
理解してないのはお前。

returnは「構文」ではなくて単なるコマンド。
コマンドとして正しく使われているから「構文エラー」にならない。
$ type return
return is a shell builtin

「構文」なのはifとかwhileとか。
$ type if
if is a shell keyword
573 :名無しさん@お腹いっぱい。2011/04/23(土) 08:54:18.85
>>572
言葉の定義に突っ込み始めたお前の負け。ww
構文だろうが、コマンドだろうが、ビルトインコマンドだろうが、>>570の本質は変わらない。

お前、バカなんだから出てくんな。
574 :名無しさん@お腹いっぱい。2011/04/23(土) 09:07:26.55
>>573
お前aho w

returnは「コマンド」だから、本来どこで使っても文法エラーにならない。
ただしbashでは、関数外の素のreturnはエラーになる。

それとは別にパイプがサブシェルになる問題があって、
bash/ash等はパイプ中のreturnでは関数を抜けられない。
ksh/zsh等はパイプ右端のreturnでも関数を抜ける。
575 :5742011/04/23(土) 09:45:06.14
>>571
エスパると、関数の中で

echo hoge | while ... return ... done
ってやりたいんだろ?

while ... return ... done <<< "$(echo hoge)"
で回避する方法が一応あるけどな。
576 :名無しさん@お腹いっぱい。2011/04/23(土) 09:49:58.08
シェルはfunctionを構文として、returnは他のコマンドと同様に処理してたわけか
なるほど、気がつかなかった。思い込んでたわ

returnがコマンドとして実行されるタイミングでは、サブシェルにも
functionの中っていう情報は伝わってるから、>>571みたいなエラーにならない訳ね

でもやっぱり挙動としてはおかしいと思うよ
構文エラーは行き過ぎだと思うが、警告は欲しいところ

# 構文にreturnを組み込むと、エラーを出すのはfunctionの定義のところになりそう
# そのときに、それがサブシェルの中だってエラー出すのは出来なくないけど
# そこまでシェルに判断させるべきか?

仕様なら仕方ないと思わなくないし、互換性のためだって言われそうだが
こんな出鱈目な仕様に依存するスクリプトなんて捨てたほうがいい

なぜ素通りさせるのだろうね、メリットないじゃん
577 :名無しさん@お腹いっぱい。2011/04/23(土) 10:09:40.20
>>575
thx!
おお、ヒアドキュメントっぽい
やっぱあるのか、調べ足らなかった

読み返したら必要なこと書いてなかった
その通りで、whileにパイプしようとしてて
挙動おかしくて、削っていったらあの形になったんだった

これも一度展開して読み込ますタイプ?
manには何もないけど制限はあるのかな

パイプだとコンカレントで動いてくれそうなんだよね
CPUいっぱい!が今なんだから、どうにかならないかと思うんだが
578 :名無しさん@お腹いっぱい。2011/04/23(土) 10:25:02.00
>>577
bashの場合、ヒアドキュメントは内部で一時ファイル作るから、
コンカレントには動かないな。

mkfifoでFIFO作ってリダイレクトするならコンカレントになるけど、
あまり美しくないのが難点。
579 :名無しさん@お腹いっぱい。2011/04/23(土) 10:32:00.45
bash4限定だけどcoprocなんてのがあった

$ coproc {
>  echo x
>  read   # 即終了を防ぐ
> }
[1] 1508

$ while read -u ${COPROC[0]} A; do
>  echo >&${COPROC[1]}   # コプロセスのreadを抜けるため
>  echo $A
> done
a

kshからインスパイアされた機能らしいが
移植性考え出すと難しいな

>>578
これはFIFOと似たようなものかな
bashだけで出来るよっていう以外に差がない
582 :名無しさん@お腹いっぱい。2011/04/23(土) 11:29:49.63
>>581
お前のようなバカを相手に回答したわけではない。

>>567で既にサブシェルに対する言及がありそれへのレスだ。>>567の質問は
> エラー出ないのは仕様?他のどのシェルもこうなの?
だ。
これはreturnがfunction外でも使えてしまった事への疑問に対する質問に他ならない。
したがって、>>568のように答えた。>>571は回答の意味を理解している。

お前が周回遅れのバカって事だ。
589 :名無しさん@お腹いっぱい。2011/04/23(土) 12:42:33.21
>>588
バカ、関数内のreturnじゃなくて、サブシェル内のreturnだからecho cが実行される。
実行結果もその通りだ。元質問者はだからこそ>>567の質問をした。

周回遅れで知恵遅れは引っ込んでろ。w
590 :名無しさん@お腹いっぱい。2011/04/23(土) 12:44:32.89
>>589
bashの場合、関数外扱いか関数内か使いかはエラーメッセージで判定できる。

$ return
return: can only `return' from a function
(関数外)

$ f() {(return)}
$ f
エラー無し(関数内扱い)
594 :名無しさん@お腹いっぱい。2011/04/23(土) 13:31:57.10
>>593
墓穴掘ってるぞ。バカ。
>>569 エラー出ないのは、文法的には間違ってないので、それで仕様。

関数内でreturnが実行されたならば、関数は終了するのが仕様。

Function:
If the builtin command return is executed in a function, the function completes
and execution resumes with the next command after the function call. Any command
associated with the RETURN trap is executed before execution resumes.
When a function completes, the values of the positional parameters and the special
parameter # are restored to the values they had prior to the function's execution.

return [n]
Causes a function to exit with the return value specified by n. If n is omitted,
the return status is that of the last command executed in the function body.
If used outside a function, but during execution of a script by the . (source)
command, it causes the shell to stop executing that script and return either n
or the exit status of the last command executed within the script as the exit
status of the script. If used outside a function and not during execution of a
script by ., the return status is false. Any command associated with the RETURN
trap is executed before execution resumes after the function or script.

周回遅れで知恵遅れは引っ込んでろ。w
595 :名無しさん@お腹いっぱい。2011/04/23(土) 14:05:14.21
>>594
>If used outside a function ... the return status is false.

関数外ならエラーステータスになると言ってるが、

$ f() {(return)}
$ f
$ echo $?
0
↑真だね。よって、関数内w
596 :名無しさん@お腹いっぱい。2011/04/23(土) 14:17:57.75
>>595
必死だな。バカ。w

関数内なら関数は終了して、関数呼び出しの次コマンドから実行が再開されると書いてある。
関数内であるもかかわらず、関数が終了しないのはバグ。
If the builtin command return is executed in a function, the function
completes and execution resumes with the next command after the function call.

周回遅れで知恵遅れは引っ込んでろ。w
597 :名無しさん@お腹いっぱい。2011/04/23(土) 14:19:38.27
仕様だけにしようがないなら、仕方ないとして
bash[version 4.1.10(4)-release (i686-pc-cygwin)]のmanから引用

>COMMAND EXECUTION ENVIRONMENT
>   Command substitution, commands grouped with parentheses, and asynchro-
>   nous commands are invoked in a subshell environment that is a duplicate
>   of the shell environment, except that traps caught by the shell are
>   reset to the values that the shell inherited from its parent at invoca-
>   tion. Builtin commands that are invoked as part of a pipeline are also
>   executed in a subshell environment. Changes made to the subshell envi-
>   ronment cannot affect the shell's execution environment.

サブシェルでは環境は親から複製されるそうだ。>>567や>>575はパイプラインに
ビルトインコマンドを混ぜてるから、意識しないうちにサブシェル環境になってしまう訳か
つまりt2の中のパイプラインの解釈は、‘echo b | ( return );’ってなる

親環境が複製されてるんだから、当然サブシェル内もfunctionの中って認識されるわな
でも、意図的にこうは絶対に書かないのに、暗黙的にサブシェルになって警告すらないのは嫌がらせだろ

# 何回もこの糞長いmanpage読むのはきつい
# せめて実行環境とスクリプティングのリファレンスは分割してくれねーかな
599 :名無しさん@お腹いっぱい。2011/04/23(土) 14:32:12.88
>>596
バグじゃない。関数外のreturnはエラーと言ってるだけで
関数内のreturnが関数を終了するかどうかは別問題

パイプがサブシェルにならないkshやzshでも以下ではreturnしない

f() {(return); echo hoge;}
601 :名無しさん@お腹いっぱい。2011/04/23(土) 14:42:31.07
>>599
仕様なのか
これはひどい
604 :名無しさん@お腹いっぱい。2011/04/23(土) 16:42:31.09
>>599
バカ、必死すぎる。ww

関数外ならfalseを返すけど、trueなので関数内というのが>>595の主張だろ。
それなら、関数内であるreturnは、関数から帰らなければいけない。

周回遅れで知恵遅れは引っ込んでろ。w
616 :名無しさん@お腹いっぱい。2011/04/24(日) 10:41:28.69
>>608に>>575の他の解決策書いてあるね。

f() {
 while read WD; do
  [ "$WD" = end ] && return # fから戻れる
  echo "$WD"
 done < <(cat "$1")
 echo "all done!" # returnしてたら来ない
}
こんな感じ。ヒアストリングと違って、パイプ使うのと同じようだ。

diff <(sed -ne '/begin/,/end/ p' foo.txt) <(sed -ne '/begin/,/end/ p' bar.txt)
便利だ。

mlの中の人的には>>567は仕様で、そもそもそんな場所のreturn自体禁止しようって人もいるっぽい。
674 :名無しさん@お腹いっぱい。2011/04/27(水) 23:04:51.19
>>673
>>575
568 :名無しさん@お腹いっぱい。2011/04/22(金) 20:12:15.15
returnはfunction呼び出し内でしか使用できないシェルもあったような気がするけど、
ashでも同じ結果。returnすなわちexitみたいだ。
580 :名無しさん@お腹いっぱい。2011/04/23(土) 11:09:19.42
>>574
言葉の定義にしか突っ込めなくなったお前の負け。
>>568はパイプの尻尾のサブシェル問題を踏まえた発言だ。

引っ込んでろバカ。
581 :名無しさん@お腹いっぱい。2011/04/23(土) 11:18:27.85
>>580
定義を抜きにしても間違ってる

>>568 は
「returnを関数以外で使えるか」
「returnがexitみたいに動作する」
の点に言及してるだけで
パイプやサブシェル問題には一切触れてない
(多分書き込み時点では知らなかったのだろうw)
583 :名無しさん@お腹いっぱい。2011/04/23(土) 11:41:23.17
>>582

>>567 のreturnはあくまで「関数内のreturn」だよ
なのに>>568 では質問していない「関数外のreturn」について回答してるし
質問のポイントをわかっていない
584 :名無しさん@お腹いっぱい。2011/04/23(土) 11:57:26.99
>>583
必死だな。バカ。サブシェルはどこ行ったんだよ。ww

関数内のreturnを「エラー出ないのは仕様?他のどのシェルもこうなの?」と聞くわけないだろ。
>>567はt2のreturnがサブシェルすなわち関数外で実行されてエラーにならなかった事を質問している。
それに対して>>568は適切に答えている。

判ってないのは周回遅れの知恵遅れのお前だけだ。 引っ込んでろ。バカ。
585 :名無しさん@お腹いっぱい。2011/04/23(土) 12:07:57.00
>>584
サブシェル自体が関数内にあるから、
サブシェルの中にあっても「関数内」なんだけどw

そうか、>>568 はreturnを「関数外」と思ってたんだなw
それ間違いだからw
587 :名無しさん@お腹いっぱい。2011/04/23(土) 12:33:14.62
>>585
必死だな、バカ。w

> サブシェルの中にあっても「関数内」なんだけどw
関数内のreturnならば、echo cは実行されない。

周回遅れで知恵遅れは引っ込んでろ。
588 :名無しさん@お腹いっぱい。2011/04/23(土) 12:38:28.17
>>587
関数内のreturnだからecho cは実行されない、んじゃなくて、
サブシェルだから関数を抜けずにecho cが実行るんだよ。

お前やっぱりサブシェルを理解してないんだな。
592 :名無しさん@お腹いっぱい。2011/04/23(土) 12:59:30.55
>>590
それが直感的におかしいから、元質問者は>567の質問をした。
>>568は適切に回答している。

周回遅れで知恵遅れは引っ込んでろ。w
593 :名無しさん@お腹いっぱい。2011/04/23(土) 13:11:14.55
適切な回答は
>>569 ←文法の件と、kshやzshの例を挙げて回答
>>575 ←回避方法を回答
だな。どっちも俺だけど

>>568 は的が外れている上に解決方法等の情報量が皆無w
607 :名無しさん@お腹いっぱい。2011/04/23(土) 18:52:01.78
つまりSUS V3的には、サブシェルで実行されている>>567のt2のreturnは関数外での
実行、returnが関数外で実行された時の動作は不定。なので仕様通りという事だね。
bashではmanに書かれている動作(関数外ではfalse)に反するのでバグ。
したがって、>>569も>>585も完璧なるウソ。

判ったか? 周回遅れの知恵遅れ。w
バカなんだから黙ってりゃよかったのに。
612 : 忍法帖【Lv=35,xxxPT】 2011/04/23(土) 19:39:40.76
>>607
判ったか? 周回遅れの知恵遅れ。w
バカなんだから黙ってりゃよかったのに。
600 :名無しさん@お腹いっぱい。2011/04/23(土) 14:41:31.00
kshとかzshはサブシェルを作らないから、望み通りパイプでreturnできるっぽいが
じゃあ、わざとサブシェル作って、そこからreturnするとbashみたく戻れないのか?
戻れないなら古くからのshの作法なんだろう。それが仕様通り
602 :名無しさん@お腹いっぱい。2011/04/23(土) 15:41:47.46
bashが保守的で、kshとかzshとかが革新的なのか

パイプを特別に扱うことがあるってのは、何か問題があるからなのか
603 :名無しさん@お腹いっぱい。2011/04/23(土) 16:24:56.59
POSIX仕様的には決まってないんじゃなかったっけ?
サブシェルにならない方がわかりやすいのは確かだと思うが。
605 :名無しさん@お腹いっぱい。2011/04/23(土) 17:56:03.46
論争そのものには興味ないですが…

The Single UNIX Specification Version 3では、

> 2.12 Shell Execution Environment
> (略)
> Additionally, each command of a multi-command pipeline is in a
> subshell environment; as an extension, however, any or all commands in
> a pipeline may be executed in the current environment.
====
> NAME
> return - return from a function
> (略)
> DESCRIPTION
> The return utility shall cause the shell to stop executing the current
> function or dot script. If the shell is not currently executing a
> function or dot script, the results are unspecified.

です。
要するにどうなっていようが仕様に適合します。
(個別の実装の「仕様」はともかく)
606 :名無しさん@お腹いっぱい。2011/04/23(土) 18:41:24.60
> (略) the results are unspecified.
undefinedでなくて、unspecifiedか。実装依存ってことね、たぶん

ユーザとしたら、移植性の高いコード書くときに、return使う場所には気をつけろってこと?

わざわざ、こういうときは実装依存ですって、規格に書くってことは、昔から揉めてたわけか
608 :名無しさん@お腹いっぱい。2011/04/23(土) 19:10:32.98
まだやるかww まー、見てる分には面白いから、もっとやれ
でも、バグバグ言うなら、本家に言えよな。向こうはきっと日本語しゃべらないんだから

で、バグ検索したらまんま見つけたww まだ読んでねーけど、似たような香りがする

return from function doesn't work when used in tail of pipeline
ttp://lists.gnu.org/archive/html/bug-bash/2010-08/msg00090.html

誰かまとめてくれんかの
609 :名無しさん@お腹いっぱい。2011/04/23(土) 19:12:31.89
つか、何気にインプロセスでパイプ処理するのってすごくねーか?
いくつ繋がってても、ビルトイン・外部コマンドがごちゃ混ぜでも動くのなら

X=0; for I in `seq 1000`; do echo $I; X=`expr $X + 1`; done |sed -ne '1,$ p' |
while read J; do echo $J; X=`expr $X + 1`; done |while read K; do echo $K; X=`expr $X + 1`; done |
while read L; do echo $L; X=`expr $X + 1`; done |while read M; do X=`expr $X + 1`; done

どーなるんだよ、これww
bashだと間違いなくXは0のままだが
610 :名無しさん@お腹いっぱい。2011/04/23(土) 19:24:00.05
>>609
> ; as an extension, however, any or all commands in
> a pipeline may be executed in the current environment.

だから、SUSv3的にも「よく頑張ったぜ!」と適合。
611 :名無しさん@お腹いっぱい。2011/04/23(土) 19:36:26.92
>>610
kshとか、zshでのことだよな?確かに頑張り過ぎだわ
ちゃんとXに値入るの、これww
614 :名無しさん@お腹いっぱい。2011/04/24(日) 08:35:06.06
なんでそんな古いの使ってるの?
617 :名無しさん@お腹いっぱい。2011/04/25(月) 10:41:39.45
>>614
8.2でもできないよ
618 :名無しさん@お腹いっぱい。2011/04/25(月) 21:34:16.48
rubyでいうところの
for dir in ENV['PATH'].split(/:/)
 puts dir
end
ということをshellスクリプトでやりたいんだけど、
for dir in `???`; do
 echo $dir
done
ここの ??? の部分がわかりません。どうするの?
619 :名無しさん@お腹いっぱい。2011/04/25(月) 21:41:36.46
>>618
echo ${PATH} | sed '/:/s// /g'
620 :名無しさん@お腹いっぱい。2011/04/25(月) 21:50:36.23
s/:/ /g じゃなくて?

PATHにスペースあったら知らんけど
621 :名無しさん@お腹いっぱい。2011/04/25(月) 22:15:49.84
>>620
どっちでも。

ksh だとこれが出来るのね。

IFS=:; for i in ${PATH}; do echo ${i}; done
622 :名無しさん@お腹いっぱい。2011/04/25(月) 22:40:48.12
>619-621
ありがとう。
echo $PATH | sed 's/:/¥n/g'
がなんかうまくいかない。sedは¥nがつかえないのかな。
626 :名無しさん@お腹いっぱい。2011/04/26(火) 01:08:02.79
質問です。
以下を見てください。
----------------------------
japan:~$ cat hoge.dat
aaa
bbb
ccc
----------------------------
japan:~$ cat hoge.sh
#!/bin/sh
IFS='
'
cnt=0
cat hoge.dat | while read -r line
do
cnt=`expr $cnt + 1`
echo "cnt=$cnt"
done
echo "cnt=$cnt"
----------------------------
japan:~$ ./hoge.sh
cnt=1
cnt=2
cnt=3
cnt=0
----------------------------
hoge.sh実行で、最後にcnt=0と表示されていますが、
なんでcnt=3とはならないのでしょうか?
627 :名無しさん@お腹いっぱい。2011/04/26(火) 01:21:51.47
>>626
パイプで繋いだために while〜 がサブシェルで実行されるから
ちなみに zsh だと最後も cnt=3 になる
673 :>>6262011/04/27(水) 23:00:35.02
>>627
ありがとうございます。

参考までに教えていただきたいのですが、サブシェルの変数の値を取得するには、どうしたらよいのでしょうか?
それとも、そのようなことは出来ないのでしょうか?
628 :名無しさん@お腹いっぱい。2011/04/26(火) 01:58:32.24
おい、周回遅れの知恵遅れ。
大好きなサブシェルの話題だが、お前バカなんだから黙ってろよ。w
631 :名無しさん@お腹いっぱい。2011/04/26(火) 22:44:39.44
>>628
訳の分からんキチガイカキコして荒らしまくってんじゃねえよキチガイ、とっとと今すぐに死んで自殺して死ねwwwwwwwwwwwwwww
年中無休発狂妄想爆裂憤死寸前粘着真性キチガイ包茎池沼病気猿男(狂猿)◆QfF6cO2gD6は今すぐに発狂して自殺して死ねよwwwwwwwwwwwwwww

何でもいいがあちこちにそうやってリンク貼って荒れるのを見て楽しんでいる年中無休発狂粘着真性キチガイ包茎池沼病気猿男(狂猿)◆QfF6cO2gD6(+とそのキチガイ妄想)はマジでウザイ(笑)から、

今すぐに発狂してとっとと自殺して今すぐに死ねwwwwwwwwwwwwwwwwwwwwwwwwwww

こういう救いようのない真性基地外ニートは今すぐにとっとと発狂してビルから飛び降りて自殺して今すぐに死ねwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
634 :名無しさん@お腹いっぱい。2011/04/27(水) 00:53:42.49
>>631
福島一号炉で焼かれてしまえ。粘着キチガイ犬。
629 :名無しさん@お腹いっぱい。2011/04/26(火) 07:03:54.52
zsh拡張し過ぎ、そこは記憶されるべきじゃない。
それ前提で書いてたし。移植性()笑
632 :名無しさん@お腹いっぱい。2011/04/26(火) 23:14:49.76
bashとzshとの挙動の違いで困ってます。
やりたいことは、「/tmp/*.html」のようなパターンに一致するファイル名を取得することと、
そのようなファイル名がなかった場合はそれを検出することです。

で、今困ってるのは、パターンに一致するファイル名がなかった場合の挙動です。
bashの場合は次のようにパターンそのものが出力され、エラーメッセージはでません。

bash> echo /tmp/*.html
/tmp/*.html

これに対し、zshではエラーメッセージがでます。
そしてこのエラーメッセージが、2>/dev/null とか 1>/dev/null とかしても表示されてしまいます。

zsh> echo /tmp/*.html
zsh: no matches found: /tmp/*.html
zsh> echo /tmp/*.html 2>/dev/null
zsh: no matches found: /tmp/*.html
zsh> echo /tmp/*.html >/dev/null
zsh: no matches found: /tmp/*.html

zshで、このエラーメッセージをださずに、パターンに一致するファイル名を取得するにはどういう方法がありますか。
633 :名無しさん@お腹いっぱい。2011/04/27(水) 00:01:44.68
>>632
setopt nonomatch
636 :名無しさん@お腹いっぱい。2011/04/27(水) 01:04:30.18
>>632
zshはsh/kshコンパチモードってのがある。
637 :名無しさん@お腹いっぱい。2011/04/27(水) 07:03:22.99
>>633
ありがとうございました。setopt nonomatchの動作を確認しました。
続いて質問ですが、一時的にnonomatchを設定し、そのあと解除したいのですが、
nonomatchが設定されているかどうかはどうやって確認すればいいでしょうか。
つまり
nonomatch_backup=getopt nonomatch
setopt nonomatch
...シェルスクリプト...
nonomatch=nonomatch_backup
みたいな感じにしたいんですが。
なおgetopt nomatchやgetopt nonomatchを試したのですが、いつも同じ値を返すようなので、期待したものとは違うようです。
638 :名無しさん@お腹いっぱい。2011/04/27(水) 07:46:22.54
>>637
サブシェル内で setopt nonomatchすれば、
そもそも状態セーブしたり解除したりする必要ないよ。

あと、getoptは全然違う外部コマンド。
639 :名無しさん@お腹いっぱい。2011/04/27(水) 08:10:21.66
>>638
おう、getoptはコマンドラインオプションをパースするコマンドでしたか。紛らわしい・・・
つうかですね、たんに /tmp/*.html のようなパターンに一致するファイルを見つけたいだけなのに、
なんでbashとzshで違う書き方をしなきゃいけないんでしょうか。
bashでもzshでも同じように動作する書き方ってありませんか?
今「zsh」でぐぐって調べてるんですが、わかんないです。
ほんとは ruby とか使いたいけど、使えるのがせいぜいawkぐらいしか期待できない環境で
やらなきゃいけなくて、もう発狂しそうです。
644 :名無しさん@お腹いっぱい。2011/04/27(水) 09:42:31.88
>>643
>>636 は無視かよ。
shコンパチモードで起動すれば解決。

zshをshの名前で起動すれば自動的にコンパチ。
658 :名無しさん@お腹いっぱい。2011/04/27(水) 15:02:48.28
>>639
逆にシェルスクリプトがbashとzshで動かないといけない意味は何?
#! /bin/sh
と指定したシェルだけ対象にすればいいだけでしょ?
根本的な部分が理解できてないのでは?

それとも各ユーザのシェル環境に取り込まれる関数でも書いているわけ?
659 :名無しさん@お腹いっぱい。2011/04/27(水) 15:45:00.73
>>639
globによる ファイル名生成でそのファイルの存在を調べたいなら、nullglob のほうがいいんじゃない?
bash: shopt -s nullglob
zsh: setopt nullglob

合致するファイル名がない場合は「*」を含む引数が空になるよ。
660 :名無しさん@お腹いっぱい。2011/04/27(水) 17:15:28.97
>>659
なんとそんな機能が!これはすばらしい。
いままでは
for x in `echo /tmp/*.html`; do
 if [ "$x" != "/tmp/*.html" ]; then
  echo $x
 fi
done
みたいなことをやってたんですけど、nullgrobのおかげですこしコードがすっきりしました。
あとは$BASH_VERSIONと$ZSH_VERSIONを調べて使い分けることにします。
ありがとうがいます。

>>658
実行しておわりというシェルスクリプトではなく、ユーザの.bashrcから読み込まれてshell関数を提供するのが目的のスクリプトなので。
641 :名無しさん@お腹いっぱい。2011/04/27(水) 09:21:04.15
移植性気にするならまずはこの辺読んで勉強しろ。

ttp://www.bookshelf.jp/texi/autoconf-ja/autoconf-ja_10.html#SEC114

やってらんねーと思ったらしれっとbashのみで動作しますと言い切って
しまうという手もw
643 :名無しさん@お腹いっぱい。2011/04/27(水) 09:33:05.51
>>641
これは参考になるページ。ありがとうございます。
しかしこのページでも、互換性のある echo "/tmp/*.html" の書き方は載ってないですね。
こんなことすら書けないシェルスクリプトって、何なんですかね。今の時代に必要なんすか?
いやゆとりの愚痴ですけど。
666 :名無しさん@お腹いっぱい。2011/04/27(水) 21:47:14.97
>>664
>>641のリンクの最初に書いてあるじゃん
642 :名無しさん@お腹いっぱい。2011/04/27(水) 09:23:05.31
検索するより公式ドキュメントを読んだ方がいい。公式ドキュメントでわからないところを検索する。
そうしないと、沢山あるウソのページに騙されて時間を浪費する。
645 :名無しさん@お腹いっぱい。2011/04/27(水) 09:45:18.57
shが基本だからshで書けばOk。
拡張シェルはshとの互換を取るような仕組みを持っているからそれを使う。
646 :名無しさん@お腹いっぱい。2011/04/27(水) 09:52:23.10
シェルスクリプトの互換性というのは暇つぶしの冗談なので真に受けると負け
647 :名無しさん@お腹いっぱい。2011/04/27(水) 10:48:12.61
大昔じゃあるまいし、商売でスクリプト書きながら
移植、転用なんてしてるとは思えない
ボーンに拘る必要はなく、自分の環境で希望の動作が問題ないなら
それはbだってcだってかまわねーんだよ。
どの道犬糞、馬糞くれーなもんなんだから。

今では、たかが数行のcシェルスクリプトみて血管切れそうに
非難するバカもいないだろうけどなw
648 :名無しさん@お腹いっぱい。2011/04/27(水) 10:57:32.48
cshなんかインストールしてないから、そんなの納品されたら動かない。取引停止だな。
651 :名無しさん@お腹いっぱい。2011/04/27(水) 11:08:37.26
いいえ?いただいた購入仕様書にはそんなことかいてありませんよほら
654 :名無しさん@お腹いっぱい。2011/04/27(水) 11:32:48.99
cがダメなんていうバカに
「極めて単純で小さなスクリプトなんで、Cの欠陥がある部分は使ってませんよ?」
「具体的に何の処理を指してますか?」
っていうとへの字にして黙るねw
結局センパイにダメって言われて、一切の知識がないんで
「ウナギとウメボシ食べません」みたいなものなんだよ
655 :名無しさん@お腹いっぱい。2011/04/27(水) 11:43:32.55
↑こういうバカに、極めて単純なスクリプトならsh使い慣れてなくても楽勝でしょ。
それくらいできないの? っていうと黙っちゃうよね。w
656 :名無しさん@お腹いっぱい。2011/04/27(水) 12:19:37.93
というか csh script を使うことの問題点は「お里が知れる」

それだけだ

本当に問題がでるレベルで使えば自然と使わなくなるしな
657 :名無しさん@お腹いっぱい。2011/04/27(水) 12:35:41.44
問題出るレベルとか言ったって
echo foo >&2
とか、いまどきcmd.exeですらできることもできない男の人って……
った感じじゃんcshって

そういう初歩のリダイレクトすらしないスクリプトだとしても
後で手を入れるかもしれないんだし
この使用範囲ならたまたまcshでも問題ないからcsh使おうとか
そんな使い分けをする意味がそもそもわからない

661 :名無しさん@お腹いっぱい。2011/04/27(水) 19:26:33.86
質問ですが、bashで簡単なスクリプトを書いています。
バイナリファイルで、ファイル名があればそれを読み、無ければパイプから、パイプもなければ、端末を読みに行き、処理をして、結果をlessで表示しようと思います。
script [files...]

filenamesに何もなければ端末を読みにいくので、これでいいかと思いましたが、lessが付くとダメです。
$ filenames=( "$@" ) # 実際は$@を処理したもの
$ cat "${filenames[@]}" | hexdump -C | less

とか書いている間に、解決法も見つかったのですが、参考までにお聞かせ下さい。
皆さんならどうしますか?
662 :名無しさん@お腹いっぱい。2011/04/27(水) 20:40:52.52
やっぱり、標準入力の他に「標準エラー入力」が欲しいよな。
664 :名無しさん@お腹いっぱい。2011/04/27(水) 21:21:45.25
シェルスクリプト冒頭で
#!/bin/sh
と続けて書く人もいれば
#! /bin/sh
と、#!のあとにスペースを入れる人もいるじゃないですか

それぞれの違いとか、狙っている効果とか、何かあるのでしょうか?
667 :名無しさん@お腹いっぱい。2011/04/27(水) 22:23:44.50
こんばんは、シェル初心者ですが
ディレクトリ内のaaaのファイル以外を削除する
あるいは、aaa.c bbb.c 以外のファイルを削除するってことは
可能でしょうか
676 :名無しさん@お腹いっぱい。2011/04/27(水) 23:36:40.56
>>667
zsh なら
rm *~aaa
rm *~aaa.c~bbb.c
なんてこともできる。
679 :名無しさん@お腹いっぱい。2011/04/28(木) 00:20:34.07
>>676
zsh 便利だな
そこまでやるならスクリプト言語を使いたくなるけど
669 :名無しさん@お腹いっぱい。2011/04/27(水) 22:31:16.19
シェルスクリプト変数で
$HOGE
と書く人もいれば
${HOGE}
と、$のあとに{ と }を入れる人もいるじゃないですか

それぞれの違いとか、狙っている効果とか、何かあるのでしょうか?
677 :名無しさん@お腹いっぱい。2011/04/28(木) 00:15:43.55
autoconfは極端すぎるわな

>>669
$ A=aaa
としたとき、
$ echo $A
aaa
は当然として
$ echo $A.B
aaa.B
となるが、以下の場合は
$ echo $A_B

となる
ここで{}を使うと
$ echo ${A}_B
aaa_B
となる

変数名の区切りと見なされたり見なされなかったりする記号を続ける場合に
うっかり変な解釈をさせない、という効果はあるかな

昔、FreeBSDかなんかで、{}使ってなくてバグってたスクリプトがあるので
よくあるバグなのかもな
680 :名無しさん@お腹いっぱい。2011/04/28(木) 06:26:02.63
>>677
ありがとうございます。では、

"$HOGE"

"${HOGE}"

それぞれの違いとか、狙っている効果とか、何かあるのでしょうか?
682 :名無しさん@お腹いっぱい。2011/04/28(木) 12:53:40.19
>>680
{}付けとく方が、変数名を意識させることによる誤りを減らせる効果はあるんじゃね

あとは省略が許されているから省略するのか、それとも省略は許されていても省略はしないのか、
そういう信条に関わる違いじゃね
670 :名無しさん@お腹いっぱい。2011/04/27(水) 22:34:59.28
あるディレクトリがあったとして、それが$PATHに含まれていないときだけ,$PATHに追加するという処理は、どう書くのがいいでしょうか。
671 :名無しさん@お腹いっぱい。2011/04/27(水) 22:40:24.42
>>670
for dir in /usr/bin/mh $HOME/bin ; do
if ! echo $PATH | grep $dir > /dev/null; then
[ -d $dir ] && export PATH=$PATH:$dir
fi
done
672 :名無しさん@お腹いっぱい。2011/04/27(水) 22:43:09.32
>>670

DIR=/usr/hoge/bin

case :$PATH: in *:"$DIR":*);; *) PATH=$PATH:$DIR;; esac

>>671 はエレガントじゃないねw
675 :名無しさん@お腹いっぱい。2011/04/27(水) 23:32:46.72
>>672
ありがとうございます。caseの引数に、$DIRじゃなくて$PATHを持ってくるんですか。頭いいなあ。
683 :名無しさん@お腹いっぱい。2011/04/28(木) 13:18:36.76
ファイル名のソートについて相談です。
touch ver0.1.jpg
touch ver0.2.jpg
touch ver0.9.jpg
touch ver0.11.jpg
touch ver0.11.2.jpg
touch ver0.11.11.jpg
というファイル名があったとして、これを単純にソートすると
ver0.1.jpg
ver0.11.11.jpg
ver0.11.2.jpg
ver0.11.jpg
ver0.2.jpg
ver0.9.jpg
となってしまいます。しかし希望するのは最初のように番号順にソートされることです。
いちおうsortには -n オプションがありますが、この場合は効かないようです。
このような場合、どうすればいいでしょうか。
684 :名無しさん@お腹いっぱい。2011/04/28(木) 13:23:43.91
>>683
ls -v
685 :名無しさん@お腹いっぱい。2011/04/28(木) 13:32:54.92
>>684

ver0.1.jpg
ver0.1.1.jpg

というファイルがあると、ls -v でもうまく行きません><
691 :6612011/04/28(木) 14:40:31.19
>>683
sort -nt '.' -k 2,2 -k 3,3

だ、だれか私の質問にレスを! lessが付いちゃ(上手く)行けないだけに...

結局3つのコマンドの組み合わせだけで、出来たのですが。
考えるネタとして面白いかなぁと、思うのですが。
686 :名無しさん@お腹いっぱい。2011/04/28(木) 13:39:34.53
$ ls -v1
ver0.1.jpg
ver0.1.1.jpg
ver0.2.jpg
ver0.9.jpg
ver0.11.jpg
ver0.11.2.jpg
ver0.11.11.jpg
$ ls --version
ls (GNU coreutils) 8.5
(略)
687 :名無しさん@お腹いっぱい。2011/04/28(木) 13:47:48.93
>>686
GNU版にはそんな機能があるのですか。すごいですね。
残念ながら自分のマシンには入ってませんでした。
いちおうPerlを使うとこんな感じでできそうなんですが、Perlを使わずにできないもんですかねぇ。

perl -e '
%h = map {
$s = $_;
@a = m/(¥d+)/g;
$k = join("_", map { sprintf("%010d", $_) } @a);
$k => $s;
} @ARGV;
for (sort keys %h) {
#print $_, "¥n";
print $h{$_}, "¥n";
}
' ver*
688 :名無しさん@お腹いっぱい。2011/04/28(木) 13:49:40.78
netscape-4.79.tar.gz
netscape-4.8.tar.gz

の場合に対応できてないようです。
netscape-4.8の方が新しいんですが。
689 :名無しさん@お腹いっぱい。2011/04/28(木) 14:00:41.41
ネスケを知らない人が見たら、4.79 の方が新しいと判断する
692 :名無しさん@お腹いっぱい。2011/04/28(木) 15:44:58.13
var = [ -n "$value" ] ? "YES" : "NO"
のように三項演算子が使いたいんですけど、なさそうなので
[ -n "$value" ] && var="YES" || var="NO"
と書いてみました。
この書き方は、ありでしょうか。
互換性が低いからやめたほうがいいとか、アドバイスをお願いします。
693 :名無しさん@お腹いっぱい。2011/04/28(木) 16:09:29.49
>>692
普通にアリ。互換性問題なし。

ちなみに、こういう書き方もある。

var=${value:+YES}; var=${var:-NO}
699 :名無しさん@お腹いっぱい。2011/04/28(木) 16:28:12.48
>>697
set -e に耐えられる合格回答は、

>>693
var=${value:+YES}; var=${var:-NO}

だけだな。
694 :名無しさん@お腹いっぱい。2011/04/28(木) 16:10:03.66
普通にif使った方が見やすい気がする
696 :名無しさん@お腹いっぱい。2011/04/28(木) 16:22:35.72
>>694
普通にif使ったら初心者と思われる気がするw

普通に書くとしてもcaseだろ。

case $value in '') var=NO;; *) var=YES;; esac
697 :名無しさん@お腹いっぱい。2011/04/28(木) 16:23:24.18
set -eしてると面白い事になるからダメ。

マイクロソフト ワイヤレス ブルートラック マウス Arc Touch Mouse RVF-00006
マイクロソフト ワイヤレス ブルートラック マウス Arc Touch Mouse RVF-00006