5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

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

1 :名無しさん@お腹いっぱい。:2011/06/16(木) 12:38:47.74
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。

□お約束
・特記なき場合は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 でトレースしましょう。

前スレ
シェルスクリプト総合 その17
http://hibari.2ch.net/test/read.cgi/unix/1290209379/

2 :名無しさん@お腹いっぱい。:2011/06/16(木) 22:26:41.84
職場での話しです。

シェルスクリプトが使える環境から一部別ネットワークで
作業をする羽目になった。

windoze環境なのは相変わらずだが、旧環境はかろうじてcygwinが使用できたが
新環境は「管理者が親切にrubyだけ入れてくれた」状態。

ま、多少高速に動きますけどね・・・
構文の見た目が糞なのだが、
俺のポーティングが悪いのかなぁ?

ファイルをsedで置換して別ファイルに書き込むとかは、
(裏でopenとかwriteとかいっぱいioctrlがcallされているか知らんが)
見た目はシェルスクリプトが百万倍スマートだと思う。

3 :名無しさん@お腹いっぱい。:2011/06/16(木) 22:50:28.09
Rubyあるだけでも随分マシなほう
素のコマンドプロンプトはマジで何もできんからな…

4 :名無しさん@お腹いっぱい。:2011/06/16(木) 23:34:00.91
質問です。


hoge="a b c d"
for m in `echo $hoge`
do
echo $m
done

↑これと同じようなことを、
hoe="a,b,c,d"
↑これみたいにカンマ区切りのデータでやりたいんですが、どうすればいいですか?


5 :名無しさん@お腹いっぱい。:2011/06/16(木) 23:40:48.99
IFS=,

hoe つまり、エミッタ接地時の出力アドミッタンスだな

6 :名無しさん@お腹いっぱい。:2011/06/16(木) 23:48:15.67
>>5
ありがとうございます!


7 :>>4:2011/06/16(木) 23:54:02.88
うーん、だめでした。。

~$ cat hoge.sh
#!/bin/sh
IFS=,

hoge="a,b,c,d"
for m in `echo $hoge`
do
echo "m=$m"
done

~$ ./hoge.sh
m=a b c d



8 :名無しさん@お腹いっぱい。:2011/06/17(金) 00:08:29.17
bashだと動いたが。環境は?

9 :名無しさん@お腹いっぱい。:2011/06/17(金) 00:27:58.76
下のやつはshとbashは同じだな。
zshはなんか他と違う。
jshもまた違う。

#!/bin/sh
IFS=,
hoge="a,b,c,d"
for m in a,b,c,d; do echo "m=$m"; done
for m in $hoge; do echo "m=$m"; done
for m in `echo a,b,c,d`; do echo "m=$m"; done
for m in `echo $hoge`; do echo "m=$m"; done
for m in "`echo a,b,c,d`"; do echo "m=$m"; done
for m in "`echo $hoge`"; do echo "m=$m"; done


10 :名無しさん@お腹いっぱい。:2011/06/17(金) 10:11:22.76
>for m in `echo $hoge`

こんなことやって気にならないなら、

for m in `echo $hoge | tr , \ '

でいいんじゃないの? 俺はイヤだけど。


11 :名無しさん@お腹いっぱい。:2011/06/17(金) 14:15:47.53
bashなら
HOGE='a,b,c,d'
IFS=', ' fuga=($HOGE)
for m in ${fuga[@]}; do echo "m=$m" ; done
でいいんじゃない。


12 :名無しさん@お腹いっぱい。:2011/06/19(日) 04:55:30.78
>>7
> for m in `echo $hoge`
echoを使う必然性は? 単に for m in $hoge なら期待通りじゃないかと思うけど。

> for m in `echo $hoge`
この場合、
(1) バッククォート中の展開するとき IFS=,だから echo a b c d になる。
(2) その出力"a b c d"を受けた元のシェルが単語分割する際も
IFS=,なので空白で分割されず、単一の文字列のまま。
ということで for m in 'a b c d' と同じになってしまうわけ。

IFSを使うなら処理のステップを分解してIFSの影響範囲を最小限に限定すると安全。
output=`なにか,区切りの出力をするコマンド`
IFS=, set -- $output
for m; do
  ...
done

13 :名無しさん@お腹いっぱい。:2011/06/28(火) 20:21:08.07
質問です。

solaris10のグローバルゾーンからローカルゾーンでループ処理を実行したいのですが、

zlogin zone コマンド

のコマンドの部分に、
例えば
for a in `cat a.log` do
echo $a
done
のような処理を入れようとすると
ローカルゾーンにログインしようとしてエラーになります。

関数とかにループ処理を格納して無理やり実行しようとしても駄目でした…

何か良い方法ありませんか?
使用シェルはbashです。

14 :名無しさん@お腹いっぱい。:2011/06/28(火) 20:28:19.77
zloginのmanに↓と書いてあるから、manual読むのが一番の近道だと思うな。

Non-Interactive Mode
If a utility is specified, zlogin
operates in non-interactive mode.
This mode can be useful for script
authors since stdin, stdout, and
stderr are preserved and the exit
status of utility is returned upon
termination.

15 :名無しさん@お腹いっぱい。:2011/06/28(火) 21:18:32.94
>>14
早速の返事ありがとうございます。
まぬある見てみたけど対話型無理って書いてあったからグローバルゾーンから複雑なコマンド実行は無理そうですね
かなり面倒だが一行づつ実行するしかないのかorz

16 :名無しさん@お腹いっぱい。:2011/06/29(水) 00:59:14.86
bashで質問です。

ssh user@host echo $HOGE_PATH

で、ローカルのHOGE_PATHではなく、ssh先のHOGE_PATHを参照することってできますか?

17 :名無しさん@お腹いっぱい。:2011/06/29(水) 01:09:51.64
>>16
ssh user@host echo '$HOGE_PATH'
とか
ssh user@host 'echo $HOGE_PATH'
とか


18 :名無しさん@お腹いっぱい。:2011/06/29(水) 01:53:12.27
>>17
おおお、そういう事ができるんですね。
確かにssh先のが参照できました。なるほどー

19 :名無しさん@お腹いっぱい。:2011/06/29(水) 07:45:18.42
>>13
自己レスですが解決しました。
for a in `zlogin zone コマンド`
do
zlogin zone echo $a
done
みたいな感じにしてやれば
グローバルからルーブ処理実行できますね。

20 :名無しさん@お腹いっぱい。:2011/06/29(水) 21:33:35.45
>>3
そりゃそうだけど。
shellscriptのテストをshellscriptで書くのは、
コマンド群の出力を別のコマンド群に食べさせて
おなかを壊さなければ安心みたいな感じだけど、
rubyのテストをrubyで書いたり、
perlのテストをperlで書いたりとかは、
なんか辻褄だけは合って当然ぽくて
安心できない。

素のコマプロしかない作業環境になったら
転職します。

21 :名無しさん@お腹いっぱい。:2011/06/30(木) 17:30:55.60
俺JScript/CScript.exeでテキストフィルタ書いたことあるぞ…

22 :名無しさん@お腹いっぱい。:2011/07/02(土) 06:56:19.18
転職すべき!

23 :名無しさん@お腹いっぱい。:2011/07/07(木) 19:31:33.14
ls -l

合計 100
とか
total 100
とか表示されるけど、この意味は何ですか?

24 :名無しさん@お腹いっぱい。:2011/07/07(木) 19:35:26.48
>>23
ls -s で表示される数字の合計。

25 :名無しさん@お腹いっぱい。:2011/07/07(木) 20:34:31.94
>>24
それは知ってるけど、それが ls -l の時に表示される意味は何ですか?

26 :名無しさん@お腹いっぱい。:2011/07/07(木) 20:40:11.55
意味はあんまりないね。
気にしなくていいよ。

27 :名無しさん@お腹いっぱい。:2011/07/08(金) 03:10:33.74
>>24
なるほど、ありがとうございます。

28 :名無しさん@お腹いっぱい。:2011/07/08(金) 23:21:49.48
ubuntu10.10の標準状態です。
経験値は極めて低いです。
ZIPファイルを展開して処理して再圧縮させたいです。
展開したフォルダだけの名前を取得したいのですが、どうやればいいんですか?
echo *

echo *.*
比べるぐらいしか思いつかないです。。。

29 :名無しさん@お腹いっぱい。:2011/07/08(金) 23:51:19.51
>>28
zip ファイルの中身の確認は
unzip -l hoge.zip
unzip -tv hoge.zip
などで確認

手軽にやるなら、fuse-zip を利用するのもあり
$ fuse-zip hoge.zip mountdir
$ 必要な処理
$ fusermount -u mountdir
でできる

unzip/zip コマンドで一部ファイルのみ変更する方法はあるのかな?

30 :名無しさん@お腹いっぱい。:2011/07/08(金) 23:51:28.22
>>28
man basename

31 :名無しさん@お腹いっぱい。:2011/07/09(土) 06:43:49.44
>>28
unzip展開後、find . -type d


>>30
お前は誰に何を答えてるんだw
manで答える回答は外してる、の法則の成立例。

32 :名無しさん@お腹いっぱい。:2011/07/09(土) 08:34:08.18
>>31
普通そこらへんにzip展開してファイルを産卵させることないから、
WORKDIRに展開するとして、こうしないかな?スクリプトから使うことも考えると。
find "$WORKDIR" -type d

33 :名無しさん@お腹いっぱい。:2011/07/09(土) 08:35:50.14
うわ…zip卵産んじゃってるよ…
s/産卵/散乱/

34 :名無しさん@お腹いっぱい。:2011/07/09(土) 09:34:51.11
>>29-33
ありがと。
キーはfind -type d
だね。
ついでに聞きたいけど、
シェルスクリプトの入門書ってなにかいい本ある?
javaとかcgiの本は本屋でいっぱい見かけるけど。。。
どんなコマンドがあるか把握するだけでもちょっと大変。

面白いけど。

35 :名無しさん@お腹いっぱい。:2011/07/09(土) 11:33:19.65
一応findがない環境を想定して、findを使わない例。

function findd() {
  for D in "$1"/*; do
    if [ -d "$D" ]; then
      echo "$D"
      findd "$D"
    fi
  done
}
findd dir

dir以下に存在するディレクトリを表示。シェルスクリプトでゴリ押し。
ネットのどっかにチュートリアルなかったっけ。それじゃ足りないかい?

36 :名無しさん@お腹いっぱい。:2011/07/09(土) 11:40:53.88
functionなんて使うなクズ。

37 :名無しさん@お腹いっぱい。:2011/07/09(土) 12:17:30.51
じゃあfunction書かなきゃいいよ。

38 :名無しさん@お腹いっぱい。:2011/07/09(土) 16:10:16.06
>>35
.(ドット)で始まるディレクトリを取りこぼすな、これ

39 :名無しさん@お腹いっぱい。:2011/07/09(土) 16:26:21.56
>>38
もし必要なら事前に次を実行しとけばどうさ?
$ shopt -s dotglob

ディレクトリにはハードリンクできなかったと思うけど、ループしてても動くのかね?findは(確か)止まるが。
ま、元の質問はZIPを展開したものに対してだから、気にしなくていいって言えばいいのか。

40 :名無しさん@お腹いっぱい。:2011/07/09(土) 16:56:42.99
>>35
-n という名前のディレクトリが有ったら表示されない。

41 :名無しさん@お腹いっぱい。:2011/07/09(土) 17:07:20.26
>>40
それは無いだろ?必ず一番初めに関数に渡したディレクトリ名が頭に付くんだから。

42 :名無しさん@お腹いっぱい。:2011/07/09(土) 17:08:28.95
>>40
いや、"$1"/* から開始してるから
-n があっても hoge/-n になるから、問題ないだろ。

43 :名無しさん@お腹いっぱい。:2011/07/10(日) 16:59:24.56
>>34
大学の図書館でいろいろなコマンドの説明が書いてあるハンドブックを読んだことがある。タイトル忘れた。
ウィキペでちょっとアレだが、ここにあるコマンドで大体必要な処理は書けるよ。
ttp://ja.wikipedia.org/wiki/Template:Unix%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89
exprとか地味によく使うコマンドの説明がなかったりするけど、
詳しい説明はman読んだほうが、どんなサイトや本の説明よりいいかと。

44 :名無しさん@お腹いっぱい。:2011/07/12(火) 19:40:46.08
centos5で質問です
↓のようなテキストファイルがあります

1 a.log root
2 a b.log apache
3 c.log mysql

ここでlogファイル名だけを抜き出したいのですが良い方法は無いでしょうか?

awk等で列を抜きだそうとすると間にスペースが入っている為、どうしても2行目がb.logと抜き出されてしまいます。

45 :名無しさん@お腹いっぱい。:2011/07/12(火) 19:44:55.52
二行目は"a b.log"ってことなのか?
最後の単語には空白が含まれない前提で、
awk '{ $1 = ""; $NF = ""; print $0 }' | sed -e 's/^ //' -e 's/ $//'


46 :名無しさん@お腹いっぱい。:2011/07/12(火) 19:51:42.21
>>45
>二行目は"a b.log"ってことなのか?
その通りです。
正確にはスペースが複数入っているようなファイル名を想定してますが…

出先で直ぐには確認出来ませんが試して見ます。

47 :名無しさん@お腹いっぱい。:2011/07/12(火) 20:02:14.49
>>44 >>45
sedだけで出来る

sed 's/[^ ]* //; s/ [^ ]*$//'

48 :名無しさん@お腹いっぱい。:2011/07/12(火) 20:28:22.50
>>47
それを書くなら、
sed 's/[^ ]* *//; s/ [^ ]*$//'
だろ。

49 :名無しさん@お腹いっぱい。:2011/07/12(火) 20:51:25.57
>>48
それだと " a b.log" (頭にスペース)のファイル名が正しく取り出せないだろw

まあ、元の仕様が不明だから何とも言えないが。

50 :名無しさん@お腹いっぱい。:2011/07/12(火) 23:52:50.07
>>46


51 :名無しさん@お腹いっぱい。:2011/07/13(水) 14:24:43.76
誰かわかる方、今週中にお願いします。

以下のバッシュをボーンで書き直せ

#!/bin/bash

color=(Red Green Blue)

for ((i = 0; i < 10; i++)) {
echo ${color[RANDOM*3/32768]}
}

52 :51:2011/07/13(水) 16:59:52.85
早くしろ、おせーぞ
金曜の朝までだ。最低でも月曜の朝まで
俺の単位が掛かっている

53 :名無しさん@お腹いっぱい。:2011/07/13(水) 17:19:38.90
こんな過疎板で釣りか? ご苦労なこった。

54 :名無しさん@お腹いっぱい。:2011/07/13(水) 17:20:04.79
かまうなよ。

55 :名無しさん@お腹いっぱい。:2011/07/13(水) 17:23:02.47
単位がかかってるのかしょうがないな。特別にやってやろう。

#!/bin/sh

exec /bin/bash <<'EOF'
color=(Red Green Blue)

for ((i = 0; i < 10; i++)) {
echo ${color[RANDOM*3/32768]}
}
EOF

56 :51:2011/07/13(水) 17:30:42.13
なんで返事がないのですか?
原理とかも質問したいので、できるだけ早くお願いします。


57 :名無しさん@お腹いっぱい。:2011/07/13(水) 18:30:19.64
>>51
わりぃ、わりぃ。直ぐに書けたけど、環境が分からなくてね。今bourne動かせるかい?

58 :名無しさん@お腹いっぱい。:2011/07/13(水) 18:34:13.92
オマエラ不親切だな。ちゃんと教えてやれよ。


#/bin/sh

echo '#include <time.h>
#include <stdlib.h>
#include <stdio.h>
char*c[]={"Red","Green","Blue"};
int main(){int i;srand(time(0));for(i=0;i<10;i++){
puts(c[rand()*3LL/((RAND_MAX+1LL))]);}return 0;}
'>t.c;gcc t.c;./a.out;rm a.out

59 :名無しさん@お腹いっぱい。:2011/07/13(水) 19:45:55.47
#!/bin/sh
color0=Red
color1=Green
color2=Blue
for i in 0 1 2 3 4 5 6 7 8 9
do
eval echo \$color`expr \`od -An -tu2 -N2 /dev/urandom\` \* 3 / 65536`
done

60 :名無しさん@お腹いっぱい。:2011/07/13(水) 20:16:33.27
traditionalなodだとそのオプションが使えないんだな

61 :名無しさん@お腹いっぱい。:2011/07/13(水) 20:48:13.35
空気読めない空気デブは死ね。

62 :51:2011/07/13(水) 21:05:23.15
みなさん多数の回答ありがとうございました。
一番回答が早かった >>55 さんので提出しようと思います。
本当に助かりました。

63 :名無しさん@お腹いっぱい。:2011/07/13(水) 22:39:12.85
#!/bin/sh
str_rand=
str_rand_buf=
while : ; do
 str_rand=$( expr "`echo "$$$str_rand$( date )" | md5sum`" : '\([^ ]*\)' )
 str_rand_buf=$str_rand_buf$str_rand
 if expr $str_rand_buf : '^\(...\)*$' >/dev/null ; then
  echo $str_rand_buf | sed 's/.../\0\n/g'
  str_rand_buf=
 fi
done | tr 0123456789acf 'bureRGdlRlrGu' |
sed -n 'y/b/B/;/Red/p;/Gre/s/$/en/p;/Blu/s/$/e/p' |
head -n 10

理解度の違いを見せ付けるチャンス!

64 :名無しさん@お腹いっぱい。:2011/07/14(木) 01:23:51.41
>>51
#!/bin/sh

color=(Red Green Blue)

for ((i = 0; i < 10; i++)) {
echo ${color[RANDOM*3/32768]}
}

65 :名無しさん@お腹いっぱい。:2011/07/14(木) 03:46:47.41
>>44
1,2,3 が最初のフィールドで、root,apache,mysql が最後のフィールドで
間にあるのがログファイルのリストだと仮定するならば、awkコードを

{
for(n=2; n<NF; n++) {
printf "%s ", $n
}
print ""
}

とすれば出来るんじゃないかな
ただ間にあるログファイル名が「空白自体をファイル名に含む」という場合はこれではできない。
>>49 の言う通り、そういう細かい仕様を明確にしないと書きようがない。

66 :名無しさん@お腹いっぱい。:2011/07/14(木) 07:15:18.61
tclはすばらしい

67 :名無しさん@お腹いっぱい。:2011/07/14(木) 07:30:57.51
bashって do 〜 done を { 〜 } で書けたんだね。知らなかった。
manにない(のかな?)けど、bashの拡張?何時ごろ入ったんだろ。

68 :名無しさん@お腹いっぱい。:2011/07/14(木) 07:40:43.45
>>67
ボーンでも for で { } って書けるよ。昔から。
whileでは書けない。

69 :名無しさん@お腹いっぱい。:2011/07/14(木) 07:53:05.71
>>68
そーなのかー。ありがとう。確かにwhileは無理だった。でもselectはいけた。
whileはlistをとるから、区別できなくて使えないんだろうね。
while :;:;:;:;:;:;:; do echo ok; done
こんな風に書けるとは思ってなかったよ。

70 :名無しさん@お腹いっぱい。:2011/07/15(金) 12:07:24.41
>>262
ファイルの先頭に文字を追加するにはどうすればいいですか?

71 :名無しさん@お腹いっぱい。:2011/07/15(金) 12:31:53.02
スレが建ってからおよそ一ヶ月。回答を得られるのは約四ヵ月後か。

72 :名無しさん@お腹いっぱい。:2011/07/15(金) 12:34:06.01
ずいぶんロングパスだね。>>262までは2か月くらいかなあ。

73 :名無しさん@お腹いっぱい。:2011/07/15(金) 12:45:53.46
>>70
rename "" "prefix" file...
とか
prename 's/^/prefix/' file...
とか


74 :名無しさん@お腹いっぱい。:2011/07/15(金) 13:01:11.76
>>73
ありがとうございます。

Sedでファイル先頭を置換するのと、
中カッコでエコーとキャットをグルーピングする方法を思いついたので、今回はそれで行こうと思います。

75 :名無しさん@お腹いっぱい。:2011/07/15(金) 13:16:40.99
>>74 を見る限り、
>>73 は明らかに勘違いした回答(ファイル名を変換してるw)だが、
ありがたいか?w

76 :名無しさん@お腹いっぱい。:2011/07/15(金) 13:27:40.84
>>74の書き方はネタのつもりでしょ。

77 :名無しさん@お腹いっぱい。:2011/07/15(金) 14:34:55.66
>>73
横からだが、ありがとう。renameの亜種がいっぱいあるせいでperlで実装されたものが行方不明だったんだが、
うちのシステムにもprenameで見つかった。プログラムの名前はかち合うように作らないで欲しいな。

78 :名無しさん@お腹いっぱい。:2011/07/15(金) 15:12:27.61
>プログラムの名前はかち合うように作らないで欲しいな。

*BSD や Linux の killall と同じつもりで Solaris で killall を叩いてしまうと、
プロセスだけでなく自分まで死にたくなるな。
# Solaris の killall の方が先のはず


79 :名無しさん@お腹いっぱい。:2011/07/15(金) 18:50:08.88
以下のバッシュをボーンで書き直せ
ただし、添付ファイルを使わないこと

わかる方、来週中までにお願いします。

#/bin/bash

diff -c <(ls -l /フォルダ1) <(ls -l /フォルダ2)

80 :名無しさん@お腹いっぱい。:2011/07/15(金) 23:04:20.09
おまえは>>55 から何も学ばなかったのか?

81 :名無しさん@お腹いっぱい。:2011/07/15(金) 23:53:06.02
学ぶような知能があったらここで質問しないだろ。

82 :名無しさん@お腹いっぱい。:2011/07/16(土) 01:18:33.17
bashとかだと$RANDOMで乱数得られるけど、他のやり方ってどんなのがある?
odとかで/dev/urandom読むとか、md5sumみたいなハッシュ関数使うとか出てるけど。

自分はあまり精度が必要でないときdateでナノ秒とってきて使ったことはある。
awkのrand()使うのも思いついたけど、これだと何でもありか。

環境に依存しないのは、exprで線形合同法でも実装するくらいしかないのかな?

83 :名無しさん@お腹いっぱい。:2011/07/16(土) 05:56:58.17
ぶっちゃけawk使ったほうが環境依存度としては低いかも知れないw(awkにしか依存しないことになるので)
シェルスクリプトとしては/dev/randomをodで読む、が一番いい気がするんだけどなあ

84 :名無しさん@お腹いっぱい。:2011/07/16(土) 07:41:17.60
/dev/randomってどのシステムにもあるの?仕様も同じ?つか、うちだと止まるんだけど。

85 :名無しさん@お腹いっぱい。:2011/07/16(土) 07:44:35.06
gawkやnawkではrand()が使えるが、純正awk(solarisのawkとか)では
rand()は使えないので、その場合わけが必要になる。

86 :名無しさん@お腹いっぱい。:2011/07/16(土) 07:56:05.57
/dev/randomは乱数のタネがたまるまでブロックする。
つーか、貴重な共有リソースだから素人は使うな。/dev/urandom使え。

87 :名無しさん@お腹いっぱい。:2011/07/16(土) 07:59:53.03
randomはともかく、urandomってどの環境にでもあるものなのか?

>>85
そうなのか…perlとかのが却っていいのかな?

88 :名無しさん@お腹いっぱい。:2011/07/16(土) 08:20:01.28
>>86
/dev/urandom -> random に symlinkされてる FreeBSDでどうしろと?

89 :名無しさん@お腹いっぱい。:2011/07/16(土) 08:42:35.59
エントロピーを凌駕するしかないな

90 :名無しさん@お腹いっぱい。:2011/07/16(土) 08:49:18.46
FreeBSDはデフォルトが/dev/urandomのように振る舞うようになっている。
バカが理解せずに使うからバカ用のインターフェースが残された。

91 :名無しさん@お腹いっぱい。:2011/07/16(土) 08:59:56.03
んで、urandomはどの環境にも必ずあるの?
そもそも環境依存の話をしてるんだから、問題はそこだと思うのだけど。

92 :名無しさん@お腹いっぱい。:2011/07/16(土) 09:07:26.58
solaris8以前に/dev/(u)randomはない。

93 :名無しさん@お腹いっぱい。:2011/07/16(土) 09:10:17.78
urandomはおろか、randomも無いのか、そいつぁ困ったな

94 :名無しさん@お腹いっぱい。:2011/07/16(土) 09:15:14.63
>>85
POSIXならrand()あるんだからそれくらい実装してくれよ。

95 :名無しさん@お腹いっぱい。:2011/07/16(土) 09:35:08.13
urandomって30代目ジャンヌダルクのこと?

96 :名無しさん@お腹いっぱい。:2011/07/16(土) 13:48:43.12
どのシステムにも漏れなく入っているハッシュを計算するコマンドで代用はどう?
「どのシステムにも」って所が難しいか。

97 :名無しさん@お腹いっぱい。:2011/07/16(土) 15:17:59.20
ハッシュは乱数じゃないから用途によっては利用できない。

98 :名無しさん@お腹いっぱい。:2011/07/16(土) 15:23:25.28
rand() {
  _seed_="`expr \( ${_seed_} \* 1103515245 + 12345 \) % 4294967296`"
  expr ${_seed_} / 65536 % 32768
}
exprだけで実装。man randからパクリ。

$ _seed_=$$; for i in `seq 5`; do rand; done
21733
22089
6602
23744
28678
乱…数…?か?exprって幾つまで数えられたっけ?そもそも種はどこから持ってくるべきなんだ?

99 :名無しさん@お腹いっぱい。:2011/07/16(土) 19:04:38.58
乱数の種の定番は現在日時じゃね

100 :名無しさん@お腹いっぱい。:2011/07/16(土) 19:42:26.34
>>98
その rand()関数、単純に randで呼び出して表示するだけならいいけど、

i=`rand`
echo $i
みたいに変数に代入する使い方をすると
rand関数全体が暗黙のサブシェルになって、_seed_が更新されないという罠。

101 :名無しさん@お腹いっぱい。:2011/07/16(土) 20:07:11.61
環境に依存しない、現在時刻を数値で取得する方法ってあったっけ。dateで出来たか?

>>100
マジだな。そこまで気にしてなかったわ。欲しい乱数の個数が決まってるなら、これでどうだろ。
for RND in $(for in `seq 10`; do rand; done`); do 〜 done

102 :名無しさん@お腹いっぱい。:2011/07/16(土) 23:25:02.38
mktemp -u XXXXXX
で何とかならないか。A-Za-zが邪魔だけど。cygwinだと/dev/urandomとか
ないんだけど、mktempもGNUにしかない?

103 :名無しさん@お腹いっぱい。:2011/07/17(日) 10:13:28.52
>>99
まだこんな馬鹿がいるのか

104 :名無しさん@お腹いっぱい。:2011/07/17(日) 10:23:13.19
もうjotでいいやw

105 :名無しさん@お腹いっぱい。:2011/07/17(日) 10:45:34.78
>>103
じゃーどうすりゃいいのよ?

>>104
これってBSDだけ?わざわざ用意するってことは、他に適当な方法がないのだろうね。

106 :名無しさん@お腹いっぱい。:2011/07/17(日) 17:25:16.53
/dev/(u)randamがFA。
ないOSには死んでもらったほうがいい。


107 :名無しさん@お腹いっぱい。:2011/07/17(日) 17:33:07.68
暗号にもちいるなら予測可能なタイムスタンプは使わない。
シミュレーションなどで再現性が重要な場合もタイムスタンプは使わない。
したがって、タイムスタンプ使うバカは死滅すべしが結論。

108 :名無しさん@お腹いっぱい。:2011/07/18(月) 00:28:21.96
大量データを処理するツールを作っているのですが、
bash/perl/awkどの言語で作成するべきか悩んでいます。
言語の特性を考えると、どれが一番おすすめでしょうか?

作成するツールの要件は下記の通り。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
作業前後でOSすべてのファイルリスト+md5sumを取得、
比較を取得し、差分を検出する。

取得するファイルリストはfind / -printf %p %T+ %l %s %m %g %uで、
%pの結果すべてをmd5sumに喰わせてハッシュ値を取得する。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
最初はbashで作成したのですが、思ったような性能を出すことができませんでした。
高速化を目指しAwkで作成したところ、10分の1以下になりました。
perlならもう少し早くなります。

が、チームにperl/awkが使えるメンバが自分以外不在です。
bashなら多少使えるそうなのですが…。

個人的には、bashが使えればawkも似たようなものなので、awkで作成しようかと思っているのですが。

109 :名無しさん@お腹いっぱい。:2011/07/18(月) 00:55:51.19
パフォーマンスを向上させたいならホットスポットを見つけて、地道に対処するべきなんじゃないの?
原因も分からず場当たり的に作業しても何も残らんよ。

110 :名無しさん@お腹いっぱい。:2011/07/18(月) 01:11:53.63
>>109
ネックになってるのはハッシュ値を計算している箇所です。
bashだと一行ずつmd5sumを呼び出すためプロセス起動、
ハッシュ値計算とコストがかかりすぎます。

代案としてawk,perlならそこを解決できるとわかったのですが。

ですので、bashでここの問題を解決できるならbashでも構いません。
例えばファイルを一意に識別するのにmd5sum以外の方法があったりとか。

111 :名無しさん@お腹いっぱい。:2011/07/18(月) 01:24:02.13
xargs使って複数のパスを同時に引数に渡せよ。

112 :名無しさん@お腹いっぱい。:2011/07/18(月) 01:25:25.53
>>111
ありがとうございます。
ためしてみます。

113 :名無しさん@お腹いっぱい。:2011/07/18(月) 01:25:50.09
それから内容の同一性確かめなくてもst_ctime使えばいいんじゃないの?
それならrsyncのdry run。

114 :名無しさん@お腹いっぱい。:2011/07/18(月) 01:34:24.76
>>110
awk, perl ではハッシュ計算を行っていないということですか?

115 :名無しさん@お腹いっぱい。:2011/07/18(月) 01:39:49.47
>>113
ls -lで確認できる権限、パーミッション、オーナー、タイムスタンプ、ファイルサイズが全く同じで、
中身だけ異なるようなファイルを cp -pで入れ替えられた場合を考慮していたつもりだったのですが。
今ctimeの仕様を見るとinodeも考慮してくれているのですね。
であれば、ctimeでOKという気もします。
rsyncのdry-runというのもあるのですね…
勉強不足でした。
まだ理解で規定な箇所もありますが、
早速、教えてもらった方法を試してみます。
ありがとうございます。

116 :名無しさん@お腹いっぱい。:2011/07/18(月) 01:40:57.89
>>114
いえ、しています。
が、findの結果一行ごとにmd5sumを起動しないので、早くなっていました。

117 :名無しさん@お腹いっぱい。:2011/07/18(月) 06:21:49.95
rsyncの--checksumオプションを使った場合、
awkやperlと比べてどちらが速いのだろうかと思った。


118 :名無しさん@お腹いっぱい。:2011/07/18(月) 10:12:13.56
>>113
st_ctimeでは無理でした。

事前、事後にrsyncでバックアップ、リストアを実施しています。
リストアップのタイミングで必ずctimeが変わるため、
ファイルの内容に変更がない場合でも必ず差分として出てしまいます。
代わりにmtimeが戻るのでmtimeで比較も考えたのですが、
touch コマンド等で修正時刻を操作された時に検知が出来ません。

やっぱり、なにかしらファイルの同一性を見る必要があります。
xargsは文字数制限が発生したおちましたが、
オプションでなんとかならないか調べてみます。

119 :名無しさん@お腹いっぱい。:2011/07/18(月) 10:13:09.33
>>117
私が作るアホシェルよりは早いきがしますね。
こちらも試してみます。
ありがとうございます。

120 :名無しさん@お腹いっぱい。:2011/07/18(月) 12:02:10.50
ノンストップの処理を行わせておいて、指定した時間の経過で自爆させる時って
( cat /dev/zero > /dev/null & ; sleep 10 ; kill $$ ) &
のような感じで良いですか?

121 :名無しさん@お腹いっぱい。:2011/07/18(月) 12:13:32.54
>>108
tripwireというファイルの改変を検出するツールがある。

122 :名無しさん@お腹いっぱい。:2011/07/18(月) 12:17:22.58
>>121
tripwireも検討したのですが、処理が重く…
時間がかかるため、自作することにしております。

123 :名無しさん@お腹いっぱい。:2011/07/18(月) 14:08:26.48
>>120
$$はサブシェルのPIDに展開されない。親が死ぬよ。

ファイルシステム全体のスナップショットを取って、そこから個々のファイルの差分を取れたら凄く楽そうなんだがなぁー。

124 :名無しさん@お腹いっぱい。:2011/07/18(月) 14:18:10.71
>>102
-uオプションって初めから有った?昔mktempスクリプトから
使おうとして動かなかったことがあったけど、何が原因だったけ…

もう一つ思いついたのは、重複が無いって条件付でこんなのはどうだ?
seq 1 10 | sort -R

125 :名無しさん@お腹いっぱい。:2011/07/18(月) 14:31:10.36
>>124
sortの -Rオプションが思いっきりGNUですw

GNU mktemp -u はドライラン
freebsdやsolarisの mktemp -u は、unlinkオプション。
動作が違う。

126 :名無しさん@お腹いっぱい。:2011/07/18(月) 14:49:59.58
>>125
やっぱりかー。微かにそんな気はしてたToT
mktempとか(自分のまわりでは)良く使われてるのに
別の環境に持ってくと挙動が違って泣きたくなる事あるよね。

こんなオプションが挙動違うのかよって思ったコマンドってどんなのがあったけかな…

127 :名無しさん@お腹いっぱい。:2011/07/18(月) 17:12:19.63
topも結構違わなかったっけ

128 :名無しさん@お腹いっぱい。:2011/07/18(月) 17:15:36.05
>>108
自己レスです。
教えていただいた方法で大分早くできました。

find の結果をawkで1行ずつ整形。
ディレクトリ、シンボリックリンクなら%p %T+ %l %s %m %g %uのみ出力。
ファイルだったらxargs -P 0 md5sum にてハッシュ値を取得、
findでとった%p %T+ %l %s %m %g %uにハッシュ値を付与しました。

大分早くはなりましたが、勉強も兼ねてもう少し、うまい方法がないか考えてみます。

129 :名無しさん@お腹いっぱい。:2011/07/18(月) 20:38:06.07
>>79 わかる方、今週中にお願いします

130 :名無しさん@お腹いっぱい。:2011/07/18(月) 21:53:30.40
>>129
コテハンつけてくれないかな。

131 :名無しさん@お腹いっぱい。:2011/07/18(月) 23:45:41.77
シェルスクリプトで、特定の確率でcommandを実行する方法ありますか?
単純に 30% とかなら
RANDOM % 3 -eq 0
でいけると思いますが、27% とかだったらどうすればいいのか。。。


132 :名無しさん@お腹いっぱい。:2011/07/19(火) 01:11:18.64
>>131
function foo() {
local -i i="$1"
((RANDOM % 100 < i)) && "$2"
}

foo 27 command

とかで正しい?

133 :名無しさん@お腹いっぱい。:2011/07/19(火) 16:45:00.33
>>132
すみません、頭が固くて嫌になるのですが
RANDOM % 100 < i
これでどうして確率になるのでしょうか?

134 :名無しさん@お腹いっぱい。:2011/07/19(火) 17:28:19.82
100で割った余りは0から99

135 :132:2011/07/19(火) 17:47:19.49
>>132
RANDOM の取り得る値が 0 から 32767 だから、
foo 27 command
だと正確には 27% にならないかな。

RANDOM % 3 -eq 0 で 30% らしいから、そこまで正確でなくて良いのか。

136 :名無しさん@お腹いっぱい。:2011/07/19(火) 17:47:38.63
>>131
RANDOM % 3 -eq 0
は、30%じゃなくて 33.3333..% な。

あと、算術式だと ((RANDOM % 3 == 0)) な。

137 :名無しさん@お腹いっぱい。:2011/07/19(火) 17:55:14.67
%単位で正確にやるには100の倍数からはみ出たところを捨てるか。

while (((i = RANDOM) >= 32700)); do :; done
((i % 100 < 27)) && echo OK

138 :名無しさん@お腹いっぱい。:2011/07/19(火) 20:36:23.78
>>133
bashだから

139 :131:2011/07/20(水) 11:03:58.02
みなさま、ありがとうございました。
理解できました。

それほど正確じゃなくてもいいので、これで十分です。ありがとう

140 :名無しさん@お腹いっぱい。:2011/07/20(水) 13:07:21.50
>>173
RANDOM >= 32700 じゃなくて RANDOM <= 32700
だな

141 :名無しさん@お腹いっぱい。:2011/07/20(水) 13:15:05.19
>>140
ちがうよ。

>>137 で合ってるよw

142 :名無しさん@お腹いっぱい。:2011/07/20(水) 13:20:05.99
>>140
こういう、正解を間違い呼ばわりするアホは何とかならないものか

143 :140:2011/07/20(水) 14:49:05.40
なんで?

while (((i = RANDOM) >= 32700)); do :; done

これだと i は 32700〜32767

((i % 100 < 27)) → (0〜67 < 27)

おかしいじゃん。



144 :名無しさん@お腹いっぱい。:2011/07/20(水) 14:59:57.76
>>143

> これだと i は 32700〜32767

↑ ハイ、ここ違うね。

おまえ数学もプログラムも苦手だろw

145 :名無しさん@お腹いっぱい。:2011/07/20(水) 15:08:47.98
>>143
while (((i = RANDOM) >= 32700)); do :; done
の実行後、
iの範囲は 0〜32699 になる。

whileループの基本。
わからないなら試してみろ。

$ while (((i = RANDOM) >= 32700)); do :; done
$ echo $i
25678

146 :名無しさん@お腹いっぱい。:2011/07/20(水) 16:24:25.04
このやりかたって、乱数が完璧なら、
一定の確率で1日たっても終わらんなんて事態も発生するよな

147 :名無しさん@お腹いっぱい。:2011/07/20(水) 17:30:48.35
たしかに可能性はゼロではないが、
1日どころか1秒以上ループが回り続ける確率ですら
宝くじで3億円当てるより低いだろう。


148 :名無しさん@お腹いっぱい。:2011/07/20(水) 18:17:25.23
それを気にするなら、unsetとかexportとか気にするべきでは?
どっかにexport RANDOM=40000とか入れられたら意図的に無限ループにできる。

149 :名無しさん@お腹いっぱい。:2011/07/20(水) 18:23:08.03
exportは大丈夫だけどunsetはまずいな

150 :名無しさん@お腹いっぱい。:2011/07/20(水) 18:27:10.90
>>148
export RANDOM=40000
ってやっても、それはseedが設定されるだけで
RANDOMは乱数のまま(無限ループにならない)。

一旦unset RANDOMしてからexport RANDOM=40000とやれば
RANDOM=40000固定になるが、いくらexportしても
スクリプト起動時に別のシェルが起動され、
exportに関わらずRANDOMは乱数機能で動作する。

151 :名無しさん@お腹いっぱい。:2011/07/20(水) 18:42:44.54
確かに固定にしようと思ったらunsetやってからexportしないと駄目だね。
だけど、それでスクリプト書いて試したらRANDOMが40000で固定されたんだが?うちのbashだけか?

もう一つ気が付いたのだが、exportするとそこから呼ばれたスクリプトの乱数列が固定される。
用途によってはこれも問題な気がする。

152 :名無しさん@お腹いっぱい。:2011/07/20(水) 18:56:13.45
>>151
>exportするとそこから呼ばれたスクリプトの乱数列が固定
>>150のいうseedの意味が分からんかったのか。
ランダムなseedを保証したかったら、スクリプトの中で
RAMDAMをランダムな数値でexportすればよい


153 :名無しさん@お腹いっぱい。:2011/07/20(水) 19:10:37.88
それよりアホな子の >>140 = >>143 の釈明会見まだぁ?

154 :名無しさん@お腹いっぱい。:2011/07/20(水) 19:29:27.84
>>152
RANDOMをランダムな数値でexport…だと…?

155 :名無しさん@お腹いっぱい。:2011/07/21(木) 20:52:45.10
>>140 = >>143 は赤面して逃げ出したのか?

156 :名無しさん@お腹いっぱい。:2011/07/21(木) 21:15:13.59
>>140もあれだが、おまえももっとさわやかになれよ

157 :名無しさん@お腹いっぱい。:2011/07/23(土) 14:32:26.17
他のサーバにtelnetでログインして、シェルを実行して、ログを取得することはできますか?

158 :名無しさん@お腹いっぱい。:2011/07/23(土) 14:58:56.53
できますん。
そもそもtelnetじゃないとだめなのか?
普通そういう時にはremshやsshを使うもんだが。

159 :名無しさん@お腹いっぱい。:2011/07/23(土) 15:06:51.98
どうしてもtelnetでやりたいならexpectを使うと簡単。

160 :名無しさん@お腹いっぱい。:2011/07/23(土) 15:27:00.01
>>158、159
ありがとうございます。
remshというのは知りませんでした。
sshは使えないと思います。
expectはネットで用例を見つけました。
teratermマクロで似たようなことをやっていたこともあるんですが、シェルスクリプトにした方が色々出来そうなのでちょっと調べてみます。

161 :名無しさん@お腹いっぱい。:2011/07/24(日) 01:22:52.02
>>160
> sshは使えないと思います。

使えるよ。ssh-agent使えよ。

162 :名無しさん@お腹いっぱい。:2011/07/24(日) 03:10:34.27
>>161
該当のサーバはtelnet接続のみでssh接続自体ができないということです。
設定を変える権限もありませんので。

163 :名無しさん@お腹いっぱい。:2011/07/24(日) 05:01:00.56
ログの出力先がサーバでなく、ターミナルを動かしてるPC側ってことなら
ターミナルソフトによってはログ取れるのもあるから(teratermも確かあるよね?)
ターミナルでログ開始して、ログ取りたいコマンド打てば良いんでね

164 :名無しさん@お腹いっぱい。:2011/07/24(日) 12:17:28.79
>>163
teratermでは出来ると思いますが、バージョンによってマクロの仕様が異なるのと、フリーソフトに頼るのもいまいち不安なのです。
expectで各サーバにログインして、シェルスクリプトを実行、ログをサーバ上に保存。ftpでログを接続元サーバにget。
取得したログをcatで一つにまとめる。
こんな感じで考えています。
自宅でvmware playerでcent osとfreeBSDを動かせるようにしているので、それで試してみようと思います。
しかし、cent osはsshでしか接続出来なかったとおもうので、設定を弄らなければならないですね。

165 :名無しさん@お腹いっぱい。:2011/07/24(日) 12:36:39.42
わざわざ別ファイルに保存して、FTPで取りに行くようにするのはなんでだろ?

166 :名無しさん@お腹いっぱい。:2011/07/24(日) 14:19:06.63
凄い初歩的な質問で申し訳ないのですが、2個以上の半角スペースを区切り文字に指定して抜き出す方法ってありますか?

例えば
a b c d e

の場合c dだけ抜き出したいんですが…

167 :名無しさん@お腹いっぱい。:2011/07/24(日) 14:23:03.91
awk '{ print $3,$4 }'

168 :名無しさん@お腹いっぱい。:2011/07/24(日) 14:23:14.34
>>166
あう…例えが全部半角になっちゃった

_が半角スペースで
a__b___c_d__e
の場合です。


169 :名無しさん@お腹いっぱい。:2011/07/24(日) 14:26:05.14
>>167
うーん
言い方が悪かったですね。
c_dの部分は一列として抜き出したいです

この場合は3列目だけでc_dって感じで…

170 :名無しさん@お腹いっぱい。:2011/07/24(日) 14:37:19.49
>>166

sed 's/.*[ ][ ]¥(.*¥)[ ][ ].*/¥1/'

171 :名無しさん@お腹いっぱい。:2011/07/24(日) 14:46:48.40
>>169
>>167でちゃんと一列で出てくると思うけど。

172 :名無しさん@お腹いっぱい。:2011/07/24(日) 14:47:27.51
あ、行じゃなく列ってことか?
いまいち仕様がよくわからん。

173 :名無しさん@お腹いっぱい。:2011/07/24(日) 14:52:42.92
>>170
おー素晴らしい。
ありがとうございます。

174 :名無しさん@お腹いっぱい。:2011/07/24(日) 14:59:17.68
>>172
$3 $4だと冒頭とかがa_bみたいな文字列だった場合、ずれてしまうんです…でもありがとう。

175 :名無しさん@お腹いっぱい。:2011/07/24(日) 15:01:12.88
1行に複数無いのか?

176 :名無しさん@お腹いっぱい。:2011/07/24(日) 15:01:41.19
>>174
冒頭が「a b」でもちゃんと出るでしょ?

177 :名無しさん@お腹いっぱい。:2011/07/24(日) 15:08:27.16
>>176
えーと
こんな時は…
a_b___b__c_d__e

bcって出ちゃうと思います。
こんな時でもc_dって出したいわけです。

178 :名無しさん@お腹いっぱい。:2011/07/24(日) 16:31:56.55
>>165
expectで接続元のサーバにリダイレクト出来ますか?

179 :名無しさん@お腹いっぱい。:2011/07/24(日) 19:26:16.15
>>177
なんか凄い出遅れた感があるけど、awkでやるならフィールドセパレータに正規表現を使えばいい。
awk -F'__+' '{print$3}'
同じようにアンダースコアはスペースに置き換えてね。

180 :名無しさん@お腹いっぱい。:2011/07/24(日) 20:22:08.50
>>179
ほーawkでフィールドセパレート指定出来るのは知ってましたがそんなやり方有るんですね
勉強になります。
見た目はそっちのがスマートですね。


181 :名無しさん@お腹いっぱい。:2011/07/24(日) 21:05:20.05
>>179
いま帰って試して見たんですがawkのやり方だと完璧ですね。
上で教えていただいたsedでやる方法だと文字が長くなったりスペースの数が不定だと変な所が抜き出されて駄目っぽいです。
今回はこちらの方法で行きますTHX

182 :名無しさん@お腹いっぱい。:2011/07/24(日) 23:10:11.58
>>79 早く、明日の朝までにお願いします!!

183 :名無しさん@お腹いっぱい。:2011/07/24(日) 23:33:13.25
そのネタもういいよ。

184 :名無しさん@お腹いっぱい。:2011/07/24(日) 23:47:31.61
>>79

dir1=`ls -l /dir1`
dir2=`ls -l /dir2`
diff -c "$dir1" "$dir2"

185 :名無しさん@お腹いっぱい。:2011/07/25(月) 00:15:41.71
すみませんが詳しい方のみ回答をお願いします

186 :名無しさん@お腹いっぱい。:2011/07/25(月) 04:05:42.24
>>79

#! /bin/sh
ls -l /フォルダ1 | (ls -l /フォルダ2 | diff -c /dev/fd/3 /dev/fd/4 4<&0) 3<&0


187 :名無しさん@お腹いっぱい。:2011/07/25(月) 06:30:34.66
>>186
ありがとうございます。これで提出しておきます。

188 :名無しさん@お腹いっぱい。:2011/07/25(月) 10:30:54.08
文字列を一文字ごとにバラバラに処理するのは、どう書くのが一番かな?
できるだけ多くのシェルで動かせるようにしたいのだけど。
自分で思いついたのはこんな感じ。
while read line; do
while :; do
chr=`echo -n "$line" |cut -c 1`
echo -n "<$chr>"
[ "$chr" = "$line" ] && break
line="$(echo -n "$line" |cut -c 2-)"
done
echo
done

189 :名無しさん@お腹いっぱい。:2011/07/25(月) 10:32:20.19
そういうのはLL使っちゃうな。

190 :名無しさん@お腹いっぱい。:2011/07/25(月) 10:48:44.13
while read line; do
for chr in $(echo -n "$line"| sed -e 's/\([^ ]\)/ \1/g'); do
echo "<$chr>"
done
done


191 :名無しさん@お腹いっぱい。:2011/07/25(月) 10:56:15.33
bashならこうも書けるか。部分文字列の置換って標準的かな?
while read line; do
while [ -n "$line" ]; do
chr="${line:0:1}"
echo -n "<$chr>"
line="${line:1}"
done
echo
done

>>188
これのchrに設定するところ、"〜"で括り忘れてた。

192 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:05:34.59
>>191
bash使っていいならもっと簡単に書ける。
(改行も同列扱いだけど)


while read -n 1 c
do
echo -n "<$c>"
done

193 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:12:55.14
> できるだけ多くのシェルで動かせるようにしたいのだけど。
ってお題なのに、bashならって言い出すのってなんなの? 池沼?

194 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:17:25.34
>>193
欲嫁。

>>191
> bashならこうも書けるか。

に反応してるんだろ。
「どうせbashならもっと簡単に書け」と。

195 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:20:11.07
>>193
そう突っかかるなよ。>>188は「できれば」って言ってるし答えてる方も
『bash「なら」』って書いてるだろ

196 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:22:06.95
>>189
> できるだけ多くのシェルで動かせるようにしたいのだけど。
ってお題なのに、LL使っちゃうって言い出すのってなんなの? 池沼?

197 :189:2011/07/25(月) 11:29:21.25
>>196
「できるだけ多くのシェルで動かせるようにしたい」ってだけで、
「シェルで動かなければならない」ってことではないでしょ?

198 :189:2011/07/25(月) 11:30:37.16
要件をちゃんとわかってるのは質問者だけなんだから、
質問者以外がどうこう言ってもしょうがないよ。

199 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:37:42.92
>>194
はあ? ↓これをまとめて書いたんだが。池沼?

if (181 == 191) {
> できるだけ多くのシェルで動かせるようにしたいのだけど。
って、お題出してといてbashならって言い出すってなんなの? 池沼?
} else {
> できるだけ多くのシェルで動かせるようにしたいのだけど。
って、お題もらっといてbashならって言い出すってなんなの? 池沼?
}

200 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:45:49.19
>>178
ログはstdoutに出して、その出力を全部expectで処理すればいい。
expectに付いてくるサンプル改造すればすぐ出来る。

201 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:47:15.57
>>199
ちょっと意味がわからない。

202 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:51:29.37
>>193は脊髄反射系

203 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:54:58.50
188です。いろいろなレスありがとう御座います。
シェルスクリプトで簡単なパーサを書きたいなと思いまして、質問しました。
perlのようなLLや、sed、awkなどを使うと全部それにやらせればいい
と言う話になりますので、私自身は使わずに書きました。

実際書こうとすると、個々の文字に分解する標準的な方法が無いのかと気になった次第です。
せめて簡単な正規表現をシェルスクリプトだけで実装したいので、
正規表現を扱える外部コマンドを呼ぶのは何だかな、と言ったところです。

204 :名無しさん@お腹いっぱい。:2011/07/25(月) 11:56:29.84
全部それにやらせればいいのに。
だめなのかな。

205 :名無しさん@お腹いっぱい。:2011/07/25(月) 12:02:42.08
>>199
私の書き方が悪く、意味が不明瞭になってしまったようで、大変申し訳なく思っています。
そこは、bashではこう書けるが他のシェルでも使える標準的な方法か?と聞きたかったのです。
重ね重ね、池沼さん、大変申し訳ありませんでした。

206 :名無しさん@お腹いっぱい。:2011/07/25(月) 12:06:30.43
>>204
同じような実装をしたときにどの程度の速度差があるのか調べる目的もあります。
シェルスクリプトは基本的に速さに期待できないのは分かっていますが、計ったことがなかったもので。

207 :名無しさん@お腹いっぱい。:2011/07/25(月) 14:39:53.04
アンチbashがよく可搬性の点から、bashスクリプトを非難するけど、
シェルのシェアを考えると、bashはどの程度なんだろうね。
MacOSXやLinuxが基本bash (dashを含む)なので、bashが首位で
かなりの割合を占めそうだけど。


208 :名無しさん@お腹いっぱい。:2011/07/25(月) 14:42:56.49
世界全体のシェアを考えてもあんまり意味がないと思うなぁ。
要は自分が作ったスクリプトが自分が使う環境で動けばいいんでしょ。

209 :名無しさん@お腹いっぱい。:2011/07/25(月) 14:46:19.02
bashスクリプトが#!/bin/shを名乗ってるから非難するのであって
#!/bin/bashなら問題ないよ

210 :名無しさん@お腹いっぱい。:2011/07/25(月) 15:08:47.23
Linuxでは sh -> bashのシンボリックリンクによって
shの正体はbashであることを明示している。(Debianは sh -> dash)

しかし、FreeBSDはshの正体がashであるにもかかわらず、
ashの名前ではインストールされておらず、
shを名乗ったままシンボリックリンクすら存在しない。

これはおかしい。

211 :名無しさん@お腹いっぱい。:2011/07/25(月) 15:34:35.74
>>210
send-prしといて。

212 :名無しさん@お腹いっぱい。:2011/07/25(月) 15:47:03.82
/bin/sh が ksh な環境もたくさんあるけどどうしましょう。

213 :名無しさん@お腹いっぱい。:2011/07/25(月) 15:56:42.40
>>210
/bin/shのような基本コマンドはカーネルから直接exec()で呼び出されたりもするから
symlinkには出来ないんだよ。システムコールのexec()はsymlinkを追跡しない。
ライブラリのexec()では、内部でreadlink()呼んでsymlinkを追跡するから
気づかないんだけどね。

214 :名無しさん@お腹いっぱい。:2011/07/25(月) 16:06:53.82
普通にsymlink追跡するよ。何歳だよジジイ。戦前の話か? www

215 :名無しさん@お腹いっぱい。:2011/07/25(月) 17:08:09.74
>>203
shは構文木を保持するのが苦手。

カーニハンが"Beautiful code"で書いた
正規表現関数を模倣してみては? 文書はPDFで手に入る。
あれは内部表現使わずに解析する毎に逐次的に実行してるから。


216 :名無しさん@お腹いっぱい。:2011/07/25(月) 19:24:14.52
>>213
じゃあ、ハードリンクでいいじゃない。

217 :名無しさん@お腹いっぱい。:2011/07/26(火) 09:10:17.00
>>215
ありがとう。元々内部表現を使う実装は無理かなと思っていたので、そのようにするつもりです。
どちらにせよ、一文字一文字個別に扱えたほうが都合が良いので、どのような方法があるのだろうと思ったのです。

218 :名無しさん@お腹いっぱい。:2011/07/26(火) 12:22:22.72
内部表現持たないと、扱える正規表現の仕様はかなり小さくなる。

219 :名無しさん@お腹いっぱい。:2011/07/30(土) 00:54:06.04
bashでファイルの1行目の10バイト目にある文字だけ置換させたいのですが
どのように書けばいいか教えていただけますでしょうか。
sed、awkコマンドでいろいろやってみたのですが、知識不足で
全行の10バイト目が置換されたりしてなかなかうまくいきません。
回答お願いします。

220 :名無しさん@お腹いっぱい。:2011/07/30(土) 01:42:36.22
sedはパス。awkならこんな感じ。でも多分edの方が速い。
awk 'NR==1{$0=substr($0,1,9)"x"substr($0,11)};1' file

ed -s file <<\EOF
1s/\(.\{9\}\)./\1x/
wq
EOF

もっといい書き方はあるかも。まあこの方法は、10バイト目じゃなくて10文字目なのがもしかしてマズイかも。

221 :名無しさん@お腹いっぱい。:2011/07/30(土) 01:50:27.92
ついでだからsedでも書いた。GNU sedなら3つの中で一番遅い方法かな。
sed -n '1s/\(.\{9\}\)./\1x/;p' file

222 :名無しさん@お腹いっぱい。:2011/07/30(土) 09:07:27.37
うとうとしながら書くもんじゃねーな。↑は、いらん部分があった。
sed '1s/\(.\{9\}\)./\1x/' file

223 :名無しさん@お腹いっぱい。:2011/07/30(土) 09:29:04.52
>>219
せっかくbashならbashの機能使おうや。

(IFS= read -r; echo "${REPLY:0:9}X${REPLY:11}"; cat) < in_file

224 :名無しさん@お腹いっぱい。:2011/07/30(土) 11:06:18.91
bashのくせに#!/bin/shとか書いてあるんだからそんな特殊機能なんか使うなよ

225 :名無しさん@お腹いっぱい。:2011/07/30(土) 11:41:44.30
>>224
特殊機能?

kshでもzshでも使える(>>223 がそのまま動く)汎用機能だが?

226 :名無しさん@お腹いっぱい。:2011/07/30(土) 15:44:10.40
/bin/sh と書くからにはコメントすらも特殊機能だからな

227 :名無しさん@お腹いっぱい。:2011/07/30(土) 16:28:16.50
シェルスクリプトでのコメントなんてライセンスの主張くらいにしか使わんだろw

228 :名無しさん@お腹いっぱい。:2011/07/30(土) 18:45:38.24
おまえは1000行野郎を書いたことがないな

229 :名無しさん@お腹いっぱい。:2011/07/31(日) 02:00:07.31
改版履歴とか書いたりして

230 :名無しさん@お腹いっぱい。:2011/07/31(日) 10:01:27.19
>>228
何それ?

231 :名無しさん@お腹いっぱい。:2011/07/31(日) 11:13:57.94
>>229
せめてRCS使おうぜ

232 :名無しさん@お腹いっぱい。:2011/08/02(火) 21:23:22.11
bashで前ゼロ削除をやろうとしているのですが、
初心者のためうまくいきません。すみませんがご教授ください。
00099999

99999

233 :名無しさん@お腹いっぱい。:2011/08/02(火) 21:31:16.74
expr 00099999 + 0

234 :名無しさん@お腹いっぱい。:2011/08/02(火) 21:37:09.94
>>233
こういう風に答えられるように私はなりたい。
echo 00099999 | awk 'sub(/^0+/,"")'

235 :名無しさん@お腹いっぱい。:2011/08/02(火) 21:38:17.44
a=00099999
echo $(( 10#$a ))

236 :名無しさん@お腹いっぱい。:2011/08/02(火) 21:50:26.85
echo ${a##*0}

237 :名無しさん@お腹いっぱい。:2011/08/02(火) 21:55:45.95
>>234,>>236
a=0 だとダメ

238 :名無しさん@お腹いっぱい。:2011/08/02(火) 22:12:30.31
>>236 は、a=102 とかでも駄目。
ベストアンサー >>235

239 :名無しさん@お腹いっぱい。:2011/08/02(火) 22:25:25.84
>>233全力スルーでワロタw

240 :名無しさん@お腹いっぱい。:2011/08/02(火) 23:14:14.84
echo ${a##0*0}でいいんじゃない?

241 :名無しさん@お腹いっぱい。:2011/08/02(火) 23:16:34.59
あー、a=010999だとダメかw

242 :名無しさん@お腹いっぱい。:2011/08/02(火) 23:17:44.95
a=000 とか a=0102 とか

243 :名無しさん@お腹いっぱい。:2011/08/02(火) 23:24:30.00
echo $a | sed 's/^00*\(..*\)$/\1/'

244 :名無しさん@お腹いっぱい。:2011/08/02(火) 23:25:43.52
[[ $a =~ ([^0][0-9]*|0)$ ]]; echo ${BASH_REMATCH[0]}

245 :名無しさん@お腹いっぱい。:2011/08/02(火) 23:48:40.41
expr $a : "0*\(..*\)"

246 :名無しさん@お腹いっぱい。:2011/08/02(火) 23:50:43.83
無駄に長くしてみた
t=$a; while :; do case $t in 0?*) t=`expr $t : '^0\(.*\)$'`;; *) break;; esac; done; echo $t

247 :名無しさん@お腹いっぱい。:2011/08/03(水) 08:29:25.47
>>243 >>245
a=-003 とかのときダメ

>>233>>235
-003 でもOK

248 :名無しさん@お腹いっぱい。:2011/08/03(水) 09:34:09.41
直感的なわかりやすさで>>233だな。
既存の文法に無理矢理おさめただけの#って何だよって感じだ。

249 :名無しさん@お腹いっぱい。:2011/08/03(水) 09:34:17.69
符号付きも考えるのかよ…

echo $a | sed 's/^\([+-]\{0,1\}\)00*\(..*\)$/\1\2/'

そういや小数点はどうする?

a=001.3

>>233>>235だとエラーになるぜ


250 :名無しさん@お腹いっぱい。:2011/08/03(水) 09:45:31.48
>>249
\?「俺忘れられてね?」

251 :名無しさん@お腹いっぱい。:2011/08/03(水) 09:58:20.89
おまえら>>232の細かい仕様が分からないままでよくそんなに遊べるな。
実は、sed 's/000//' ですむ問題かもしれないぞ

252 :名無しさん@お腹いっぱい。:2011/08/03(水) 09:59:38.84
a=1000だったら…

253 :名無しさん@お腹いっぱい。:2011/08/03(水) 10:02:05.30
>>250
スマン、、

echo $a | sed 's/^\([+-]\?\)00*\(..*\)$/\1\2/'


254 :名無しさん@お腹いっぱい。:2011/08/03(水) 11:00:28.45
>>249
expr で >>233 がエラーになる環境って何?

次善策はbcに食わせることかな

echo -00123 | bc

255 :名無しさん@お腹いっぱい。:2011/08/03(水) 11:11:50.20
なんで要求がどんどん増えるんだ。

256 :名無しさん@お腹いっぱい。:2011/08/03(水) 11:47:06.73
曖昧な仕様で最小限の要求だけ想定するとつまんないから

257 :名無しさん@お腹いっぱい。:2011/08/03(水) 11:47:40.69
printf '%d' 00099999
じゃだめか?

258 :名無しさん@お腹いっぱい。:2011/08/03(水) 11:49:01.23
おまえらががっつくから>>232が怖がって出てこないじゃねーか

259 :名無しさん@お腹いっぱい。:2011/08/03(水) 11:51:38.84
>>257
printf '%d' 00011111とかやると2進数だとして処理されちゃうので
printf '%g' の方がいい



260 :名無しさん@お腹いっぱい。:2011/08/03(水) 12:16:53.25
間違えた、octalで処理されるんだった

261 :名無しさん@お腹いっぱい。:2011/08/03(水) 12:18:58.25
>>259
$ printf '%g' 01234500
1.2345e+06

だめじゃん。

現在の最良回答: >>233 >>235 >>254

262 :名無しさん@お腹いっぱい。:2011/08/03(水) 12:31:37.13
ん?結局整数限定?

263 :名無しさん@お腹いっぱい。:2011/08/03(水) 12:35:11.55
小数アリなら >>254 のみ正解か

264 :名無しさん@お腹いっぱい。:2011/08/03(水) 12:38:51.53
だな

265 :名無しさん@お腹いっぱい。:2011/08/03(水) 12:48:54.11
>>253がもうちょっとまともに動けば文字列処理型で最善だったかもな。


266 :名無しさん@お腹いっぱい。:2011/08/03(水) 12:58:05.76
>>261
まてよ、、指数表記もアリだとしたら…

a=001.2345e+06
echo $a | bc
(standard_in) 1: syntax error


267 :名無しさん@お腹いっぱい。:2011/08/03(水) 13:41:25.51
>>233
その発想がすげぇ。

268 :名無しさん@お腹いっぱい。:2011/08/03(水) 17:30:18.84
たぶん >> 233 で FA だと思うが…

>> 266
a="-001.2345e+06"
echo $a | sed 's/\([0-9.]*\)[Ee]\([+-]\?[0-9]*\)/\1*10^(0\2)/' | bc
-1234500.0000


269 :名無しさん@お腹いっぱい。:2011/08/03(水) 17:52:20.58
指数は展開しなくてもいいんじゃ… >>253を使えば"-1.2345e+06"になるし

270 :名無しさん@お腹いっぱい。:2011/08/03(水) 18:09:09.98
よし、俺が仕様を決めてやるよ

入力:10進数、正負あり、小数可、指数表記可
出力:10進数、入力と数値的に等しい最短の文字列、指数表記可


271 :名無しさん@お腹いっぱい。:2011/08/03(水) 18:22:33.47
>>232はどこに行ったんだ。

272 :名無しさん@お腹いっぱい。:2011/08/03(水) 18:28:23.89
233で満足したんだろう

273 :名無しさん@お腹いっぱい。:2011/08/03(水) 18:37:10.44
ならそう書いてほしいな。

274 :名無しさん@お腹いっぱい。:2011/08/03(水) 18:41:36.30
>>233見て、それでも別解出し続けたバカ共の事なんか気にしなくていいだろ。

275 :名無しさん@お腹いっぱい。:2011/08/03(水) 18:52:59.80
バカはともかく、お題を楽しんでるだけなんだから、質問者放置でよし
質問やり逃げなんていつものこと

276 :名無しさん@お腹いっぱい。:2011/08/03(水) 19:07:03.53
実は別解出し続けた回答者のひとりが >>232 と同一人物。
>>232 は初心者を装ったネタ振り。

277 :名無しさん@お腹いっぱい。:2011/08/03(水) 19:22:17.13
というか、>>232=>>233だろう。ドヤ顔で>>233を書き込んで盛大に釣り上げた訳だ。やり手だね。

278 :名無しさん@お腹いっぱい。:2011/08/03(水) 19:25:14.65
それは、下手したら233一発で収束してしまう諸刃の剣

279 :名無しさん@お腹いっぱい。:2011/08/03(水) 22:32:05.53
ファイルに改行コードがあるかどうか判定し、なければ10バイト目に
改行コードを入れるbashを教えてください。。。。

280 :名無しさん@お腹いっぱい。:2011/08/03(水) 22:43:40.70
>>279
/bin/bash

281 :名無しさん@お腹いっぱい。:2011/08/04(木) 00:21:46.47
↓のようなテキスト(sample.txt)があり
aaa 1
xxx 2
bbb 3
aaa 4
aaa 5
xxx 6
bbb 7
xxx 8
aaa 9
「xxx」以降、最初に出現した「aaa」の後に続く数字を出力しようと思っています。
上記テキストの場合、期待する結果は4と9です。
そこで以下のようなスクリプトを作りました。
#! /bin/sh
cat sample.txt |
awk '/xxx/{
while ( getline > 0 ){
if ($0 ~ /aaa/) {
print $2;
break;
}
}
}'
期待した動作はするのですが、「xxx」を見つけたら→その後一行ずつ探す、という実装で
ちょっと力技すぎるかな?と思ってます。
xxxを検索条件としている所と、if文中でaaaと比較する所とで、方法がマチマチなので
これってどうなのだろうか、と。
かといって全てwhileループ内に入れて、まずxxxだったら…というのもイマイチかと…

よりうまい書き方とかありましたら、教えてください。

282 :名無しさん@お腹いっぱい。:2011/08/04(木) 00:27:02.64
>>279
エスパー解釈すると、ファイルに一切改行がない場合のみ、
1行10文字で改行を入れる、ということでいいかな。


case `wc -l < file` in
0) fold -10 file;;
*) cat file;;
esac

283 :名無しさん@お腹いっぱい。:2011/08/04(木) 00:31:55.31
迷わずperl
perl -n -e 'if ((/^xxx/ .. /^aaa/) && /^aaa\s+(\d+)/) { print "$1\n"}' < sample.txt

284 :名無しさん@お腹いっぱい。:2011/08/04(木) 00:41:54.94
>>281
いくつか思いついたけど、できるだけそれを尊重してフラグを使う方法にしてみた。
cat sample.txt | awk 'z&&/aaa/{z=0;print$2};/xxx/{z=1}'

sedでも書けそう。perlならもっと短く書けるかな?

285 :名無しさん@お腹いっぱい。:2011/08/04(木) 00:48:02.52
>>283
perlで書くとこうなるのか。ちょっと意外。
それ見てawkも範囲指定できること思い出した。
awk '/xxx/,/aaa/{if(/aaa/)print$2}' sample.txt
これ以上簡単に書ける方法は思いつかんかった。

286 :名無しさん@お腹いっぱい。:2011/08/04(木) 00:53:18.58
再々修正。同じ正規表現を使うのは非効率なので結果を再利用。
awk '/xxx/,a=/aaa/{if(a)print$2}' sample.txt

287 :名無しさん@お腹いっぱい。:2011/08/04(木) 01:04:20.50
じゃ、sedで

sed -n '/^xxx/,/^aaa/{s/^aaa \([0-9]\+\)/\1/p}' < sample.txt

範囲指定のregexpを{}内から参照ってできないんだっけか

288 :名無しさん@お腹いっぱい。:2011/08/04(木) 12:01:18.20
>>283-287
皆さん情報ありがとうございました

いろいろ新しい発見をしました
いただいた情報をもとに、修正の方針など検討します

289 :名無しさん@お腹いっぱい。:2011/08/04(木) 16:42:26.40
>>267
awkの定石

290 :名無しさん@お腹いっぱい。:2011/08/04(木) 17:19:33.47
>>289
awkやってるといつも思うんだが単項+演算子じゃダメなん?

291 :名無しさん@お腹いっぱい。:2011/08/04(木) 17:35:14.32
+ 0 (as number)は . "" (as string)と対称構造を持つ定石。

292 :名無しさん@お腹いっぱい。:2011/08/04(木) 17:37:39.05
奥が深いですね!

293 :名無しさん@お腹いっぱい。:2011/08/04(木) 18:10:14.75
>>291
ありがとう。そういうことか。演算子の優先順位が違うから専用の演算子でも欲しいところだ。

294 :名無しさん@お腹いっぱい。:2011/08/04(木) 21:08:43.16
>>219の質問に似ているのですが
先頭文字がABCDEで始まるレコードの10バイト目にある文字だけを置換させたいのですが
どのように書けばいいのでしょうか。


295 :名無しさん@お腹いっぱい。:2011/08/04(木) 21:18:07.50
直ぐ下のレスのawkスクリプトのNR==1を/^ABCDE/にすればいいと思うの。

296 :名無しさん@お腹いっぱい。:2011/08/04(木) 21:18:38.31
>>294
>>221 の sedの 1s の部分を /^ABCDE/s に置き換えるだけ。

297 :名無しさん@お腹いっぱい。:2011/08/04(木) 21:27:15.40
>>294
せっかくbashならbashの機能使おうや。

while IFS= read -r; do
case $REPLY in ABCDE*) echo "${REPLY:0:9}X${REPLY:11}";;
*) echo "$REPLY";; esac; done

298 :名無しさん@お腹いっぱい。:2011/08/04(木) 21:31:01.38
bashのくせに#!/bin/shとか書いてあるんだからそんな特殊機能なんか使うなよ

299 :名無しさん@お腹いっぱい。:2011/08/04(木) 21:35:26.56
>>298
特殊機能?

kshでもzshでも使える(>>297 がそのまま動く)汎用機能だが?

300 :名無しさん@お腹いっぱい。:2011/08/05(金) 10:10:22.29
read で変数を指定しなかったときに $REPLY に入れるとか、
${var:m:n} で変数から文字を切り出すってのは
ksh 系の機能で sh にはない機能だよね。
少なくとも、/bin/sh が dash や ash である OS では動かない。


301 :名無しさん@お腹いっぱい。:2011/08/05(金) 10:52:47.50
>>300
> read で変数を指定しなかったときに $REPLY に入れるとか、

なんでこんな馬鹿な仕様を新設したんだろうな。

302 :名無しさん@お腹いっぱい。:2011/08/05(金) 21:37:43.68
リハ用のシェルのソースで、
ふざけ心で変数無指定時にはREPLYに入れるようにしておいたら、
誤って本番のソースとして流れてしまったんです。

303 :名無しさん@お腹いっぱい。:2011/08/05(金) 22:26:41.64
そのつもりならコミットせんだろ

304 :名無しさん@お腹いっぱい。:2011/08/05(金) 22:34:37.22
誤ってコミットしてしまい、23秒間Ctrl-Cを押し続けたんですけど取り消せませんでした

305 :名無しさん@お腹いっぱい。:2011/08/05(金) 23:14:59.41
つまんね。

306 :名無しさん@お腹いっぱい。:2011/08/11(木) 10:25:22.54
rsync で相互同期(src と dst で共に更新がありえて、新しい方を採用)する場合って、
rsync -u src dst
rsync -u dst src
すればできますが、時間がかかります。
一発でやる方法ありますか?
また、rsync じゃなくてコレならそれを一発でできるよみたいのありますか?

307 :名無しさん@お腹いっぱい。:2011/08/11(木) 11:05:23.86
http://www.cis.upenn.edu/~bcpierce/unison/ とか


308 :名無しさん@お腹いっぱい。:2011/08/11(木) 21:55:08.20
shまたは、bashで、
コマンドをタイムアウトさせる関数timeoutを作りたい。
timeout [タイムアウト秒数] [コマンド]

で、
指定[タイムアウト秒数]以内に[コマンド]が終了した場合は、
その[コマンド]の終了コードを、
[タイムアウト秒数]に引っかかった場合は、timeout関数の終了コードを返す。

そんな関数って書けますか?


309 :名無しさん@お腹いっぱい。:2011/08/11(木) 21:56:35.05
追記、
もちろん[タイムアウト秒数]に引っかかった場合は、
[コマンド]を強制終了させます。

310 :名無しさん@お腹いっぱい。:2011/08/11(木) 22:05:42.93
すみません、出来ました・・・

311 :名無しさん@お腹いっぱい。:2011/08/11(木) 23:46:06.76
どうやって?

312 :名無しさん@お腹いっぱい。:2011/08/12(金) 04:05:08.93
>>307 ビンゴです。アリガトン!

313 :名無しさん@お腹いっぱい。:2011/08/12(金) 09:08:38.64
unison昔試したときイマイチ挙動が安定しなかったんだよな
更新かけたファイルがたまに消えたり。
今は良くなったかな?

314 :名無しさん@お腹いっぱい。:2011/08/12(金) 10:56:57.06
>>311
こんな感じでやりましタ。行数の問題で見にくいですが。

timeout() {
TIMEOUT=$1
shift 1
"$@" &
PID=$!
PASSED_SEC=0
while [ ${PASSED_SEC} -lt ${TIMEOUT} -a `ps -p ${PID} | grep -cv PID` -ne 0 ]
do
PASSED_SEC=`expr ${PASSED_SEC} + 1`
sleep 1
done
if [ `ps -p ${PID} | grep -cv PID` -ne 0 ]; then
kill -KILL ${PID}
wait ${PID}
echo "$@: killed, for timeout(${TIMEOUT}sec) exceeded." >&2
return 1
fi
wait ${PID}
return $?
}

315 :名無しさん@お腹いっぱい。:2011/08/12(金) 21:18:57.02
>>314
別にcoreutilsに入っているtimeoutコマンドをエミュレートしたかった訳じゃないのね。

316 :名無しさん@お腹いっぱい。:2011/08/12(金) 22:08:40.27
denコマンド作ったよ

$ den
-- 東京電力 -------------------------
2011/8/12 21:55 UPDATE
PEAK供給力: 5480 万kW
21:55: 3771 万kW (68%)
-- 東北電力 -------------------------
2011/8/12 22:02 UPDATE
PEAK供給力: 1228 万kW
22:00: 884 万kW (71%)
-- 関西電力 -------------------------
2011/8/12 21:55 UPDATE
PEAK供給力: 2850 万kW
21:45: 2081 万kW (73%)


317 :名無しさん@お腹いっぱい。:2011/08/12(金) 22:48:06.16
den co

318 :名無しさん@お腹いっぱい。:2011/08/12(金) 23:55:37.23
man co

319 :名無しさん@お腹いっぱい。:2011/08/13(土) 12:55:03.94
ping co

320 :名無しさん@お腹いっぱい。:2011/08/14(日) 14:20:20.46
tin sh

321 :名無しさん@お腹いっぱい。:2011/08/15(月) 12:57:15.16
dmesgの先頭の
[ 0000.000] を削除したいんですが
どうすればできますか


322 :名無しさん@お腹いっぱい。:2011/08/15(月) 13:08:25.41
sed 's/^\[ 0000\.000\]//'

323 :321:2011/08/15(月) 13:51:10.11
>322
ありがとうございます。
ただ
全部の行の[ 4.01234] などをずべて消したいです


324 :名無しさん@お腹いっぱい。:2011/08/15(月) 13:58:58.03
>>321

dmesg | sed 's/[^ ]* //'

325 :名無しさん@お腹いっぱい。:2011/08/15(月) 13:59:39.32
条件後出しかよ。

326 :名無しさん@お腹いっぱい。:2011/08/15(月) 14:06:11.38
>>325
条件後出しじゃなくて、
>>322 は最近のLinuxのdmesgを良く知らずに回答してると思われる。

>>324 が正解のひとつ

327 :名無しさん@お腹いっぱい。:2011/08/15(月) 14:29:49.97
>>324 は不正解だろ。
こっち正解

dmesg | sed 's/[^]]*[]] //'

328 :名無しさん@お腹いっぱい。:2011/08/15(月) 14:34:10.87
dmesg | sed 's/.*\] //'


329 :名無しさん@お腹いっぱい。:2011/08/15(月) 14:40:28.88
>>328
不正解。
それだと dmesg中の [8086:0040] type 0 class みたいな行の [8086:0040] の部分まで
消えてしまう。

330 :321:2011/08/15(月) 15:03:57.65
みなさん
ありがとう、ございます。


331 :名無しさん@お腹いっぱい。:2011/08/15(月) 16:41:52.68
もう遅いけど、とりあえず

dmesg | cut -d']' -f2-


332 :名無しさん@お腹いっぱい。:2011/08/16(火) 19:06:44.80
bashでファイルの先頭が’A’で始まるレコードの10バイト目から12バイト目までが
’空白’(スペースが3個)であれば、その空白を’XXX'に変換したいのですが
うまくいきません、良い書き方教えてくださ

333 :名無しさん@お腹いっぱい。:2011/08/16(火) 19:07:28.10
bashでファイルの先頭が’A’で始まるレコードの10バイト目から12バイト目までが
’空白’(スペースが3個)であれば、その空白を’XXX'に変換したいのですが
うまくいきません、良い書き方教えてくださ

334 :名無しさん@お腹いっぱい。:2011/08/16(火) 20:50:11.25
>>333
sed -e '1s/\(A.\{8\}\) /\1XXX/'

335 :名無しさん@お腹いっぱい。:2011/08/16(火) 20:58:42.93
しまった。2chに書くと空白3つが一つに変換されてしまうのね。
sed -re '1s/(A.{8}) {3}/\1XXX/'

336 :名無しさん@お腹いっぱい。:2011/08/16(火) 21:37:58.18
&nbsp;ではなく{3}使ってくるとかワラタw

337 :名無しさん@お腹いっぱい。:2011/08/16(火) 22:35:00.01
>>335
初心者のためあまりよく分からないのですが、
10バイト目から12バイト目が’空白’の条件は
どうやっているのでしょうか。。。
>>336
あと を使う書き方は{3}を に変えるだけで
よいのでしょうか。

338 :名無しさん@お腹いっぱい。:2011/08/16(火) 22:54:31.69
>>337
ああ、確かに>>334,>>335は間違いだった。スマン。
正しくは
sed -re '1s/^(A.{8}) {3}/\1XXX/'
だな。

これは
「一行目の先頭の文字がAであり、その後に任意の文字が8文字続き、そのあとに空白が3文字続いたなら
その部分を()でマッチした部分+XXXに置き換える」
という意味。
もっと詳しいことが知りたかったらsedとか正規表現でググると良いぞ。


339 :名無しさん@お腹いっぱい。:2011/08/17(水) 01:42:01.56
面倒くせえな

340 :名無しさん@お腹いっぱい。:2011/08/19(金) 14:52:03.70
対した事の無い処理をわざわざ複雑に書くのはただの馬鹿。
perl一つで解決する物をsed使ったりして頑張っちゃうとか

341 :名無しさん@お腹いっぱい。:2011/08/19(金) 15:22:53.37
sed一つで済むのにわざわざperlを使っちゃうのも如何なものだと思うけど。

342 :名無しさん@お腹いっぱい。:2011/08/19(金) 15:43:28.04
わざわざっつーか、汎用テキスト処理スクリプトであるPerlを使っちゃうと
スクリプトの意味が解りにくくなるんよね。
sedだったら、まず最も多い用途は置換だから、置換かな?と思って読むことが出来る。
もちろん、複雑なテキスト処理に使うのは大賛成だけどね。

343 :名無しさん@お腹いっぱい。:2011/08/19(金) 16:01:18.18
大半のテキスト処理はsedとawkがあればできちゃうからなあ。
Perlじゃないとできないことは滅多にないし
Perl書くぐらいならRubyかPythonで書いちゃう。

344 :名無しさん@お腹いっぱい。:2011/08/19(金) 16:07:50.83
まあ、重たい処理ならPerlオンリーでも良いんじゃね?
シェルスクリプトだとどうしても処理長くなっちゃうし。
ただまあ、ここはシェルスクリプトのスレなんだよな。

345 :名無しさん@お腹いっぱい。:2011/08/19(金) 18:50:17.85
まあおいらが言いたかったのは列抜き出すだけで単純にawkで済むものをsed使って正規表現の置換で無理やり見たいのをこのスレでよく見るからさ
本人はスキルを自慢しているつもりなんだろうけど、見辛いだけなんだよね
可視性も考慮しろと言いたい

346 :名無しさん@お腹いっぱい。:2011/08/19(金) 18:54:44.18
まあ、いいんじゃないの?
ここは初学者用の教科書じゃないんだから。
自治厨より役に立つ。

347 :名無しさん@お腹いっぱい。:2011/08/19(金) 18:59:05.65
と言うか個人的な好みも有るかもしれないが、sedは見た目がきたない
正規表現で置換をやるなら何故perlを使わないのか理解に苦しむ
まあスレチですが…

348 :名無しさん@お腹いっぱい。:2011/08/19(金) 19:04:48.19
そもそも正規表現自体が汚いんだからperl使おうがsed使おうが一緒だろ
まあスレチですが…

349 :名無しさん@お腹いっぱい。:2011/08/19(金) 19:51:31.19
>>345
全く逆

単純にsedで済むものは必ずsedで書くこと。
sedで書けない処理の場合のみawkで書く。
sedで書けるのにわざわざawk使うのはバカ。

sedもawkも使わずにシェルだけで書けるものはシェル(内部コマンド)で書く。


(おまけ) perlで書くのは無条件で馬鹿。

350 :名無しさん@お腹いっぱい。:2011/08/19(金) 21:44:24.56
perlって、awkの機能もsedの機能もgrepの機能も持ってるじゃん
awk、sed、grep使ってる程度のシェルスクリプトって、perlで書こうと思えば書けちゃうじゃん
だから全部perlで書くなら、別にいいと思うんだよ

でも、シェルスクリプト中で、awkやsed、grepでできる処理をperlで書くっていうのは、
それはなんかイケてないって気がするんだよな

逆に、perlでなきゃ無理な処理をシェルスクリプトに混ぜ込むってのも、perlを必要とするなら
全部perlで書いちゃえyo、とも思うんだよな

なんというか、シェルもperlも、スクリプト動かせる土台じゃん、と
まぁawkも結構いろいろできるけど、それはそれとして、さ

351 :名無しさん@お腹いっぱい。:2011/08/19(金) 21:59:37.16
sedはawkより遅いってイメージがあるw

352 :名無しさん@お腹いっぱい。:2011/08/19(金) 22:10:23.08
イメージで語るなよ。

353 :名無しさん@お腹いっぱい。:2011/08/19(金) 22:11:59.95
sedで充分なのはsedで、不十分なのはperlで、pythonはワンライナー書けないから却下。
awkの出番はほぼ無い。唯一「n番目のフィールドを取り出す」これだけがawkを使う場面。

354 :名無しさん@お腹いっぱい。:2011/08/19(金) 23:44:48.77
>>353
そんだけならcutでいいでしょ。

だから、不十分なのはperlでって、本当に不十分なんすかね?という話になる。

355 :名無しさん@お腹いっぱい。:2011/08/19(金) 23:53:21.61
>>354
cutは文字列をセパレータに出来ないじゃん。使い分けるの面倒だからその用途にはawkで良い。

356 :名無しさん@お腹いっぱい。:2011/08/20(土) 00:18:53.90
>>354
cutでawkと全く同じようにフィールド切り出せるの?

357 :名無しさん@お腹いっぱい。:2011/08/20(土) 17:20:50.24
linux環境上で120MBぐらいのファイルの文字コード変換を
iconvコマンドで別ファイル書き出すbashを作成していたのですが、
エラーが出てしまいました。エラー内容がうろ覚えなのですが、
(たしか容量的な問題のエラー)
容量の問題かと思い調べたのですが、2GBまでは大丈夫そうなのですが
何か他に問題てありますか。。。

358 :名無しさん@お腹いっぱい。:2011/08/20(土) 19:09:59.84
bashというのは名前からしてシェルですか?
でも、すでにbashという名のシェルは存在するので、別の名前にした方が良いですよ。

359 :名無しさん@お腹いっぱい。:2011/08/20(土) 19:41:06.50
>>357
iconv に -c オプションを付けろ。
-c がないとiconvで変換できない文字コードに出会った時に異常終了する。


>>358
エスパー失格の上に返しがつまんね

360 :名無しさん@お腹いっぱい。:2011/08/20(土) 19:54:25.02
>>359
エスパーさんは隔離スレから出てこないでください。隔離スレに回答待ってる質問者がいますよ。

361 :359:2011/08/20(土) 20:48:13.07
>>360
俺はそっちのスレの住人じゃないよ。
他板でも、エスパー回答はごく当たり前の風潮。

362 :名無しさん@お腹いっぱい。:2011/08/20(土) 21:33:09.90
>360 わかります がんばって! ^^

363 :名無しさん@お腹いっぱい。:2011/08/20(土) 23:39:01.28
流子さんのbash、智花のbash。

364 :名無しさん@お腹いっぱい。:2011/08/21(日) 08:38:40.08
現在のディレクトリ以下のディレクトリ、ファイルから再帰的に
目的の文字列を検索て、フルパスを一覧表示したいです。
どうすればよいですか


365 :名無しさん@お腹いっぱい。:2011/08/21(日) 08:45:48.09
それはシェルスクリプトでやるべきではありません。とても遅くなるからです。

366 :名無しさん@お腹いっぱい。:2011/08/21(日) 09:50:41.06
find . | xargs grep "AAA"
では




367 :名無しさん@お腹いっぱい。:2011/08/21(日) 10:04:41.51
GNU grepなら-rオプションがあるよ〜

368 :364:2011/08/21(日) 10:28:39.99
まったく、違う方法を考えてました
ありがとう


369 :名無しさん@お腹いっぱい。:2011/08/21(日) 10:41:00.74
>>366
それ、今時のスペース入りファイル名で誤動作するから禁止。
「xargsは使うな」っていうテンプレ、前スレまであったのになくなったな。

370 :名無しさん@お腹いっぱい。:2011/08/21(日) 10:44:31.30
$ find . -print0 | xargs -0 AAA
でいいっしょ。

371 :名無しさん@お腹いっぱい。:2011/08/21(日) 10:50:24.40
>>370
それはGNU限定になるから没。(しかもgrep忘れてるしw)

find . -exec grep AAA {} +
が正解。
(最後 + がポイント)

372 :名無しさん@お腹いっぱい。:2011/08/21(日) 10:53:09.46
>>371
最後の+は古いバージョンのfindじゃ使えないんじゃないの?

373 :名無しさん@お腹いっぱい。:2011/08/21(日) 10:57:18.19
>>371
の方法に別に異論はないけどFreeBSDのfind/xargsにも -print0/-0はあるみたい。

374 :名無しさん@お腹いっぱい。:2011/08/21(日) 11:59:28.74
+が使えるなら-print0も使えるってオチとか無いの?w

375 :名無しさん@お腹いっぱい。:2011/08/21(日) 12:03:11.21
むしろgrep -r -nで|sedで削って| uniqとかでまとめちゃうとかw

376 :名無しさん@お腹いっぱい。:2011/08/21(日) 12:06:04.28
>>375
何をしたいのかよく分からないけどgrep -r -lとは違うの?

377 :名無しさん@お腹いっぱい。:2011/08/21(日) 12:20:24.86
>>374
Solarisでは +は使えるが -print0は使えない

378 :名無しさん@お腹いっぱい。:2011/08/21(日) 12:25:52.43
+はposix -print0/-0は非標準。

379 :名無しさん@お腹いっぱい。:2011/08/21(日) 12:45:56.74
xargsを使っちゃいけないってことはhogeにファイル名の一覧があるとして
$ tr '\n' '\0' < hoge | xargs -0 grep AAA
みたいなことをしたい場合はどうすればいいの?

380 :名無しさん@お腹いっぱい。:2011/08/21(日) 13:47:08.25
>>379

IFS='
'
grep AAA `cat hoge`

381 :名無しさん@お腹いっぱい。:2011/08/21(日) 13:48:05.92
>>369
昔は誤動作しなかったの?

382 :名無しさん@お腹いっぱい。:2011/08/21(日) 13:53:56.90
-0もできないような古いOSなんか使ってるんじゃねぇってことじゃね?

383 :名無しさん@お腹いっぱい。:2011/08/21(日) 14:16:06.89
find ./ -type f -exec grep AAA {} /dev/null \;
てのがよくある方法だと思ったが

384 :名無しさん@お腹いっぱい。:2011/08/21(日) 14:22:00.06
>>381
昔はファイル名にスペースなんか入れないことが暗黙の了解だった。
CUIのみの操作だから、スペース入りファイル名は作りにくいし作らない。
だから、-0なしのxargsが普通に使われていた。

385 :名無しさん@お腹いっぱい。:2011/08/21(日) 14:30:57.34
>>380
それ、スペースはOKだけど、* ? [ab] とかのワイルドカードが展開される。

set -f 追加しろ。

386 :名無しさん@お腹いっぱい。:2011/08/21(日) 17:29:00.39
なぜファイル名にスペース禁止にしなかったのかほんとに意味が分からない

387 :名無しさん@お腹いっぱい。:2011/08/21(日) 17:53:00.44
「Filenames in Shell」
http://www.dwheeler.com/essays/filenames-in-shell.html
これ参考になりそうだけど全部英語なのでキツい。誰か翻訳しませんか。

388 :名無しさん@お腹いっぱい。:2011/08/21(日) 18:59:58.18
>>387
ありがとう。参考になったよ。この程度の英語ならそのまま読める。
"mojibake"だけ日本語だった。これって英語圏でも通じる言葉になったのかw

389 :名無しさん@お腹いっぱい。:2011/08/21(日) 19:06:56.58
シェルスクリプトを勉強する前に、Perlを勉強することにしましたw

390 :名無しさん@お腹いっぱい。:2011/08/21(日) 19:16:17.14
>>387 のページより、

IFS="$(printf '?n?t')"
# CORRECT if filenames can't include tab/newline *and* if IFS omits space:
COMMAND $(find .)

↑ 駄目だよ。
>>385 が言うように set -f しないと、
findしたファイル名に素の * とかが含まれていると、それが再度展開される。

391 :名無しさん@お腹いっぱい。:2011/08/21(日) 19:30:00.12
emojiも英語みたいだぞ?

392 :名無しさん@お腹いっぱい。:2011/08/21(日) 23:25:52.93
>>371
最後 + だと grep に渡されるファイル名が1つだけの場合が起こり得る。
>>383 はそれを回避できるが、まぁ効率は悪いな。
「フルパスを一覧表示」だから、素直に -l オプションつければいいんじゃないか?

find ${PWD}/ -type f -exec grep -l 'AAA' /dev/null {} +

/dev/null は "-e" のような名前のファイルがあっても動くように入れてみた。

393 :名無しさん@お腹いっぱい。:2011/08/22(月) 06:52:56.26
>>392
grep に渡されるファイル名が1つだけの場合は起こりえない。
>>371 では、あえて -type f を付けていない。
だから、カレントディレクトリの . が必ず渡されるため、
それと通常ファイルを含めて2個以上の引数がgrepに渡る。

394 :名無しさん@お腹いっぱい。:2011/08/22(月) 12:03:29.03
CentOS 6でやってみた
以下連投すmanko

$ find .
.
./oppai oppai
./oppai oppai/oppai text.txt
./unko
./unko/text.txt
./manko
./manko/text.txt
$ cat ./oppai\ oppai/oppai\ text.txt
AAA
$ cat unko/text.txt
shit
$ cat manko/text.txt
pussy

395 :名無しさん@お腹いっぱい。:2011/08/22(月) 12:03:59.75
>>366
$ find . | xargs grep "AAA"
grep: ./oppai: そのようなファイルやディレクトリはありません
grep: oppai: そのようなファイルやディレクトリはありません
grep: ./oppai: そのようなファイルやディレクトリはありません
grep: oppai/oppai: そのようなファイルやディレクトリはありません
grep: text.txt: そのようなファイルやディレクトリはありません

>>370
$ find . -print0 | xargs -0 grep AAA
./oppai oppai/oppai text.txt:AAA

>>371
$ find . -exec grep AAA {} +
./oppai oppai/oppai text.txt:AAA

>>383
$ find ./ -type f -exec grep AAA {} /dev/null \;
./oppai oppai/oppai text.txt:AAA

>>392
$ find ${PWD}/ -type f -exec grep -l 'AAA' /dev/null {} +
/tmp/oppai oppai/oppai text.txt

396 :名無しさん@お腹いっぱい。:2011/08/22(月) 12:06:50.88
AAAじゃなくxだったらどうなる?

397 :名無しさん@お腹いっぱい。:2011/08/22(月) 12:13:17.20
>>396
$ find . | xargs grep "x"
grep: ./oppai: そのようなファイルやディレクトリはありません
grep: oppai: そのようなファイルやディレクトリはありません
grep: ./oppai: そのようなファイルやディレクトリはありません
grep: oppai/oppai: そのようなファイルやディレクトリはありません
grep: text.txt: そのようなファイルやディレクトリはありません
$ find . -print0 | xargs -0 grep x
$ find . -exec grep x {} +
$ find ./ -type f -exec grep x {} /dev/null \;
$ find ${PWD}/ -type f -exec grep -l 'x' /dev/null {} +

398 :名無しさん@お腹いっぱい。:2011/08/22(月) 12:22:54.38
Binary file なんちゃらって出るのはBSD限定?
NFSだと別の表示になるかもしれんが。

399 :名無しさん@お腹いっぱい。:2011/08/22(月) 12:56:08.85
ufsだとディレクトリが読めちゃうよね。
NFSだと読めないし、ext[234]でもディレクトリは読めない。
他のファイルシステムはどうだろう?

あと、検索対象のファイルがバイナリファイルだった場合、
古いgrepだとBinary ...のエラーで門前払いされて
中身を検索してくれないことがある。GNU grepだとバイナリでもOK。

400 :名無しさん@お腹いっぱい。:2011/08/23(火) 12:41:14.11
zfsでも$ cat .
とかできちゃうな。
この辺の挙動の違いってファイルシステムじゃなくて
FreeBSDとLinuxのシステムコールの実装の違いだと思ってたんだけど違うのかな。

401 :名無しさん@お腹いっぱい。:2011/08/24(水) 14:28:13.26
>>393
最初に実行される grep についてはそうなんだが、ファイルがたくさんあって、
渡される引数が ARG_MAX を超えたときに別のプロセスとして実行される
grep でも起こり得ないんだろうか。まぁ、めったにはおこらないと思うが…

そもそもこれを想定しないで良いなら grep AAA `find ./` でいいわけだし。


402 :名無しさん@お腹いっぱい。:2011/08/24(水) 14:35:51.85
>>401
>grep AAA `find ./` でいいわけだし。

↑ それ、スペース入りファイル名で誤動作。で、話がループ。

403 :名無しさん@お腹いっぱい。:2011/08/24(水) 15:33:23.64
みんな GNU grep 入れようぜ。

404 :名無しさん@お腹いっぱい。:2011/08/24(水) 17:17:40.10
>>402
grep AAA "`find ./`" でいいわけだし。

405 :名無しさん@お腹いっぱい。:2011/08/24(水) 19:12:50.20
grep pattern filename* /dev/null
は定石かと。

406 :名無しさん@お腹いっぱい。:2011/08/24(水) 19:13:41.72
xargs的には、grep pattern /dev/null filename* がいいのかな。

407 :名無しさん@お腹いっぱい。:2011/08/24(水) 19:28:14.75
>>405
それ、過去のバッドノウハウな。

今は -H オプションがあるから grep -H hoge file*

408 :名無しさん@お腹いっぱい。:2011/08/24(水) 19:49:37.05
-Hは0個に対応できないでしょ。file+にしか。

409 :名無しさん@お腹いっぱい。:2011/08/24(水) 20:04:50.08
>>408
0個の場合は findから呼び出されないから無問題。

410 :名無しさん@お腹いっぱい。:2011/08/24(水) 20:06:25.45
そんなこと全く気にしたことが無かったのだが、その/dev/nullは、運悪く渡されるファイルがなかったときに、
標準入力を読みに行ってシェルスクリプトが固まるのを防ぐためのもの…なのか?

411 :名無しさん@お腹いっぱい。:2011/08/24(水) 20:17:16.93
>>408
コマンドライン直接の話だとしても、

ファイルが0個の場合は file* って文字列自体が grepの引数になってエラーになるだけ
だから、stdinを読んでしまうことはない。
file* の文字列自体が渡ってしまうことは /dev/nullを付けても解決しない。

412 :名無しさん@お腹いっぱい。:2011/08/24(水) 22:51:09.55
file*は正規表現のつもりなんじゃないの? +とか書いてるし。

413 :名無しさん@お腹いっぱい。:2011/08/24(水) 22:58:28.01
>>412
発端は >>405

どう見てもワイルドカードです。

414 :名無しさん@お腹いっぱい。:2011/08/24(水) 23:38:26.66
質問です。

以下のようなスクリプトがあります。
-------------------------
$ cat ./hoge.sh
#!/bin/sh -x
find . -type f | wc -l
-------------------------

このスクリプトを実行すると、通常以下のように出力されます。
-------------------------
$ ./hoge.sh
+ find . -type f
+ wc -l
1
-------------------------

しかし、時々以下のように変な出力がされることがあります。なぜでしょうか?
そして、回避策はありますか?
-------------------------
$ ./hoge.sh
+ find+ wc /home/mao/tmp/110824 -l -type
f
1
-------------------------


415 :>>414:2011/08/24(水) 23:39:55.88
すいません、最後のサンプルだけ訂正させてください
-------------------------
$ ./hoge.sh
+ find+ wc . -l -type
f
1
-------------------------



416 :>>414:2011/08/24(水) 23:41:34.43
私が思うに、パイプの左と右が一緒に実行されるのでは?と疑っています。


417 :名無しさん@お腹いっぱい。:2011/08/24(水) 23:57:54.89
>>414
質問とは直接関係ないけど、
それ、改行入りファイル名で誤動作するから使用禁止。

418 :名無しさん@お腹いっぱい。:2011/08/25(木) 00:09:59.39
>>416
パイプの左と右が同時に実行される、で正解だよ。それで仕様。
嫌な場合はBIOSでCPUを1コア以外止める。

419 :名無しさん@お腹いっぱい。:2011/08/25(木) 00:11:07.08
>>418
いやいや、1コアでも無理でしょ

420 :名無しさん@お腹いっぱい。:2011/08/25(木) 08:26:15.19
>>419
いいや、1コアなら大丈夫。
ヒント:プリミティブ

421 :名無しさん@お腹いっぱい。:2011/08/25(木) 08:51:25.98
1単語出すごとにflushしてるのに?

422 :名無しさん@お腹いっぱい。:2011/08/25(木) 09:12:50.11
Windows7 UltimateにあるUnix互換モードって普通のunixみたいに使えるものなの?bashとかもあるらしいのだけど

423 :名無しさん@お腹いっぱい。:2011/08/25(木) 09:15:14.31
>>421
flushは行ごと。(確認済み)

424 :名無しさん@お腹いっぱい。:2011/08/25(木) 09:21:01.39
シェルの実装依存だろ
set -x のデバッグメッセージについては、

ksh zsh bash: 行ごとflush
ash: 単語ごとflushw

425 :名無しさん@お腹いっぱい。:2011/08/25(木) 09:23:19.55
行ごとflushならマルチコアでも>>414の問題置きなくね?

426 :名無しさん@お腹いっぱい。:2011/08/25(木) 09:28:30.56
>>424
jshも単語ごとだね
v7shは明示的にはflushしてなさそうだけど、単語ごとwrite

427 :名無しさん@お腹いっぱい。:2011/08/25(木) 09:47:13.83
同様に、単語ごとflushでもシングルコアなら >>415 の現象は起きにくい。

428 :名無しさん@お腹いっぱい。:2011/08/25(木) 10:13:07.83
>>427
アホは書きこむな。

429 :名無しさん@お腹いっぱい。:2011/08/25(木) 10:18:09.31
で、ありがたいヒントくださった>>420どこいった?

430 :名無しさん@お腹いっぱい。:2011/08/25(木) 10:41:34.33
>>424がFA

431 :名無しさん@お腹いっぱい。:2011/08/25(木) 10:54:50.98
つか、単語ごとにflushする利点ってなんだ?

432 :名無しさん@お腹いっぱい。:2011/08/25(木) 10:57:42.21
>>430
質問者への回答になってない

433 :名無しさん@お腹いっぱい。:2011/08/25(木) 11:42:56.62
>>422
ターミナルの画面がでかくできない
コピーペーストできない

つかえない

434 :名無しさん@お腹いっぱい。:2011/08/26(金) 18:54:06.62
test

435 :名無しさん@お腹いっぱい。:2011/08/27(土) 05:01:57.93
質問です.
set -x による出力が

+ date -d '2011/4/2 6 day' +%Y

のようになっていて,その次の出力行が

date: 余分な演算子 `day\''
詳しくは `date --help' を実行して下さい.

と出力される箇所があるのですが,-xの出力をそのまま端末エミュレータに
コピペしてみると正しく実行されます.
このエラーの原因が分からなくて困っています.
どなたか助けてください.よろしくお願いします.

436 :名無しさん@お腹いっぱい。:2011/08/27(土) 09:37:12.48
>>435
シングルクォートが、通常の文字として解釈されてる。
シングルクォートが余分。
あるいは、もう1回解釈させるために
evalを付けると良い。

再現方法:
$ date -d "'"2011/4/2 6 day"'" +%Y
date: 余分な演算子 `day¥''
詳しくは `date --help' を実行して下さい。

437 :名無しさん@お腹いっぱい。:2011/08/27(土) 09:49:38.05
>>435
エスパー回答するぞ。他の変数にdateの引数入れてるんだろ?

$ hoge="-d '2011/4/2 6 day' +%Y"
$ date $hoge
date: 余分な演算子(ry

$ eval date $hoge
2011


>>436 の言うようにevalで解決。

438 :435:2011/08/27(土) 16:35:27.84
>>436,437
evalで解決できました.ありがとうございました.

ちなみに,>>437さんの言うように,dateの引数を変数に入れて使ってました.

439 :名無しさん@お腹いっぱい。:2011/09/04(日) 08:03:40.42
>>1のお約束について
Ubuntuのデフォルトが"dash"っになってたような気がするんだけども・・・それは書かなくていいのか?

440 :名無しさん@お腹いっぱい。:2011/09/04(日) 08:24:10.51
Ubuntuっつーか、Debian系で使われるのがdash(Debian ash)だな、ashのDebian版
Debian系では対話環境のデフォルトはbash、シェルスクリプトはdashを前提とすることが多い
Ubuntuの/bin/shも確か中身はdashなんだっけ?

ちなみにお約束に追記するとしたら、どの辺にどう追記するよ?

441 :名無しさん@お腹いっぱい。:2011/09/04(日) 15:37:58.36
見てきた
sh -> dash てなってた
知らんかったわ@Ubuntu

442 :名無しさん@お腹いっぱい。:2011/09/04(日) 15:56:28.15
>>440
>>Linuxユーザは/bin/shの正体がbashなので特に注意。
>>FreeBSDユーザは/bin/shの正体がashなので注意。
の下に一緒にいれときゃいいんじゃないかな?
>>441
if [[ "${foo}" =~ "${foo}" ]]; then 〜fi
みたいな式が使えなくてさ・・・「何で?デフォルトのshはbashにリンクされてるんじゃないの?」
って思って調べてみたら・・・

443 :名無しさん@お腹いっぱい。:2011/09/04(日) 16:02:43.65
950あたりでまた言ってくれ。

444 :名無しさん@お腹いっぱい。:2011/09/04(日) 17:11:34.08
AIX6.1環境に旧サーバーからのアプリケーション移行を行ってるんですが
その際不要なファイルが大量にあり、一括表示する方法はないものかと
あれこれ試してみました。

結果として下記のような記述になったのですが…(色々省略してますが)

$ echo "ls -l $1 "`while read line do; echo "grep -v "$line ;done < $2` > 不要ファイル一覧表示.ksh
$ 不要ファイル一覧表示.ksh
$ rm 不要ファイル一覧表示.ksh

$1は検索対象ディレクトリ、$2は必要ファイル一覧です

不要ファイル一覧表示.kshの生成と削除を行わず、いきなり実行は出来ないんでしょうか?

445 :名無しさん@お腹いっぱい。:2011/09/04(日) 17:22:46.04
echo "ls -l $1 "`while read line do; echo "grep -v "$line ;done < $2` | ksh

446 :名無しさん@お腹いっぱい。:2011/09/04(日) 18:37:56.77
>>445
なるほど、ありがとうございます!
あと自分の記述が間違えてた…
$ echo "ls -l $1 "`while read line do; echo "|grep -v "$line ;done < $2` > 不要ファイル一覧表示.ksh
パイプ入れ忘れ〜

447 :名無しさん@お腹いっぱい。:2011/09/04(日) 18:45:15.84
ash復権してるのか


bash笑()

448 :名無しさん@お腹いっぱい。:2011/09/04(日) 18:47:44.05
コマンドAのstdoutをコマンドBのstdinへパイプで入力、コマンドAのstderrをコマンドCのstdinへパイプで入力を
一発でやることはできますか?

449 :名無しさん@お腹いっぱい。:2011/09/04(日) 18:58:27.97
一発じゃ無理だろうな

450 :名無しさん@お腹いっぱい。:2011/09/04(日) 19:04:13.63
>>448

(com_A | com_B) 2>&1 | com_C

451 :名無しさん@お腹いっぱい。:2011/09/04(日) 19:32:23.93
cmd_Bが変なの吐かないように細工した方がいいんじゃね?

452 :名無しさん@お腹いっぱい。:2011/09/04(日) 20:14:15.92
>>446
セミコロンの位置とかいろいろ間違えすぎだろ

$ for f in "$1"/*; do fgrep -q "$f" "$2" || echo "$f"; done | xargs rm
これで仕様合ってんのかね。

# .で始まるファイルもあるとこれではまずいが

453 :名無しさん@お腹いっぱい。:2011/09/04(日) 23:04:02.49
>>442
「Debian系Linux(Ubuntuなど)では/bin/shの正体がdash(Debian版ash)だったりするので注意。」
って感じかな、>>443 の言う通り >>950 辺りでまた言ったほうが良いかもね

454 :名無しさん@お腹いっぱい。:2011/09/05(月) 04:33:29.14
>>442
> if [[ "${foo}" =~ "${foo}" ]]; then 〜fi
> みたいな式が使えなくてさ・・・「何で?デフォルトのshはbashにリンクされてるんじゃないの?」
状況が分からないけど、 bash 特有の機能を使うときは、シェバングを
/bin/bash などに変えたほうが良いと思う。


455 :名無しさん@お腹いっぱい。:2011/09/05(月) 11:02:57.64
[[ は bash 特有の機能じゃなくて ksh 由来だったかと。
それはそうと、/bin/sh が bash な環境しか使ったことない人は
どれが bash 特有の機能なのかなんかぜんぜん知らないし気にしてないというのが実情。


456 :名無しさん@お腹いっぱい。:2011/09/05(月) 11:15:31.47
>>446
grep使うなら"^$line$"した方がいい。
>>452
grep, egrepだと正規表現に使う文字がパス名に含まれると難しい。
しかしfgrepだと部分文字列でマッチしてしまうよ。


457 :名無しさん@お腹いっぱい。:2011/09/05(月) 11:24:55.01
SUS的には[[は予約語で、動作は未定義。
同様のものにfunction selectがある。

SUS定義の展開系では古典shに
~username
$(command)
$((expression))
が加わってる。

http://pubs.opengroup.org/onlinepubs/009695399/
http://pubs.opengroup.org/onlinepubs/009695399/idx/shell.html
をテンプレに加えたいな。

458 :名無しさん@お腹いっぱい。:2011/09/05(月) 12:41:05.07
>>455
一応そういう人を対象(?)にbashの固有の機能を使わないように書くガイドが
debianのマニュアルの中にあった気がする

459 :名無しさん@お腹いっぱい。:2011/09/05(月) 13:13:38.31
まあDebianの場合bash依存を減らすのに一番の方法は
ガイドとか読むよりも、まずdashで書き始めることなんだろうけどな

460 :名無しさん@お腹いっぱい。:2011/09/05(月) 14:00:50.35
Ubuntu のサイトだけど
https://wiki.ubuntu.com/DashAsBinSh

考えたくない人は
$ sudo dpkg-reconfigure dash

/bin/sh を /bin/bash のシンボリックリンクへ

461 :名無しさん@お腹いっぱい。:2011/09/05(月) 14:07:38.29
こっちのが新しいよ
http://pubs.opengroup.org/onlinepubs/9699919799/

462 :名無しさん@お腹いっぱい。:2011/09/05(月) 14:24:44.74
実際、ほとんどのUbuntu(Debian)ユーザーは >>460
/bin/sh -> bash に設定してるよ。
だから、Debian系Linux(Ubuntuなど)では/bin/shの正体がdash」(>>453)
と言うとそれはそれで嘘になる。

463 :名無しさん@お腹いっぱい。:2011/09/05(月) 14:41:01.80
>>462
だから>>453では「だったりする」という書き方にしてるんだよ。

464 :名無しさん@お腹いっぱい。:2011/09/05(月) 15:43:25.11
「になってることもある」で

465 :名無しさん@お腹いっぱい。:2011/09/05(月) 15:54:21.01
ほとんどのユーザがしているってこれからもそうとは限らないのでは?
そもそもdashを採用したのはDebianでは現行のsqueezeからだし。
デフォルトではそうなっているっていう事実は考慮すべき。

466 :名無しさん@お腹いっぱい。:2011/09/05(月) 22:33:21.16
素人の私に教えてください。
シェル内で scriptコマンド使ったら、
そこでexitで抜けるまでシェル止まってしまうんですが、

script
色々処理
exit

ってシェル内でうまく処理する方法ってないの?

467 :名無しさん@お腹いっぱい。:2011/09/05(月) 22:41:10.03
同じではないが、近い方法でなら
exec >foo 2>&1
とかあるが。

468 :名無しさん@お腹いっぱい。:2011/09/06(火) 00:26:39.23
>>466
"&" でscriptコマンドをバックグラウンド実行させればいいのでは?

script &
色々処理
exit

ただしこの場合、scriptコマンドが投げっぱなしになるので、

・scriptコマンドの終了値を取得したい場合
・最終的にscriptコマンドの終了を待ってから呼び出し元のシェルスクリプトを終了したい場合

こういう状況なら少し工夫が必要だと思う

469 :名無しさん@お腹いっぱい。:2011/09/06(火) 00:53:40.00
帰宅途中につきスマホしかないので試してないけど

script script.log << EOF
色々処理
exit
EOF

とできた気がする

470 :名無しさん@お腹いっぱい。:2011/09/06(火) 01:21:53.69
>>462
してないしてないw
シェルスクリプト走らすのにいちいちフットプリントのデカいbashなんか使わん

471 :名無しさん@お腹いっぱい。:2011/09/06(火) 02:43:49.75
>>468
バックグラウンドで実行すべきはいろいろな処理の方だろ。
scriptは対話的に使うものだから。

472 :名無しさん@お腹いっぱい。:2011/09/06(火) 06:43:26.83
>>468 >>469
馬鹿ばっか

473 :名無しさん@お腹いっぱい。:2011/09/06(火) 22:44:34.89
"script" って名前のLinuxコマンドがあるんだね

474 :名無しさん@お腹いっぱい。:2011/09/06(火) 23:09:38.28
The script command appeared in 3.0BSD.

475 :自動再起動:2011/09/07(水) 06:41:54.75
AppleScript スレ
http://hibari.2ch.net/test/read.cgi/mac/1256127156/l50
の586で尋ねたことと同じ動作をシェルスクリプトでできないか質問.

Mac で落ちたアプリ (TeamViewer を想定) を自動的に起動して「隠す」スクリプト.Ruby 可.回答待ってます.


476 :名無しさん@お腹いっぱい。:2011/09/07(水) 07:45:05.72
ここよりもMac板のが詳しいんじゃないかな

Mac OS XをUnixとして使ってる人の為のスレ 16
http://hibari.2ch.net/test/read.cgi/mac/1302132772/

477 :自動再起動:2011/09/07(水) 17:03:35.86
>>476
Thanks! そういうスレがありましたね.でもしばらくはここで募集します.
open -g は使うと思うので,鍵は「このアプリは起動中?」を確かめるコマンドじゃないかと考えてる.




478 :名無しさん@お腹いっぱい。:2011/09/07(水) 17:14:20.10
>>477
>このアプリは起動中?
普通はpgrepなんだけど
$ which pgrep
/opt/local/bin/pgrep
標準じゃなかったorz

479 :名無しさん@お腹いっぱい。:2011/09/07(水) 23:13:26.12
>>477
launchサービスでコントロールしなよ。

480 :名無しさん@お腹いっぱい。:2011/09/08(木) 12:10:12.57
$ EXPR="echo \"scale=2;8 / 10\" | bc"
$ PERCENT=`${EXPR}`
$ echo ${PERCENT}
の結果が
"scale=2;8 / 10" | bc
って出力される

.80
って出力を得たいんだけど、どこ直せば良いか教えてください。


481 :名無しさん@お腹いっぱい。:2011/09/08(木) 12:15:20.20
eval ${EXPR}

482 :名無しさん@お腹いっぱい。:2011/09/08(木) 12:26:00.96
>481
$ EXPR="echo \"scale=2;8 / 10\" | bc"
$ PERCENT=eval ${EXPR}
"scale=2;8 / 10" | bc
$ echo ${PERCENT}
"scale=2;8 / 10" | bc

こうなっちゃいました。
なんか間違ってますか?

483 :名無しさん@お腹いっぱい。:2011/09/08(木) 12:29:48.70
>>482
PERCENT=`eval ${EXPR}`

484 :自動再起動:2011/09/08(木) 12:33:32.60
>>479
なんのことかと思えば,Mac の launch services というやつね
http://developer.apple.com/library/mac/#documentation/Carbon/Conceptual/LaunchServicesConcepts/LSCIntro/LSCIntro.html
ぱっと見た限り,あるアプリから他のアプリその他を開くもののように見える.
質問した動作は,シェルスクリプトでできる範囲外ってことことなのかなあ.


485 :名無しさん@お腹いっぱい。:2011/09/08(木) 12:34:37.81
>483
できた!さんくす!

486 :名無しさん@お腹いっぱい。:2011/09/08(木) 12:59:00.95
>>484
http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man5/launchd.plist.5.html

> 質問した動作は,シェルスクリプトでできる範囲外ってことことなのかなあ.

専用のデーモンがいるからそれ使え。


487 :名無しさん@お腹いっぱい。:2011/09/08(木) 13:40:29.79
>>468さんのやり方だと、色々処理の中での出力がログに出ないような・・・
>>469のやり方で、うまくいきました

> ・最終的にscriptコマンドの終了を待ってから呼び出し元のシェルスクリプトを終了したい場合
そうですね、色々処理の終了を待ってくれはしませんね

シェルスクリプトの中で、scriptコマンドを使ってログを取りつつ、何らかのコマンドの
実行結果のログを取って、それらのコマンドの終了後、scriptコマンドをexitで抜ける、
という作業をうまく行うやり方って、あるのかな?
exitで抜けた後に、取られたログをgrepとかで解析したりしたい

いま似たような事をしているシェルスクリプトは、例えばftpのログはリダイレクトさせて
ログに吐かせ、SQL*Plusの実行時はspoolでログに吐かせ、といちいちコマンド単位に
別々の方法でログに出力させて、一式集めたうえで解析しているのですが、
それをscriptコマンドで統一的に行うことができればなあと思いました

488 :名無しさん@お腹いっぱい。:2011/09/08(木) 16:10:42.61
もっとうまくやりたいことをまとめられないのか。

489 :名無しさん@お腹いっぱい。:2011/09/08(木) 17:14:16.94
set -xでよくね?

490 :自動再起動:2011/09/08(木) 23:25:14.75
>>479 >>486 の回答はありがたいが,勉強不足で理解できてません.
ちなみにUNIXシェルスクリプト逆引き大全333の極意の243番に
「特定のコマンドが実行されているかどうか調べる」
というのがある.それが何かは知らないが,
この場合,Macのアプリは「コマンド」には該当しないということですかね.
もし該当するならすぐ答えが出そうなものだから.


491 :自動再起動:2011/09/08(木) 23:32:52.83
おっと失礼.>>486 のリンクがおかしくて,今まで OS X Developer Library の Getting Started
に飛んでいた.いま,再びクリックしたら具体的な項目に飛べた.
Thanks a lot! 読んでみます.


492 :名無しさん@お腹いっぱい。:2011/09/09(金) 07:44:48.75
>>487
昔ながらの方法:

#!/bin/sh
exec 3>stdout.log
# stdoutをfd3に切り替える
exec 1>&3
exec 4>stderr.log
# stderrをfd4に切り替える
exec 2>&4
echo "ftp:"; echo "ftp:" 1>&2
echo "ftp log"; echo "ftp error" 1>&2
echo "sql:"; echo "sql:" 1>&2
echo "sql log"; echo "sql error" 1>&2
# 切り替えを復帰してfd3とfd4をクローズ
exec 3>&1 3>&-
exec 4>&2 4>&-


493 :名無しさん@お腹いっぱい。:2011/09/09(金) 08:17:56.47
>>492
嘘書くな。

最後の2行で stdoutとstderrが復帰できてない。

あらかじめ fd1 fd2 を execで複製しておいてそれを復帰するべき。

494 :名無しさん@お腹いっぱい。:2011/09/09(金) 11:31:29.30
>>493
なんか丁寧に書こうとして失敗してたね…

#!/bin/sh
exec 3>&1 4>&2 1>stdout.log 2>stderr.log
echo "ftp:"; echo "ftp:" 1>&2
echo "ftp log"; echo "ftp error" 1>&2
echo "sql:"; echo "sql:" 1>&2
echo "sql log"; echo "sql error" 1>&2
exec 1>&3 3>&- 2>&4 4>&-
echo "return"
echo "error return" 1>&2


495 :名無しさん@お腹いっぱい。:2011/09/09(金) 13:58:09.43
>>487
scriptでやろうとしたり、>>494のような努力をするよりも、
TeraTermとかでログとって、まとめて取れたログをPC上で
解析すんのが、ぶっちゃけ一番簡単じゃね?

496 :名無しさん@お腹いっぱい。:2011/09/09(金) 14:21:02.01
>>487
というか、その何らかの処理ってのをまとめて関数にしてしまえばすむ気がするのだが。
俺が勘違いしてるのかな?

497 : 忍法帖【Lv=3,xxxP】 :2011/09/11(日) 22:52:35.33
awk(種類は問いません。インストールするので)で二つの表の処理したいと思っています。
表1
bad.com a3
ddfa.net a5
zdf.sj a13
aaa.com a222
表2
aaa.com sd
zdf.sj tt
bad.com tt
ddfa.net sd
処理結果の表
bad.com tt a3
ddfa.net sd a5
zdf.sj tt a13
aaa.com sd a222
フィールド3の数字を昇順にソートした表にして、表2をフィールド2を挿入したい。
※ワンライナーのPerlでも参考までにお願いします。

498 :名無しさん@お腹いっぱい。:2011/09/11(日) 22:59:20.03
>>497
表1のフィールド1は、表2のフィールド1に絶対に存在すんの?

499 : 忍法帖【Lv=3,xxxP】 :2011/09/11(日) 23:02:41.01
>>498
> 表1のフィールド1は、表2のフィールド1に絶対に存在すんの?
できれば、絶対存在しない場合の方が望ましいです。
存在しない処理のその項目には不明だかとか、そんな感じで処理されるとありがたいです。

500 :名無しさん@お腹いっぱい。:2011/09/11(日) 23:27:21.27
>>497
$ cat tab1.txt
bad.com a3
ddfa.net a5
zdf.sj a13
aaa.com a222
$ cat tab2.txt
aaa.com sd
zdf.sj tt
bad.com tt
ddfa.net sd
$ cat awk.sh
#!/bin/sh
while read LINE
do
col1=`echo $LINE | cut -d ' ' -f 1`
col2=`echo $LINE | cut -d ' ' -f 2`
coln=`echo $col2 | sed s/^a//`
coltmp=`grep $col1 tab2.txt`
if [ 0 != $? ]; then
newcol='-'
else
newcol=`echo $coltmp | cut -d ' ' -f 2`
fi
echo $coln $col1 $newcol $col2
done < tab1.txt | sort -n | cut -d ' ' -f 2,3,4

501 :名無しさん@お腹いっぱい。:2011/09/11(日) 23:30:06.39
>>500
わざとやってんだろw

502 :名無しさん@お腹いっぱい。:2011/09/11(日) 23:40:00.68
  /\___/\
/ ⌒   ⌒ ::: \
| (●), 、(●)、 |    / ̄ ̄ ̄ ̄ ̄
|  ,,ノ(、_, )ヽ、,,   |  < やるじゃん
|   ト‐=‐ァ'   .::::|    \_____
\  `ニニ´  .:::/
/`ー‐--‐‐―´´\

503 :名無しさん@お腹いっぱい。:2011/09/11(日) 23:41:39.60
>>500
あ〜あ、先に書かれちゃったw でも一応書いておこうっと。。。
ただ、表1のフィールド1が表2のフィールド1に存在することが前提だから
ダメだけど

$ paste -d" " <(sed 's/[ \t]\+/ /g' 02.tbl | sort) <(sed 's/[ \t]\+/ /g' 01.tbl | sort) | cut -d" " -f1,2,4 | sort -t" " -k 3.2 -n

504 :名無しさん@お腹いっぱい。:2011/09/11(日) 23:44:55.73
>>500
awk or Perlでお願いします。

505 :名無しさん@お腹いっぱい。:2011/09/11(日) 23:48:07.50
colnの意味が分かった

506 :名無しさん@お腹いっぱい。:2011/09/11(日) 23:49:27.32
>>500,503
ここはシェルスクリプトスレだから…って思ってたら、やっぱりこうなったかw
自分も書こうと思ったけど、やらなくてよかったわ。
正直ソートはsortコマンドに投げたほうが良さそうだと思うんだ。
仕様で表1のフィールド2が重複するならawkだけだと面倒になる。

507 :名無しさん@お腹いっぱい。:2011/09/12(月) 00:17:10.38
>>506に答えてくれないから分からないけど外部コマンドも使って重複してても動くように書いた。

awk 'file != FILENAME { file = FILENAME; table++ }
table < 2 { t[$1] = $2; next }
{
  n = $2; gsub(/[^0-9]/, "", n)
  x = ($1 in t) ? t[$1] : "表2に無いよ"
  print n, $1, x, $2
}' 表2 表1 | sort -n | sed 's/[^ ]* //' >処理結果の表

どのawkでも動く。動作未確認。sortに-k0が要るかも。

508 :名無しさん@お腹いっぱい。:2011/09/12(月) 00:41:27.03
勉強になるな

a222だのa13だのって、ソート無理じゃね?と思ってたが、こういうひと手間尊敬するわ

509 :名無しさん@お腹いっぱい。:2011/09/12(月) 16:17:47.89
やるなぁ

510 :名無しさん@お腹いっぱい。:2011/09/13(火) 23:03:39.63
バイナリエディタの無い環境で、高々30数バイトのために
インストールするのが面倒だったから、下のようなスクリプトを書いた

#!/bin/bash
IFS=
printf "${*/#/\x}"

引数に並べた1バイトのヘキサを、バイナリに変換するだけなんだが
${*/#/\x} ← こいつがbash依存なんだよね
他の環境だったらどうしたらいいか、賢いやり方が思いつかないのだけど
どういった方法があるかな?bash固有の機能を使わないようにしたい

511 :名無しさん@お腹いっぱい。:2011/09/13(火) 23:43:36.25
いちばんどこでも使えそうなのはawkかな


512 :名無しさん@お腹いっぱい。:2011/09/13(火) 23:56:26.00
for i in "$@"
do
printf "\\$(printf "%o" 0x$i)"
done
ってのはPOSIX shなら動くと思う

513 :名無しさん@お腹いっぱい。:2011/09/14(水) 00:21:09.75
マジな話ポータビリティにこだわるのって本当に意味あるの?

514 :名無しさん@お腹いっぱい。:2011/09/14(水) 00:22:35.90
>>497
亀レスですが perl で、こんなんどうでしょう?
表1を逆にしてハッシュ%cに、表2は%dにそれぞれ突っ込んでます。

perl -0777 -e '

%c=(reverse split(/\s+/,<>));

%d=(split(/\s+/,<>));



foreach $k(sort {($a=~/(\d+)/)[0]<=>($b=~/(\d+)/)[0]}keys %c)

{print "$c{$k} $d{$c{$k}} $k\n"}' tab1.txt tab2.txt


実行結果
bad.com tt a3
ddfa.net sd a5
zdf.sj tt a13
aaa.com sd a222


515 :名無しさん@お腹いっぱい。:2011/09/14(水) 00:24:22.25
ありゃ、改行が変に...
空行は無視してください。


516 :名無しさん@お腹いっぱい。:2011/09/14(水) 00:44:40.04
awkだとこれでいいのかな
awk 'BEGIN{for(i=1;i<ARGC;++i)printf("%c",int("0x"ARGV[i]))}'

517 :名無しさん@お腹いっぱい。:2011/09/14(水) 00:45:39.24
>>513
こだわる心がけそのものについては、殊勝であり意味はあるが、だがその行為には価値が無い

518 :名無しさん@お腹いっぱい。:2011/09/14(水) 00:49:48.76
>>511 初めに考えたけど、これを思いついたから。awkも亜種が多いし

>>512
そういえばprintfはどのシェルでも内部コマンドで用意されてたっけ
1つずつ処理するのは時間がかかりそうって思ったんだが、そうでもないのか

>>513 こだわってる訳じゃなく手元にbashの無い環境もあったので

最終的に入力がワードサイズのリトルエンディアンだったことに気が付いて下のようになった

IFS=\
printf "`echo " $*" |sed 's/ \([^ ]*\) \([^ ]*\)/\\\\x\2\\\\x\1/g'`"

皆さんどうもありがとう

519 :名無しさん@お腹いっぱい。:2011/09/14(水) 00:52:13.62
>>516
文字列を数値に直すとき0xを見て16進数と解釈するのはgawkの拡張じゃなかったかな。

520 :名無しさん@お腹いっぱい。:2011/09/14(水) 02:26:04.89
perlだと sprintf("%c", chr(hex($_))) 辺りかな。


521 :名無しさん@お腹いっぱい。:2011/09/14(水) 08:04:47.40
>>513
人によってはあるんじゃない?

522 :名無しさん@お腹いっぱい。:2011/09/14(水) 13:13:00.93
>>513
30代の漏れは大学自体は NEWS や SUNOS / Solaris, FreeBSD, Linux
と混沌とした混在環境だったからポータビリティに気を使ってたなぁ。
よく perl に逃げてた覚えが...


523 :名無しさん@お腹いっぱい。:2011/09/14(水) 15:51:33.93
Perlってひとつの環境のバージョン違いぐらいしか基本的にないから、そういうときは何気に便利よね

524 :名無しさん@お腹いっぱい。:2011/09/14(水) 22:38:18.78
機能に過不足があっても何とか代替手段を編み出せるOSコマンド群と、
モジュール不足で機能が欠損するperl環境を比較すると、perlもそんなに
便利じゃない

原理的OSコマンドセットかGNUのbinutilsかって違いよりも大きいだろ

525 :名無しさん@お腹いっぱい。:2011/09/14(水) 22:46:26.27
シェルスクリプトのちょっとした補完(ここではバイナリ出力)
という目的でLL使おうって話なんだから、
モジュールやらなんやらまで必要なプログラムの話じゃないだろ

526 :名無しさん@お腹いっぱい。:2011/09/14(水) 23:33:29.77
「LL」っていう定着していない略語使う奴に限ってシェルスクリプトを使いこなせていない、の法則。

527 :名無しさん@お腹いっぱい。:2011/09/14(水) 23:48:23.31
LLくらい定着してるだろ

528 :名無しさん@お腹いっぱい。:2011/09/14(水) 23:54:05.97
デブが着るサイズの事だろ。

529 :名無しさん@お腹いっぱい。:2011/09/15(木) 00:16:50.11
LL教室

530 :名無しさん@お腹いっぱい。:2011/09/15(木) 00:47:20.88
>>524
uname の結果見て if 文書きまくって OS 毎にちゃんと動くようにするのは結構辛いぜ?
# 昔 echo -n するのに Solaris ならわざわざ /usr/ucb/echo って指定したり
# とか面倒な事してましたよ。

perl の機能欠損? /bin/sh だけだと機能欠損あるから grep/sed/awk とかを
使ってるわけで、 perl からだって grep/sed/awk とかを呼び出ししても良いわけだし。
何でもかんでも perl で書こうとしてるから不便に感じてるのでは。


531 :名無しさん@お腹いっぱい。:2011/09/15(木) 03:01:04.51
llと言えば 'ls -l' のエイリアスかなと思う。

532 :名無しさん@お腹いっぱい。:2011/09/15(木) 07:20:25.84
64bit定数値を代入する時は右端にちゃんと LL 付けろよ。
long long hoge;
hoge = 123LL;

533 :名無しさん@お腹いっぱい。:2011/09/15(木) 10:04:28.95
>>531
それこそ定着していない。

534 :名無しさん@お腹いっぱい。:2011/09/15(木) 10:54:34.18
>>531
”ll” とかだっせーw

535 :名無しさん@お腹いっぱい。:2011/09/15(木) 10:57:30.47
"””"とかだっせーw

536 :名無しさん@お腹いっぱい。:2011/09/15(木) 12:47:50.47
"\"””\""とかだっせーw

537 :名無しさん@お腹いっぱい。:2011/09/15(木) 16:28:07.16
llって、どのへんが起源なんだろうな

実現方法がOSによって違うからビビる

538 :名無しさん@お腹いっぱい。:2011/09/15(木) 17:22:52.99
ls -l ってわざわざ別名でaliasするほどのものかなあ
よく使うオプションをls自体にaliasしておいて、時々使うものは逐次指定でよくない?

539 :名無しさん@お腹いっぱい。:2011/09/15(木) 17:28:15.73
わざわざっていうか、OS 側でデフォルトで設定してあったりする。

540 :名無しさん@お腹いっぱい。:2011/09/15(木) 17:33:21.42
mjd

541 :名無しさん@お腹いっぱい。:2011/09/15(木) 18:23:27.91
aliasで設定しているOSもあれば、llというコマンド(実体はlsのリンクだが)で提供しているOSもある

542 :名無しさん@お腹いっぱい。:2011/09/15(木) 18:26:06.10
>>541
後者は知らなかったな。
なんてOS?

543 :名無しさん@お腹いっぱい。:2011/09/15(木) 18:31:34.68
/etc/profileや /etc/profile.dにある設定って余計なお世話だから、
OS新規インストール直後に即攻で消すわ。
おまえらもそうだよな?

544 :名無しさん@お腹いっぱい。:2011/09/15(木) 18:33:55.60
消さないよ。

545 :名無しさん@お腹いっぱい。:2011/09/15(木) 18:39:22.98
消さずにリネームして無効にするっていう意味ね。

546 :名無しさん@お腹いっぱい。:2011/09/15(木) 18:41:19.26
リネームもしないよ。

547 :名無しさん@お腹いっぱい。:2011/09/15(木) 18:50:05.32
使うサーバの数多いし自分だけで使うわけじゃないから
なるべくツルシの状態で使うようにしてる。

548 :名無しさん@お腹いっぱい。:2011/09/15(木) 19:01:30.40
商用OSかフリーOSかで違うなぁ。
商用OSなら/etc/profileとか考えられて設定されてるんだろうから、消さない。
フリーOSの場合、メンテナなりパッケーじゃなりの個人的趣味が /etc/profileに
書かれてたりするから、趣味の押しつけ拒否ですぐに消してしまう。

549 :名無しさん@お腹いっぱい。:2011/09/15(木) 19:12:16.22
商用でもいーかげんな設定はあるし、
フリーでも考えて設定してあるのもあるし、
そんなの一概には言えんよ。

550 :名無しさん@お腹いっぱい。:2011/09/15(木) 20:02:48.99
AIXやSolarisだと、いい加減というか、ほとんど何も設定してないでしょ。
HP-UXだと、Terminalの追加設定がprofileだったかに書かれてて、うかつに置き換えたりすると、「あれ?キーがきかねーぞ」とか言われたりするけど。

551 :名無しさん@お腹いっぱい。:2011/09/15(木) 20:19:53.08
FreeBSDの/etc/profile
http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/profile?rev=1.15;content-type=text%2Fplain

552 :名無しさん@お腹いっぱい。:2011/09/15(木) 21:36:49.17
>>542
http://h20000.www2.hp.com/bc/docs/support/SupportManual/c02261048/c02261048.pdf
↑のHP-UX 11i v3のマニュアルによると

ll is equivalent to ls -l (ell)
The shorthand notations are implemented as links to ls.
てことだ

553 :名無しさん@お腹いっぱい。:2011/09/16(金) 02:34:05.36
j jobs
k kill
l ls
とか、aliasで短縮している。
>>513
> マジな話ポータビリティにこだわるのって本当に意味あるの?
捨てプログラムなら何でも良いし、使用頻度低くて危険ではないプログラムならとりあえず自分の環境で動けばいいんじゃないの。
あとLinuxを使いつづけているとオリジナルのプログラムって自然と増えていくし、半年以上経ったプログラムをまじめに読み返したくないから
書きたい衝動のときにやれることはやっておくのがあとあと楽。

554 :名無しさん@お腹いっぱい。:2011/09/16(金) 10:46:07.17
そういう話続けたいなら別のところで



555 :名無しさん@お腹いっぱい。:2011/09/16(金) 11:16:14.80
aliasでやってんのかコマンドでやってんのかって違いは、下手するとシェルスクリプトの実行結果にの影響を与えるものだよ

cronで動かしてるシェルスクリプトとかで

556 :名無しさん@お腹いっぱい。:2011/09/16(金) 11:49:39.54
スクリプト内で短縮形を使うとかありえないw
あと、特に意味もなく使う相対パスも。

557 :名無しさん@お腹いっぱい。:2011/09/17(土) 02:13:08.53
>>538
そう思うけど過去にRed HatだったかVineだったかで/etc/profileにデフォルト設定されてたのよ。
la='ls -a' とかな。
変な癖ついちゃうと後々面倒だから使わなかったけど。

558 :名無しさん@お腹いっぱい。:2011/09/17(土) 08:36:48.69
だからメンテナなりパッケージャなりの個人的趣味の /etc/profileは
即攻で消すべきなんだよ。

559 : 忍法帖【Lv=5,xxxP】 :2011/09/17(土) 11:31:09.22
いきなり消すことないじゃん。
インストール後に速攻rsyncで/etcと$HOMEをコピーして、当分の間残しておく。

560 :名無しさん@お腹いっぱい。:2011/09/19(月) 16:43:26.44
>>557
そうなのか…そういう鳥があったなら仕方ない。
俺はその辺から入った身じゃないけど、その辺から入ってたら確かにaliasしてたかも知れんな。

561 :名無しさん@お腹いっぱい。:2011/09/28(水) 23:09:14.82
./test.sh "a a" "b b" "c c"
とスペースありの
引数を複数指定してシェルスクリプトを起動して、
さらに、
test.sh
では、
./test2.sh "a a" "c c"
と引数 "b b" を削って、別のシェルスクリプトを起動します。

初めの test.sh に渡される引数の数が不定で、
"b b"がどこに現れるかも不定の時、
引数 "b b" だけを抜いて、
test2.sh の引数としたいのですが、どうしたらできますでしょうか?



562 :名無しさん@お腹いっぱい。:2011/09/28(水) 23:19:04.60
>>561

#!/bin/bash

argv=("$@")
for ((i=0; i < $#; i++)) {
case "${argv[i]}" in 'b b') unset argv[i];; esac
}

./test2.sh "${argv[@]}"

563 :名無しさん@お腹いっぱい。:2011/09/28(水) 23:26:47.27
>>562
ありがとうございます!
が、ホントすみませんが、shでお願いします。


564 :名無しさん@お腹いっぱい。:2011/09/28(水) 23:36:05.08
>>561

#!/bin/sh

n=$#
while [ "$n" -gt 0 ]; do
if [ "$1" != 'b b' ]; then
set "$@" "$1"
fi
shift
n=`expr $n - 1`
done

./test2.sh "$@"

565 :名無しさん@お腹いっぱい。:2011/09/28(水) 23:43:24.70
>>564
ありがとございます!
set "$@" "$1"
にはやられました。
ホント助かりました。
精進します。

566 :名無しさん@お腹いっぱい。:2011/09/29(木) 17:01:08.06
setの意味がいまだに良く分かっていない俺

567 :名無しさん@お腹いっぱい。:2011/09/29(木) 17:11:36.86
いいかい、setの活用は set set set。どの setかは文脈で判断するんだ。
ただし、三単現の場合は setsになるので、これも手がかりになる。

568 :名無しさん@お腹いっぱい。:2011/09/29(木) 18:34:51.04
>>564
引数の中に -a -b -c とか含まれていると誤動作する。

set -- "$@" "$1"
だな。
常に set -- にする習慣を。

569 :名無しさん@お腹いっぱい。:2011/10/09(日) 13:58:18.17
引数として渡された複数のテキストファイルに対して
各ファイルの冒頭に、ファイルのフルパス名を書いた簡単なヘッダを付け
それらをcatのように連結させて標準出力したいのですが、どんな感じでやれば良いのでしょうか

570 :名無しさん@お腹いっぱい。:2011/10/09(日) 14:09:57.68
#! /bin/sh
for UNKO in `echo $*`
do
echo "Header: ${UNKO}"
cat ${UNKO}
echo "manko"
done

571 :名無しさん@お腹いっぱい。:2011/10/09(日) 14:24:48.24
ファイル名を相対パスで渡したらフルパスにならんな

572 :名無しさん@お腹いっぱい。:2011/10/09(日) 14:27:36.32
>>570
ありがとうございます、とりあえずこれでも充分です
フルパスにする方法は自分で調べますね

573 :名無しさん@お腹いっぱい。:2011/10/09(日) 14:48:25.58
>>570
フルパス以前の問題として、

in `echo $*` ってギャグかよ! スペース入りファイル名で誤動作しまくり。
in "$@" が常識。あるいは、for文では省略すると in "$@" の意味になる。

574 :名無しさん@お腹いっぱい。:2011/10/09(日) 14:53:46.23
自分は与えられたファイルのフルパスを調べるとき、>>570に倣うなら、

FILENAME=`basename ${UNKO}`
PATHWORK=`dirname ${UNKO}`
FILEDIR=`cd ${PATHWORK}; pwd`
FULLPATH=${FILEDIR}/${FILENAME}

みたいな感じに順々にやってるけど、なんかサクッと取得する方法って、ある?

575 :名無しさん@お腹いっぱい。:2011/10/09(日) 15:04:17.56
FreeBSDやUbuntuにはデフォでrealpathが入ってたような気がするし
Linux系列ならreadlink -fでおk

576 :名無しさん@お腹いっぱい。:2011/10/09(日) 16:53:03.92
bashで
local A=aaa

local -i A=aa
の違いは何なのでしょうか?

577 :名無しさん@お腹いっぱい。:2011/10/09(日) 17:03:21.47
man bash

578 :名無しさん@お腹いっぱい。:2011/10/09(日) 17:08:34.27
>>573
ってことは、相対パスの場合

for S do
echo "<<<<< ${S} >>>>>"
cat ${S}
done

が最適解ですね、ありがとうございます

579 :名無しさん@お腹いっぱい。:2011/10/09(日) 17:16:19.97
>>578
なぜcatの方はクォートしないし

580 :名無しさん@お腹いっぱい。:2011/10/09(日) 17:18:00.09
>>579
あう、>>570 を改変したためクォートしないまま残ってました

581 :名無しさん@お腹いっぱい。:2011/10/09(日) 17:42:37.61
doの前に;

582 :名無しさん@お腹いっぱい。:2011/10/09(日) 17:55:48.05
相対パスの場合、
ファイル名として -n とか -v とかが含まれていると
cat "${S}"
が面白いことになるw

583 :名無しさん@お腹いっぱい。:2011/10/09(日) 18:41:50.45
>>575
readlinkか…何気に今日最大の収穫だわい

584 :名無しさん@お腹いっぱい。:2011/10/09(日) 19:08:49.76
>>581-582
ってことは、こんな感じですか?

for NAME; do
echo "ヘッダ${NAME}"
cat "-- ${NAME}"
done

585 :名無しさん@お腹いっぱい。:2011/10/09(日) 19:25:05.39
惜しい!

586 :名無しさん@お腹いっぱい。:2011/10/11(火) 08:05:18.23
ボーンで、配列って使える?くぐってもわからんかった。

587 :名無しさん@お腹いっぱい。:2011/10/11(火) 08:16:38.19
bashとかじゃなきゃ無理じゃなかった?配列っぽく変数を扱うことは出来るが

588 :名無しさん@お腹いっぱい。:2011/10/11(火) 08:18:01.32
>>586
工夫すれば使える。

589 :名無しさん@お腹いっぱい。:2011/10/11(火) 09:15:05.14
とつぜんだがちょっと関数書いたので貼ってみる

gengou(){
TMP_LANG=$LANG ;
LANG=ja_JP.UTF-8 ;
export LANG ;
case $1 in
[0-9]*)
echo $(if test $1 -gt 1988 ;then echo '平成'$(expr $1 - 1988 ;) ;
elif test $1 -gt 1925 ;then echo '昭和'$(expr $1 - 1925 ;) ;
elif test $1 -gt 1911 ;then echo '大正'$(expr $1 - 1911 ;) ;
elif test $1 -gt 1867 ;then echo '明治'$(expr $1 - 1867 ;) ;
else echo '西暦'$1 ;
fi ;)'年' ;
: ;;
[[:alpha:]])
echo "USAGE $0 1" ;;
esac ;
LANG=$TMP_LANG ;
}

どうかな?明治以降で申し訳ないが

590 :名無しさん@お腹いっぱい。:2011/10/11(火) 11:07:07.14
行末の;がキモ過ぎ

591 :名無しさん@お腹いっぱい。:2011/10/11(火) 11:14:31.08
元号は元日から変わるわけじゃない。

592 :名無しさん@お腹いっぱい。:2011/10/11(火) 12:56:56.64
そうだね他に何かある?

593 :名無しさん@お腹いっぱい。:2011/10/11(火) 13:12:47.84
ボーンで使えない $( ) とか [[:alpha:]] は使うべきじゃない。

逆に、ボーン対応しなくていいなら、遅いexpr使わずに $(( )) を使うべき。

594 :名無しさん@お腹いっぱい。:2011/10/11(火) 13:29:44.63
case文で [0-9]*) で判定してるけど、3hoge とかでもマッチするぞ。
正規表現と勘違いしてる?

case文で場合わけするなら、残りは *) でデフォルトにするべき。

シェル関数内の $0 はシェル関数名を表さない。(もとのシェルスクリプト名になる)
なので、USAGE $0 とか書いてるのはおかしい。

595 :名無しさん@お腹いっぱい。:2011/10/11(火) 13:38:30.40
>>590-594
みなさんどうもありがとう。
これでレポートが出せそうです。

596 :名無しさん@お腹いっぱい。:2011/10/15(土) 07:49:31.32
「もし、当該ファイルに、指定した正規表現が含まれているなら、次の処理を実行する」
というような時、どのように書けばいいでしょうか?


597 :名無しさん@お腹いっぱい。:2011/10/15(土) 08:42:17.08
>>596

if egrep '正規表現' file > /dev/null 2>&1; then
次の処理
fi

598 :名無しさん@お腹いっぱい。:2011/10/15(土) 08:59:12.02
grep -qs -e regexp file && hogehoge

599 :名無しさん@お腹いっぱい。:2011/10/15(土) 09:18:58.77
>>598
grep の -q や -s オプションはバージョンによって使えなかったり
挙動が異なったりするので、-q -s を使わずに /dev/null にリダイレクト推奨。

>>597
thenの前に ;

600 :名無しさん@お腹いっぱい。:2011/10/15(土) 16:02:44.00
>>597,598,599
ありがとうございました

601 :名無しさん@お腹いっぱい。:2011/10/17(月) 12:52:21.92
$PATHに、とあるパス($PWD/bin)を追加したいのですが、
$PATHに存在しない場合だけ追加したいです。
それで、あるパスが$PATHに含まれているかどうかを調べるにはどのような方法がいいでしょうか。

if `echo $PATH | grep "$PATH/bin"`; then
 export $PATH=$PATH/bin:$PATH
fi

こんなのでいいでしょうか。


602 :名無しさん@お腹いっぱい。:2011/10/17(月) 13:48:59.00
>>601
内部コマンド(case文)だけでやった方が良い

case ":${PATH}:" in
*:"$PWD/bin":*)
;;
*)
PATH=$PWD/bin:$PATH
;;
esac

603 :名無しさん@お腹いっぱい。:2011/10/17(月) 14:49:24.55
>>602
かっこいい!さんくすです。

604 :名無しさん@お腹いっぱい。:2011/10/17(月) 21:03:41.31
windowsサーバのMRTGをunixで作ってます
unixサーバはMRTG出来てるんだけど、シェルスクリプト使って値取得してます
unixに合わせて欲しいと言われたのでスクリプトやろうとしてますがプログラムほとんど分からなくて困ってます
メモリとcpuとハードが対象で、メモリは%表示でcpuと一緒に一つのグラフに載せてて、MIB取得とグラフ表示は出来てます
出来てるunixのスクリプトの中身を見るとMIB値を取得して変数に入れて除算とかしてるようです
どなたか助けてください


605 :名無しさん@お腹いっぱい。:2011/10/17(月) 21:07:27.04
いや。助けろって言われても俺に具体的に何をしろと?
とりあえずその「出来てるスクリプト」を読んで同じように書けばいいだけのような。

606 :名無しさん@お腹いっぱい。:2011/10/18(火) 00:05:25.33
>>604
監視対象が Windows で値をとってグラフにする側が UNIX ってことでしょ?
別に相手が UNIX だろうが Windows だろうが SNMP で MIB の値をとってくる
ことに変わりはないと思うぞ。

もちろん OID が違うだろうから OID のところだけ変えてやればいいだけなんじゃないか?
# 軽くググった感じでは Windows XP の CPU 使用率とかの OID がでてくるけど。


607 :名無しさん@お腹いっぱい。:2011/10/18(火) 08:18:57.55
>>605
>>606
そうです。windowsのMIB値取得して、unixでグラフ表示です
スクリプトの中身もsnmpwalkでMIB値を変数に入れて計算させてるようなので、MIB値変えてやってみます
ありがとうございます

608 :名無しさん@お腹いっぱい。:2011/10/18(火) 08:35:04.55
配列を各変数に一度に代入したいのですがどう書けばいいのでしょうか?
イメージとしては
a,b,c=array('a','b','c')
のようなことをしたいです

609 :名無しさん@お腹いっぱい。:2011/10/18(火) 23:16:35.95
>>604です
何度も申し訳ないのですが、助けてください
OIDを変えたりいろいろやってみたのですが、いまいちうまく動いてくれません。
下記がまともに動いているunixのスクリプトです
※一度に入らないのでいくつかに分けます

##!/bin/sh

SNMPWALK="/usr/local/bin/snmpwalk"

COMMUNITY="${1:-public}"

HOST="${2:-localhost}"

CPU1=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
ssCpuUser.0 2> /dev/null | awk '{print
$4}' 2> /dev/null`

X=`expr "$CPU1" : '\([0-9][0-9]*\)'`
if [ $CPU1 != $X ]; then
echo "0";echo "0" ; exit;
fi

CPU2=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
ssCpuSystem.0 | awk '{print $4}'`

USAGE1=`echo "( ${CPU1} + ${CPU2} ) * 10" | bc`

610 :名無しさん@お腹いっぱい。:2011/10/18(火) 23:17:44.00
>>609の続きです

MEM1=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
memTotalReal.0 | awk '{print $4}'`
MEM2=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
memAvailReal.0 | awk '{print $4}'`

MEM_FREE=`echo "scale=3 ; ( "${MEM2}" / "${MEM1}" ) * 1000" | bc | cut -d\. -f1`

USAGE2=`expr 1000 - "${MEM_FREE}"`

if [ "${USAGE1}" -lt 0 -o "${USAGE1}" -gt 1000 ]; then
USAGE1="0"
fi

if [ "${USAGE2}" -lt 0 -o "${USAGE2}" -gt 1000 ]; then
USAGE2="0"
fi

echo "${USAGE1}"
echo "${USAGE2}"

exit 0

611 :名無しさん@お腹いっぱい。:2011/10/18(火) 23:47:27.26
>>609がCPU処理
>>610の最初がメモリ処理
最後がifでの分岐と最終結果の表示になってます

CPUについてはOIDを 「hrProcessorLoad」 にしたのですが
どうやら取得できているようです

メモリについては 空きメモリ / トータルメモリ * 1000
をやって使用率をパーセント表示させているようです。
ただ、windowsのsnmpだとトータルメモリが一発で取れないため

MEM3=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
hrStorageSize.5 | awk '{print $4}'`

MEM4=`"${SNMPWALK}" -v 2c -t 0.1 -c "${COMMUNITY}" "${HOST}"
{hrStorageAllocationUnits.5 | awk '{print $4}'`

MEMtotal = "${MEM3}" * "${MEM4}" を追加してトータルメモリを取得してます
同様に使用メモリも算出して
空きメモリ = トータルメモリ - 使用メモリ としてます
そして、最後に 空きメモリ / トータルメモリ * 1000 
で後は使いまわしているのですが、うまくいきません。
そもそもやり方としてはあっているのでしょうか?


612 :名無しさん@お腹いっぱい。:2011/10/19(水) 00:28:31.23
bcに-lがない。突っ込みたいところはあるけど仕事だろ?じゃあ寧ろ弄らないほうがいい

613 :名無しさん@お腹いっぱい:2011/10/19(水) 18:53:11.71
着信したメールをパイプして、Subject: が特定の文字(例えばrequest)なら
本文を標準出力に出すスクリプトを書きたいんですが、考え方が良く分かりません。
ちなみにメールは
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1
MIME-Version: 1.0
To: postmaster@domain.jp
Subject: Test
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit

This is test mail.

-
Subject: が Test で
本文が This is test mail. です。



614 :名無しさん@お腹いっぱい。:2011/10/19(水) 19:01:06.40
>>613
procmail 使え、とかそういう話?

615 :613:2011/10/19(水) 19:42:40.82
>>614
postfixで返信を考えてるんですが、aliasesでメール内容をスクリプトに
パイプすることはできるんです。
パイプで渡された内容は、引数として扱えるのでしょうか?


616 :名無しさん@お腹いっぱい。:2011/10/19(水) 19:50:26.47
標準入力に入る。

617 :名無しさん@お腹いっぱい。:2011/10/19(水) 20:28:33.72
>>611
純粋に snmpwalk でこけてるだけでしょ?
snmpwalk 単体で実行して値が取れるところまで頑張ってくれ。
snmp の話でスクリプト関係ない。
板違いなんで一旦終わりの方向で。

板違いだが一応指針だけ。
もう一度 Windows で CPU 使用率とる OID 調べてみろ。
俺が見た限りだと SNMP4NT とやらをインストールして、
.1.3.6.1.4.1.311.1.1.3.1.1.2.1.3 あたりのどっかの値をとるみたいだ。

ちなみにロード(ロードアベレージ)はかなりの確率で君のほしがって
いる値ではないであろうと推測される。


618 :名無しさん@お腹いっぱい。:2011/10/19(水) 20:38:11.44
>>613
Subject: に Test が含まれるメールのみ、その本文(のみ)を標準出力に出すスクリプト

#!/bin/sh

sed -n '1,/^$/{ /^Subject:/{ /Test/!q } }; /^$/,$p'

619 :名無しさん@お腹いっぱい。:2011/10/19(水) 20:40:06.76
>>613
RFCに従ったメールであれば、「ヘッダ部+空行+本文」の構成なので、
本文のみを抜き出したければ、最初の空行以降の文を抜き出してみそ。

620 :名無しさん@お腹いっぱい。:2011/10/19(水) 20:46:08.68
>>618 が具体解答書いた後に抽象概念だけ書く >>619 って・・・

621 :名無しさん@お腹いっぱい。:2011/10/19(水) 21:05:44.85
そっとしといてやれ。

622 :名無しさん@お腹いっぱい。:2011/10/19(水) 21:06:20.31
>>617
MIB値が正常に取れてなかったです
今日朝イチでケアレスミスを見つけて、そこ直したらメモリとCPUの%とれました
板違いで本当にすみませんでした
教えてくださりありがとうございます

623 :613:2011/10/19(水) 22:55:23.44
>>619
ありがとうございます。
一行ですむんですか
まだ、しっかり理解できないので、勉強してみます。


624 :名無しさん@お腹いっぱい。:2011/10/20(木) 11:20:21.94
結局お礼もらったのは「抽象概念」だけ書いた方じゃないかw

625 :名無しさん@お腹いっぱい。:2011/10/20(木) 13:04:59.53
昨今のメールだと、Subject がエンコードされてて 1行じゃ済まない気がしますが…

626 :名無しさん@お腹いっぱい。:2011/10/20(木) 17:44:11.90
質問です
シェルで、代入するときに、変数名を可変にすふことは可能でしょうか?

array_$1=$some_value

みたいにして、配列のようにあつかいたいのですが…


627 :名無しさん@お腹いっぱい。:2011/10/20(木) 17:51:03.15
>>626
可能。

eval array_$1=$some_value

628 :名無しさん@お腹いっぱい。:2011/10/20(木) 17:57:09.43
>>626
Bシェル系に従ったシェルであれば、「左辺変数名決定→変数展開」の順なので、
展開後に左辺変数名として解釈させたければ、evalを付けて実行してみそ。

629 :名無しさん@お腹いっぱい。:2011/10/20(木) 17:58:51.92
>>627 が具体解答書いた後に抽象概念だけ書く >>628 って・・・

630 :名無しさん@お腹いっぱい。:2011/10/20(木) 18:31:11.49
考え方の解説として>>619>>628も有用だよ

そして>>618が読み解けない俺orz

631 :名無しさん@お腹いっぱい。:2011/10/20(木) 23:36:53.85
あれじゃマルチパートのメール着たら死亡だけどねえ。
boundary指定のメール来ることも考えるのなら、
専用のモジュール使ってperl, python辺りで書いた方がいいよ。
今は>>613みたいな古典的な形式のメールばかりじゃないからね。

632 :名無しさん@お腹いっぱい。:2011/10/21(金) 06:39:13.89
>>625
>>631
元の質問 >>613 は、
システムの遠隔操作等で
「自分で」特定のSubject:(半角英数)のメールを送って操作したいということだから、
SubjectがMIMEエンコードされてたり複数行の場合とか、
マルチパートのメールについては考えなくていい。

633 :625:2011/10/21(金) 09:58:20.71
>>632
だんだんとスレチになってきたけど…
User-Agent が Thunderbird だから、エンコードを知らない古の mail コマンドや
telnet コマンドでmail するときのように自分で Subject をゴリゴリ書いてないのが気になります。
「自分で」アラートメールを送らせて監視するシステムっぽいというのは判断できますが
メールクライアントは、そのアプリの判断で MIME エンコードしますよ。charset=ISO-2022-JP だし。
仕事で作ったとなると「日本語のほうが分かりやすいだろ」とかで仕様変更されトラブることも考えられる。

あえて言えば、勘違いさせるサンプルが悪い。そして俺必死すぎ。

634 :名無しさん@お腹いっぱい。:2011/10/21(金) 10:12:36.43
そういうのは本人が考えることだから
議論してもしょうがない。

635 :名無しさん@お腹いっぱい。:2011/10/21(金) 10:26:41.98
>>633
メールクライアントはThunderbirdだと特定できてるのだから、
Thunderbirdは英数文字のみのSubject:をMIMEエンコードしない。
(たとえcharset=ISO-2022-JPでも)

636 :名無しさん@お腹いっぱい。:2011/10/21(金) 10:56:16.79
RFC 2047 の話題なので、スレチ

637 :名無しさん@お腹いっぱい。:2011/10/21(金) 11:35:22.79
>>632
> 元の質問 >>613 は、
> システムの遠隔操作等で
> 「自分で」特定のSubject:(半角英数)のメールを送って操作したいということだから、

どこにそんなこと書いてあるの?
ちょっとびっくりした。それとも>>613本人なのか?

638 :名無しさん@お腹いっぱい。:2011/10/21(金) 11:37:58.44
なんか日本語読解力ない人が居ますねぇ〜

639 :名無しさん@お腹いっぱい。:2011/10/21(金) 11:45:17.75
「操作する」と「出力する」は全然違うんだが。

640 :名無しさん@お腹いっぱい。:2011/10/21(金) 11:57:23.42
>>639
読解力のなさをわざわざアピールしなくていいよw

641 :名無しさん@お腹いっぱい。:2011/10/21(金) 12:00:57.64
また質問者不在のまま荒れて行く。

642 :名無しさん@お腹いっぱい。:2011/10/21(金) 12:54:28.16
>>640
「出力する」を「操作する」と誤読したボンクラのレスなど読解する必要は無い。

643 :名無しさん@お腹いっぱい。:2011/10/21(金) 13:15:45.03
>>642
「出力する」のは何の為か、って読解力もないのかねw

644 :名無しさん@お腹いっぱい。:2011/10/21(金) 14:40:15.35
メールボックスのフィルター捕まえて、
「遠隔操作」って言葉が最初からおかしい。

645 :名無しさん@お腹いっぱい。:2011/10/21(金) 14:42:47.56
>>644
えっ?
メールボックスのフィルターの話じゃないんだけど・・

646 :名無しさん@お腹いっぱい。:2011/10/21(金) 14:53:32.27
>>615読めよ。
aliasで| cmdしたいんだろ。

647 :名無しさん@お腹いっぱい。:2011/10/21(金) 15:48:23.28
質問者を置いてきぼりにしたくだらない揚げ足取りって、
すっかりこのスレの名物だね。
この板の他のスレではめったにないのに、ここだけは日常的にやってる。


648 :名無しさん@お腹いっぱい。:2011/10/21(金) 16:02:35.18
ここだけじゃないだろ
○○システムズ最後の○○ のスレで毎日やってる

649 :613:2011/10/22(土) 08:27:38.00
やっと、sed -n '1,/^$/{ /^Subject:/{ /Test/!q } }; /^$/,$p' の意味が
分かって帰ってきました。なにかお騒がせしてたみたいですいません。
>>618 ありがとうございました。
とりあえず、Subject: は英文のみ、本文は最初の1行のみを有効にするつもりです。
sedはどうも、一般のシェルとは様子が違うようでなかなかわかりにかいですが
Retrun-Pasth: と 本文を変数に代入することって出来ないでしょうか?





650 :名無しさん@お腹いっぱい。:2011/10/22(土) 08:35:54.71
>>637 よ、>>649 ↓のカキコ見たかい?
> Subject: は英文のみ、本文は最初の1行のみを有効にするつもりです。

やっぱり質問者は制御メールに関する質問をしていたわけだ。
(メールボックスのフィルターの話じゃない)

読解力のなかった >>637 は謝罪会見開け。

651 :名無しさん@お腹いっぱい。:2011/10/22(土) 08:51:58.83
バカが必死すぐる。www

652 :名無しさん@お腹いっぱい。:2011/10/22(土) 09:31:23.54
>>649
凝ったことやりたいならperlか何かで書いた方がいいんじゃないの。

653 :名無しさん@お腹いっぱい。:2011/10/22(土) 09:35:23.36
そういうこと言う奴に限って、「じゃあperlで書いて」と言ったら書けないんだよなw

654 :名無しさん@お腹いっぱい。:2011/10/22(土) 09:37:46.42
そうでもないよ。

655 :名無しさん@お腹いっぱい。:2011/10/22(土) 09:44:15.17
>>649
ちょっと時間がないので概念だけ、

sedを使わずに、/bin/shの while read arg1 arg2 でメール全体を行ごとに読んで回す。
case $arg1 で場合分けして、Subject: やRetrun-Path: の時、
arg2の値を変数にコピーして記憶する。
$arg1が空文字( '' )の時はヘッダーの終了なので、
その場で再度 read body ってやると、"$body" にメール本文の最初の1行が入る。
ここで breakでwhileループを中断する。

656 :613:2011/10/22(土) 09:48:18.87
>>652
Postfixのaliasが、メールのテキストをパイプで渡すみたいねんですが
シェルにしても、perlにしても標準入力を変数に代入するにはどうすればいいですか?
どうもこのパイプからの入力の扱いが理解できて無いもので


657 :名無しさん@お腹いっぱい。:2011/10/22(土) 10:09:37.85
read使う。

658 :名無しさん@お腹いっぱい。:2011/10/22(土) 10:35:08.49
>>655 が投稿した「後」に何の情報も増えてない投稿する >>657 って・・・

659 :名無しさん@お腹いっぱい。:2011/10/22(土) 10:39:38.60
俺は656の質問に答えただけだけど。

660 :名無しさん@お腹いっぱい。:2011/10/22(土) 10:41:04.97
>>655 をコーディングすると、以下になる。


#!/bin/sh

while read arg1 arg2
do
case $arg1 in
Subject:)
subject=$arg2;;
Retrun-Path:)
return_path=$arg2;;
'')
read body
echo "$subject"
echo "$return_path"
echo "$body"
break;;
esac
done

ただし、while文を抜けるとサブシェル問題で変数が元に戻る問題は別途対応のこと。

661 :613:2011/10/22(土) 11:01:19.56
>>655 660
なんとなく分かったような
また、しばらくもぐりこんできます。
ありがとう


662 :名無しさん@お腹いっぱい。:2011/10/22(土) 12:48:13.35
>>637 = >>639 = >>642 = >>644 = >>651
の謝罪会見まだぁ??

663 :名無しさん@お腹いっぱい。:2011/10/22(土) 14:06:32.88
>>650 粘着キチガイ犬が必死すぎる。www

664 :名無しさん@お腹いっぱい。:2011/10/22(土) 14:11:51.76
>>656
> perlにしても標準入力を変数に代入するにはどうすればいいですか?
while (<>) { ... } で $_ に入れる、とか。
http://www.lr.pi.titech.ac.jp/~abekawa/perl/perl_lecture.html

665 :名無しさん@お腹いっぱい。:2011/10/22(土) 14:12:22.64
謝罪とか何とかはよそでやってくれよ。邪魔。

666 :名無しさん@お腹いっぱい。:2011/10/22(土) 14:16:40.84
>>650
何ら立証できてないのに、バカがはしゃいで勝ち誇ってる。哀れすぎる。

667 :名無しさん@お腹いっぱい。:2011/10/22(土) 14:39:26.40
>>666

>>649 (質問者本人)
> Subject: は英文のみ、本文は最初の1行のみを有効にするつもりです。


この質問者本人からの1文で,完璧なまでに >>666 の敗北が立証されたねw
それとも >>666 は読解力がないから、自分が敗北したことも理解できてないのか?ww

668 :名無しさん@お腹いっぱい。:2011/10/22(土) 16:49:54.52
捌くメールの数が大したことないなら1パスにこだわらずに、
subject=`sed -n '1,/^$/s/^Subject:\(.*\)/\1/p' "$FILE"`
returnpath=`sed -n '1,/^$/s/^Return-Path:\(.*\)/\1/p' "$FILE"`
body=`sed -n '/^$/,+1p' "$FILE"`
としてもいいんじゃないの?

多い場合は舐めるデータ量より、sedの三回起動のほうが問題になるはず。

669 :名無しさん@お腹いっぱい。:2011/10/22(土) 16:53:00.47
>>656
上のようにstdinを三回舐める時は、
cat > /tmp/foobarbaz$$
/tmp/foobarbaz$$に対する処理
rm -f /tmp/foobarbaz$$
とすればいい。

670 :名無しさん@お腹いっぱい。:2011/10/22(土) 16:58:22.16
1パスの解答 >>660 の後に 3パス(しかも一時ファイル必要)の解答する >>668 って・・・

671 :名無しさん@お腹いっぱい。:2011/10/22(土) 17:03:01.10
>>667
精薄哀れすぎる。 www

それだけで制御と決めつけられる単純な思考しか出来ない事を
そんなに必死になってアピールしなくてもいいんだぞ。

672 :名無しさん@お腹いっぱい。:2011/10/22(土) 17:15:37.83
>>670
必要なかったかね。
仕様では:の後はスペースなくても構わないので、
(その辺は説明せずに)つい書いてしまったわ。
IFSに:を加える修正したほうが良かっただろうね。

673 :名無しさん@お腹いっぱい。:2011/10/22(土) 22:27:56.31
>>670
くだらねーツッコミしてるお前よりかは、
建設的というか有益なんじゃね?

674 :名無しさん@お腹いっぱい。:2011/10/24(月) 14:31:59.41
findコマンドでカレントディレクトリからファイルを探す場合、
find . -name '*.html'
としますが、これだと
./views/foo.html
のように、頭に「./」がついてしまいます。
今はsedを使ってこれを取り除いているのですが、find自体でこれをつけないようにすることはできませんか。



675 :名無しさん@お腹いっぱい。:2011/10/24(月) 14:48:52.05
>>674
GNU findで、 -printf %P

676 :名無しさん@お腹いっぱい。:2011/10/24(月) 14:55:30.34
find * -name '*.html' で行けるかなと思ったけど、ドットで始まるディレクトリ
が検索対象にならないからダメでした…

677 :名無しさん@お腹いっぱい。:2011/10/24(月) 15:18:00.71
>>675
うう、Macだからgnu findではなかった。。。
linuxだったらいけるんでしょうね。残念!

678 :名無しさん@お腹いっぱい。:2011/10/24(月) 18:16:30.00
前の担当者(フランスに渡米中)が書いたシェルに、
↓みたいなのがあるんだ。

exec 3<&0
exec < ファイル

while read line; do
ほげほげ;
done

exec 0<&3


これ、何でわざわざ execとか使ってるの? なんか意味あるの?
while … done < ファイル
って書けばいいんじゃないの?
担当者が書き方知らなかったんでしょうか?

679 :名無しさん@お腹いっぱい。:2011/10/24(月) 19:23:26.39
使ってみたかったんじゃない。「exec使ってる俺ってステキ!」みたいな

680 :名無しさん@お腹いっぱい。:2011/10/24(月) 19:59:38.22
>>678
http://www.faqs.org/faqs/unix-faq/faq/part3/section-8.html

POSIXではwhileリダイレクトはカレントシェルで実行されることになっているけど
伝統的なbourne shellではwhileリダイレクトはサブシェルで実行された
その問題への対処として、まさにそれと同じようなexecトリックが
上のページで説明されているよ


681 :名無しさん@お腹いっぱい。:2011/10/24(月) 20:23:12.58
>>680
そんな深い意味があったのですね。ありがとうございました。
あやうくシェルを書き直すところでした。

682 :名無しさん@お腹いっぱい。:2011/10/25(火) 04:41:44.48
b

683 :名無しさん@お腹いっぱい。:2011/10/25(火) 18:07:14.98
シェルってゆーな
フランスに渡米中するな

684 :名無しさん@お腹いっぱい。:2011/10/25(火) 18:34:31.52
シェル自体を書き直すのは尊敬するなあ
普通はシェルスクリプトの修正で済ませるだろうに

ぐらいにしとき

685 :名無しさん@お腹いっぱい。:2011/10/25(火) 19:06:53.52
>>683
そこツッコんだら負け。

686 :名無しさん@お腹いっぱい。:2011/10/25(火) 22:59:20.26
>>681
その手があったか...!

687 :名無しさん@お腹いっぱい。:2011/10/27(木) 01:51:27.89
この中に何問くらい
学校のレポート課題があるんだろう…


688 :名無しさん@お腹いっぱい。:2011/10/27(木) 02:08:45.38
今時学校のレポート課題にシェルスクリプトを書けってのはそんなにないんじゃない?
>>589みたいに何の役にも立たないスクリプトなら見ただけで学校の課題って分かるけど。

689 :名無しさん@お腹いっぱい。:2011/10/27(木) 08:51:53.40
>>687
そんなことがお前の心配事か?

690 :名無しさん@お腹いっぱい。:2011/10/27(木) 10:04:54.24
そうだ。

691 :名無しさん@お腹いっぱい。:2011/10/27(木) 13:25:53.60
128bit の数値って、シェルでそのまま扱えたでしょうか?

expr だと 32bit まででした…IPv4ならともかく、IPv6が…

692 :名無しさん@お腹いっぱい。:2011/10/27(木) 13:31:07.16
今のバージョンの GNU expr は 128bitでも行ける。

693 :名無しさん@お腹いっぱい。:2011/10/27(木) 13:31:28.94
bcでも使えばいんじゃないの。

694 :名無しさん@お腹いっぱい。:2011/10/27(木) 13:33:54.24
ldd expr したら、
libgmp とリンクしてるじゃん。
こりゃ、128bitどころか、10進で1万桁とか100万桁とかでも行けるわ。

695 :名無しさん@お腹いっぱい。:2011/10/27(木) 13:42:20.00
>>692
う〜ん、GNU…最新版に更新させてくれるかなぁ…
できなきゃ、やっぱり桁毎にわけて管理するトリッキーな方法を採るしかなさげ…

>>693
あ、bc だと 64bit までいけましたが、128bitになると途端に挙動がおかしくなってくれまして。


696 :名無しさん@お腹いっぱい。:2011/10/27(木) 13:51:09.95
libgmpってお絵書きソフトのライブラリだっ毛?
それがbit数とどういうご関係で??

697 :名無しさん@お腹いっぱい。:2011/10/27(木) 13:57:31.01
>>695
じゃあdc

698 :名無しさん@お腹いっぱい。:2011/10/27(木) 13:58:35.78
gimpとgnu mpは違うものとマジレス

699 :名無しさん@お腹いっぱい。:2011/10/27(木) 14:17:07.85
>>697
dc は対話モードだけかなぁなんて思ってたので、挫折してました…。
128bit が扱えるなら、もうちょっと頑張ってみます。

700 :名無しさん@お腹いっぱい。:2011/10/27(木) 16:36:58.12
IPv6アドレスの処理ならビット演算くらいしかしないでしょ。
16bitに分けて計算すれば?
それとも足し算して桁上がりとかあるのかい?

v6なら16bitバウンダリ以外で区切る状況は少ないでしょ。

701 :691:2011/10/27(木) 18:54:44.18
みなさま、ありがとうございます。

>>700
四則演算するというより、ソート目的ですね。
ip2long的な(これはPHPですが)。
単純にできれば、それに越したこと無いと思います。

702 :名無しさん@お腹いっぱい。:2011/10/27(木) 21:09:13.79
シェルでソートしちゃうの?

703 :691:2011/10/28(金) 00:26:42.49
$ sort -n
で…と思ったましたけど、sort コマンド自体 128 bit を扱えそうにないことに
今更気づきましたよ。ダメじゃん。
素直にトリッキーなシェルスクリプト(16bit毎に計算するタイプ)組んでおきます orz

128bit 空間は、デカすぎ

704 :名無しさん@お腹いっぱい。:2011/10/28(金) 00:36:44.16
省略なしの文字列にしたらsortで比較できるでしょ

705 :名無しさん@お腹いっぱい。:2011/10/31(月) 16:07:26.28
bashで別サーバのファイルリスト取得したいんだけどftp&ls使うのが良いのかな?
他に良い方法ある?

706 :名無しさん@お腹いっぱい。:2011/10/31(月) 16:11:50.98
ふつー ssh 別サーバー ls -laR /

707 :名無しさん@お腹いっぱい。:2011/10/31(月) 16:14:36.02
ああそっか一回入っちゃえば良いか
「別サーバの情報取得」みたいに考えちゃってたのが不味かったか

回答ありがとうございます

708 :名無しさん@お腹いっぱい。:2011/10/31(月) 16:15:58.31
FTPだって「一回入っ」てね?

709 :名無しさん@お腹いっぱい。:2011/10/31(月) 16:49:07.81
ftp でやるなら ncftpls でやると少し楽だよ
まぁ、ssh できるなら間違いなく ssh つかうけど

710 :名無しさん@お腹いっぱい。:2011/10/31(月) 17:40:03.30
rsh のように ssh を使えるなんて、、、

711 :名無しさん@お腹いっぱい。:2011/10/31(月) 17:43:06.97
もともと rsh のセキュア版じゃん。

712 :名無しさん@お腹いっぱい。:2011/11/02(水) 00:02:17.09
文字列の先頭を小文字から大文字に変えたいんですが、どうすればいいですか?

イメージ的には
echo hello | hoge
とやれば、
Helloが出力されるみたいな。


713 :名無しさん@お腹いっぱい。:2011/11/02(水) 00:20:34.84
echo hello | sed -r 's/(^[a-z])/\U\1/'

714 :名無しさん@お腹いっぱい。:2011/11/02(水) 00:27:44.47
へえ、sed -rだと\Uが使えるのか
echo hello | sed 'h;s/\(.\).*/\1/;y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/;G;s/\(.\)../\1/'

715 :名無しさん@お腹いっぱい。:2011/11/02(水) 00:28:55.19
誤解してるようだけど-rは () NO

716 :名無しさん@お腹いっぱい。:2011/11/02(水) 00:29:43.73
誤解してるようだけど-rは()の前の\をなくすためだぞ。

717 :名無しさん@お腹いっぱい。:2011/11/02(水) 00:33:14.46
\UってGNUかなんか?

718 :名無しさん@お腹いっぱい。:2011/11/02(水) 00:35:57.98
ああほんとだ
GNU依存だね

719 :名無しさん@お腹いっぱい。:2011/11/02(水) 01:34:30.14
じゃあPOSIXの範囲で
echo hello |awk '{print toupper(substr($0,1,1))substr($0,2)}'

720 :名無しさん@お腹いっぱい。:2011/11/05(土) 00:55:41.43
シェルスクリプト内でexportしたい場合って
どうすべきなのでしょうか・・・

普通に
#!/bin/sh
OUT="$HOME/bin"
export OUT
というスクリプト(test.sh)を作って
パーミッションを755なんかに設定して
./test.sh
このように実行しても
シェル内の環境変数にはセットされないですよね?

source test.sh

とすれば環境変数にはセットされますが
exitできなくなったりで不便で・・・


721 :名無しさん@お腹いっぱい。:2011/11/05(土) 07:56:13.29
>>720
sourceしたスクリプトでexitすると元のシェルが終了してしまうという問題なら、
exitの代わりに returnを使えば桶。

722 :名無しさん@お腹いっぱい。:2011/11/07(月) 19:32:14.25
微妙にスレチかも知れないんですが教えてください

mysqladmin ping
とかでmysqlのインスタンスが起動しているか否か判別出来ると思うんですが、
例えばインスタンスが起動していない場合でも
mysqladmin ping > a.log
とかやっても実際はエラーが出力されるのにテキストにはこの場合、何も出力されません。

何か良い方法ありませんか?


723 :名無しさん@お腹いっぱい。:2011/11/07(月) 19:35:14.48
> a.log 2>&1
という話か?

724 :名無しさん@お腹いっぱい。:2011/11/07(月) 19:42:49.55
>>723
おおー!!エラーは出力が別なのか…知らなかった!

ありがとうございます

725 :名無しさん@お腹いっぱい。:2011/11/07(月) 22:22:11.24
sedで、"を置き換えたい場合は、sed 's/"//'のようにして、
'を置き換えたい場合は、sed "s/'//"のようにしてますが、
'も"も置き換えたいという場合は、みなさんならどうしますか?


726 :名無しさん@お腹いっぱい。:2011/11/07(月) 22:29:27.87
$ sed "s/['\"]//g" ...

727 :名無しさん@お腹いっぱい。:2011/11/07(月) 22:37:13.51
>>726
シングルとダブルを逆にしてみたらこうなった。
$ echo morning\'noon\"night | sed 's/["\']//g'
>

不思議。。。


728 :名無しさん@お腹いっぱい。:2011/11/07(月) 23:00:53.54
[ の直後の1文字は特別扱いされる

729 :名無しさん@お腹いっぱい。:2011/11/07(月) 23:10:00.12
単純にシングルクオートの中だからエスケープされてないだけでは?

730 :名無しさん@お腹いっぱい。:2011/11/10(木) 20:03:26.47
sed -e 's/"//' -e "s/'//"

731 :名無しさん@お腹いっぱい。:2011/11/10(木) 20:33:37.44
俺なら面倒だから全体あるいはその部分をクオートからはずす

sed s/[\"\']//g

sed 's/['\"\'']//g'


732 :名無しさん@お腹いっぱい。:2011/11/11(金) 21:30:05.22
シェルスクリプトの超初心者です。

linuxマシンからリモートのlinuxマシンに対して

ローカルマシンからsshでリモートログインして、リモートマシンのシェル上での操作を連続して実行するシェルスクリプトを
作成したいと考えているのですが、それは可能なのでしょうか。

ローカルマシンでssh等のコマンドをシェルスクリプトで連続して実行できますが、ログインしてからの操作を、どう
書いたら良いのか全くわかりません。これって原理的に無理なのかな?と思ってしまいますが・・・。

ヒントをいただけると助かります。

733 :名無しさん@お腹いっぱい。:2011/11/11(金) 21:43:00.04
>>732

-----
#!/bin/sh
hostname
whoami
-----

↑というスクリプトをリモートで実行したい場合、

-------------------------
#!/bin/sh
ssh リモートホスト '
hostname
whoami
'
-------------------------

全体(複数行)を ' ' で囲んで中にコマンドを書く

734 :名無しさん@お腹いっぱい。:2011/11/11(金) 21:50:45.95
>>733
さっそくコメントありがとうございます。
さっそく試してみたいと思います。

735 :名無しさん@お腹いっぱい。:2011/11/12(土) 00:59:31.94
>>733

#!/bin/sh
ssh remotehost /bin/sh -c '
hostname
whoami
'

でしょ

736 :名無しさん@お腹いっぱい。:2011/11/12(土) 09:00:52.62
>>735
それだと ' ' の中が2重解釈されて動かない場合がある。

>>733 で正解。

737 :名無しさん@お腹いっぱい。:2011/11/12(土) 09:12:12.02
>>735
確認してから書き込め馬鹿。
>>735 だと、
「/bin/sh -c」
「hostname」
「whoami」
という3つのコマンドが個別にremotehostで実行される。
で、「sh -c」で
sh: -c: option requires an argument

ってエラー出る。残りのhostnameとwhoamiは、
/bin/sh -c を通さずに sshのログインシェルで直接実行される。

で、結局 /bin/sh -c の意味がないので >>733 で良いことになる。

>>736 「動かない場合がある」じゃなくて、もともと期待通りに動かない。

738 :名無しさん@お腹いっぱい。:2011/11/12(土) 20:52:48.94
apt-get install hoge
などが並んだスクリプト作ったのですがいちいち[y/n]で入力を求められます
ここでy自動的にを入力とかできるんですか?

739 :名無しさん@お腹いっぱい。:2011/11/12(土) 20:56:22.14
>>738
yes

740 :名無しさん@お腹いっぱい。:2011/11/12(土) 21:36:33.23
apt-getなら-y | -yes | --assume-yesあたりのオプション使えば良い

741 :名無しさん@お腹いっぱい。:2011/11/12(土) 21:43:47.38
ありがとうございます

742 :名無しさん@お腹いっぱい。:2011/11/12(土) 23:03:16.31
a="foo\nbar"
のような変数をフィルターしたい場合はどうすればいいんでしょうか?
とりあえずechoを使って

echo $a | head -1

としていますが他に書き方がありますか?

743 :名無しさん@お腹いっぱい。:2011/11/12(土) 23:10:18.91
echo "$a" | (read b; echo "$b")

744 :名無しさん@お腹いっぱい。:2011/11/12(土) 23:19:05.86
>>737
>>733の前半のスクリプトは確実に /bin/sh で実行されるのに対して、
後半はリモートホストのログインシェルで実行されるんですよね。
/bin/sh で実行したいときはどうしたら良いですか?

745 : 忍法帖【Lv=18,xxxPT】 :2011/11/12(土) 23:21:42.78
実行されるシェルが違ったら同じスクリプトを実行しても結果が同じとは限らないからな〜
バカはどっちかなぁ

746 :名無しさん@お腹いっぱい。:2011/11/12(土) 23:23:20.64
>>744
こうじゃね
ssh remotehost sh -c "'hostname
whoami
printenv'"

747 :名無しさん@お腹いっぱい。:2011/11/12(土) 23:25:31.02
>>744
ssh remote-host 'sh -c \'なんだ; かんだ\''

748 :名無しさん@お腹いっぱい。:2011/11/12(土) 23:31:50.02
いまどき ログインシェル≠/bin/sh なんてユーザーはいないから。
少なくともリモートログインする鯖は ログインシェル=/bin/sh 以外あり得ない

749 :名無しさん@お腹いっぱい。:2011/11/12(土) 23:33:21.91
>>747
それちがうよ。シングルクォートの中はバックスラッシュでエスケープできない

750 :名無しさん@お腹いっぱい。:2011/11/12(土) 23:57:12.05
>>748
えっ?逆に今どきだからログインシェルzshとかあるだろ?

751 :名無しさん@お腹いっぱい。:2011/11/13(日) 00:26:19.45
>>748
へ?

752 :名無しさん@お腹いっぱい。:2011/11/13(日) 23:41:42.45
/bin/shの実体がbashだったり、posixシェル(といいつつksh)だったり。

753 :名無しさん@お腹いっぱい。:2011/11/13(日) 23:53:05.98
>>752
それは無問題。

754 :名無しさん@お腹いっぱい。:2011/11/14(月) 07:15:07.39
>>746でFAで良いんじゃないのか
よー分からんが


755 :名無しさん@お腹いっぱい。:2011/11/14(月) 07:41:52.91
>>754
>>746 はコマンド内部にさらにクォートが必要な場合に困る。

最初の >>733 でFA。

756 :名無しさん@お腹いっぱい。:2011/11/14(月) 10:42:51.50
echo 'hostname
whoami' | ssh remotehost sh


757 :名無しさん@お腹いっぱい。:2011/11/14(月) 10:46:37.80
>>756
それだと、rm -i のように標準入力を読むコマンドがあった場合におかしくなる

758 :名無しさん@お腹いっぱい。:2011/11/14(月) 10:47:35.04
>>732は納得したのかな。

759 :名無しさん@お腹いっぱい。:2011/11/14(月) 11:35:30.06
>>757
/bin/shで実行されなきゃいけないスクリプトだったとしても
/bin/shで実行される保証のない>>733よりはマシだと思うな。


760 :名無しさん@お腹いっぱい。:2011/11/14(月) 11:40:05.30
つーか、流しこむスクリプトがshじゃなくてperlだったりなんだったりする
可能性を考えると、

scp hoge.sh remotehost:/tmp/
ssh remotehost sh /tmp/hoge.sh
ssh remotehost.rm /tmp/hoge.sh

がいちばん汎用性が高くて確実だな。


761 :名無しさん@お腹いっぱい。:2011/11/14(月) 13:19:40.74
>>760
添付ファイルを作っちゃうと美しくないし、
複数のプロセスで同時実行した時干渉する。

762 :名無しさん@お腹いっぱい。:2011/11/14(月) 16:37:56.72
添付・・・?

763 :名無しさん@お腹いっぱい。:2011/11/14(月) 16:45:13.12
ネタニマジレ(ry

764 :名無しさん@お腹いっぱい。:2011/11/14(月) 18:45:39.36
結局、ログイン先のシェルも指定でき、且つどんなコマンドも実行出来て余分なゴミファイルを作成しない模範回答はどれよ?

765 :名無しさん@お腹いっぱい。:2011/11/14(月) 18:54:43.62
(echo ""; sleep 1
echo "コマンドをつらつら記述"; sleep 1
echo ""; sleep 1
echo "exit") | telnet (ホスト名かIPアドレス)


むかし、こんなやりかたでメールを送ってたことがある…(もちろん記述内容は違うけど)

766 :名無しさん@お腹いっぱい。:2011/11/14(月) 18:57:46.37
最初にsleep 1する意味が分からん

767 :名無しさん@お腹いっぱい。:2011/11/14(月) 19:22:57.61
実際やってみるとわかるけど、適度に sleep を入れないと取りこぼす。
っていうか、1秒でもよくコケる。
結論: telnet は使いものにならないから nc を使え。


768 :名無しさん@お腹いっぱい。:2011/11/14(月) 21:12:17.86
>>767
SMTP みたいに "会話" する場合は expect がいいんだが、マイナーだからみんな知らないのかな。
昔作ったメール送信用 expectスクリプトの一部晒しとくわ。 興味持ったら勉強してみるといい。

spawn telnet localhost 25
expect -re "220 .*"
sleep 0.3
send "HELO localhost\r"
expect -re "250 .*"
sleep 0.3
send "MAIL FROM: foo@example.com\r"
...


769 :名無しさん@お腹いっぱい。:2011/11/14(月) 21:23:47.16
>>768
昔作っただけあって、EHLOじゃなくてHELOですがそうですかとか、
expectはもちろんみんな知ってるけど、いまどきexpectはスマートじゃないので
なるべく避けるのと、SMTPなら curlコマンドの smtp://mailhost とかでできるので
そっち使った方がいいとか、まあそんなとこだな。

770 :名無しさん@お腹いっぱい。:2011/11/14(月) 22:24:48.60
rsh remote-host sh -c '
頑張って
中身は
クオートしながら書いてくれ’

771 :名無しさん@お腹いっぱい。:2011/11/14(月) 22:26:44.74
>>770
だから、その書き方自体が間違い。>>737 が指摘してる通り。

772 :768:2011/11/14(月) 23:03:22.81
>>769
curl で SMTP できるのは知らんかった。 勉強になります。
今時は expect は使わないのか... で何使ってるん?


773 :名無しさん@お腹いっぱい。:2011/11/15(火) 01:11:15.54
>>771
だから>>737はログイン先の
シェルを指定してないから
予期しない動作をする可能性があるだろ。

774 :名無しさん@お腹いっぱい。:2011/11/15(火) 01:12:34.45
逆にログイン先のシェルに手元のシェルを合わせたらいかんのか

775 :名無しさん@お腹いっぱい。:2011/11/15(火) 06:24:18.71
>>773
ログイン先のシェルはBシェル系と考えて良い
少なくとも、自分がアカウントを持っているログイン先なんだから
「予期しない」わけがない

あと、発想を変えて、
/bin/shをログインシェルにしたアカウントを別に作ってもいいわけだし。

776 :名無しさん@お腹いっぱい。:2011/11/15(火) 13:46:21.78
「リモートはUNIXじゃないかもしれない」とか切りないので、
適当な仮定を考えるセンスが必要。

話は変わるが、コマンドを区切るのに改行派が多いのに驚愕。
俺はセミコロン派。

777 :名無しさん@お腹いっぱい。:2011/11/15(火) 18:45:20.87
>>776
ワンライナーでシェルスクリプト書くのか?

778 :名無しさん@お腹いっぱい。:2011/11/15(火) 22:49:35.69
やりたいこと:
「git merge」を必ず「--no-ff」つきで実行したい

方針:
function git {} を定義し、引数に「merge」があった場合にそれを「merge --no-ff」に置き換えて実行する
Perlで書くとこんなかんじ

sub git {
 my $i = 0;
 for (@_) {
  $i++;
  if ($_ eq "merge") {
   slice(@_, $i, 0, "--no-ff");
   last;
  }
 }
 my $command = join(" ", @_);
 `$command`;
}

わからないこと:
shell関数の書き方、特に slice と `$command` の方法

function git {
for i in $*; do
# どう書けばいいの?
done
}

だれか教えて!


779 :名無しさん@お腹いっぱい。:2011/11/15(火) 23:01:14.49
>>778

function git {
n=$#
while [ "$n" -gt 0 ]; do
set -- "$@" "$1"
if [ "$1" = 'merge' ]; then
set -- "$@" --no-ff
fi
shift
n=`expr $n - 1`
done
command git "$@"
}

780 :名無しさん@お腹いっぱい。:2011/11/15(火) 23:55:01.18
>>779
なにこれすごい・・・
sliceのかわりに、配列の要素を循環させていくのか。すごいテクニックですね。
ありがとうございました。

781 :名無しさん@お腹いっぱい。:2011/11/16(水) 11:49:25.77
bashです。

up()
{
curl -F "file=@$1;filename=$(basename $1)" -X POST http://www.example.com/upload.cgi
}

up manko.jpg

で417エラーが返ってくるのですが、curlに追加すべきオプションは何でしょうか?
それともアップロードCGI次第なんでしょうか。教えてください。


782 :名無しさん@お腹いっぱい。:2011/11/16(水) 12:05:18.45
CGI次第。

783 :名無しさん@お腹いっぱい。:2011/11/16(水) 13:07:07.93
>>782
つまりCGIを変更しない限りシェルスクリプト側ではどうにも出来ないという事ですか?

784 :名無しさん@お腹いっぱい。:2011/11/16(水) 13:36:13.16
それもCGI次第。

785 :名無しさん@お腹いっぱい。:2011/11/16(水) 14:14:19.94
>>784
シェルスクリプト/CGIを含めて、一番スマートなファイルアップロードの
仕組み・書き方を教えてください。

最初からこう聞けば良かった。

786 :名無しさん@お腹いっぱい。:2011/11/16(水) 14:17:59.10
scp

787 :名無しさん@お腹いっぱい。:2011/11/16(水) 15:20:22.30
scp は認証もあり十分複雑だと思う。
ftpで

788 :名無しさん@お腹いっぱい。:2011/11/16(水) 15:32:34.05
インデントはスペース何個分が一般的ですか?

789 :名無しさん@お腹いっぱい。:2011/11/16(水) 15:33:01.48
>>785
その聞き方だと話が拡散するぞ。
もうちょっと状況を絞ってくれ。

790 :名無しさん@お腹いっぱい。:2011/11/16(水) 15:48:02.61
>>789
すみません。CGIと出しているので、scpやftpがくるとは思いませんでした。

具体例を書きます。

1)アップロード先サーバはフリーのレンタルサーバ。SSH不可。FTP/CGI(perl)可。
2)CGIアップローダは既存のものが使えたら良いが、自前で準備することも可。
3)クライアント側のポートフィルタの関係上、HTTPでファイルをアップロードしたい。
4)curl/wgetなどの一般的なコマンドでbashベースのスクリプトでアップロードしたい。
5)アップロードするファイル(バイナリ)は、設備の温度ログ等なので秘匿する必要はない。

といった具合です。


791 :名無しさん@お腹いっぱい。:2011/11/16(水) 16:05:42.78
ftpのPASVモードでええやん

792 :名無しさん@お腹いっぱい。:2011/11/16(水) 16:28:15.83
>>791
ポートフィルタ以外にも、HTTP以外のセッションは張れないよう、プロトコルを監視して
フィルタリングしているので無理ですね。仮に使えたとしても、クライアント側にFTPパスワードを
記載しておけないので、FTPは使えません。

と、言いたいところですが、シェルスクリプト(curl/wget)でHTTPのPOST送信ってそんなに難しいものなんですか?
やたら、こちらが意図してないftpばかり勧めてくる方がいるので、不安になってきました。
(´・ω・`)


793 :名無しさん@お腹いっぱい。:2011/11/16(水) 16:35:12.28
> 1)アップロード先サーバはフリーのレンタルサーバ。SSH不可。FTP/CGI(perl)可。

「FTP可」って書いてあるけど?

794 :名無しさん@お腹いっぱい。:2011/11/16(水) 16:36:31.23
>>792
別に難しくないけど、
CGIによってどういうパラメータ渡せばいいかが違うから
「こうやればいい」なんて簡単には言えない。
だから一般的なscpとかFTPとかを勧められる。

795 :名無しさん@お腹いっぱい。:2011/11/16(水) 16:38:09.86
>>788
何個が一般的ってのは特にないと思う。

796 :名無しさん@お腹いっぱい。:2011/11/16(水) 16:42:22.89
まーそろそろ誰か教えてやれよw
スクリプトを自作するつってる時点でパラメータも糞もないだろw

>>793
>>792

797 :名無しさん@お腹いっぱい。:2011/11/16(水) 16:43:58.44
「自作する」とは言ってないような。

798 :名無しさん@お腹いっぱい。:2011/11/16(水) 16:43:59.65
>>796
お前がな

799 :797:2011/11/16(水) 16:44:47.05
あ、CGIのスクリプトじゃなくアップロード側のスクリプトか。
だとしてもパラメータは関係あるじゃん。

800 :名無しさん@お腹いっぱい。:2011/11/16(水) 16:47:07.01
試してはいないが、CGI側が
<form method=POST>
<input type=file name=file>
<input type=submit>
みたいなフォームを処理できる場合
>>781の-Fで十分な気もするが。

801 :名無しさん@お腹いっぱい。:2011/11/16(水) 17:25:18.21
> "file=@$1;filename=$(basename $1)"
まさにこれがパラメータだよなぁ。

>>797
796じゃないが、対偶は常に成立するから「既存」じゃなくて
新たに作るのは事実だろう。「自」作かどうかは知らん。

>>792
問題はそもそも「417 Expectation Failed」なんだから、
Expectヘッダを上書きしてやりゃいいんじゃないの?

802 :792:2011/11/16(水) 17:38:35.43
>>801

up()
{
curl -H "Expect:" -F "file=@$1;filename=$(basename $1)" -X POST http://www.example.com/upload.cgi
}
up manko.jpg

Expectヘッダを空指定で上書きしたらいけました。ありがとうございます。
(´;ω;`)


803 :名無しさん@お腹いっぱい。:2011/11/16(水) 18:54:26.54
ユーザーのパスワードを一括で変更したいです
linuxのようにchpasswdみたいなのでリストから読み込むのを想定していますが、soiarisなので出来ません。
追加でツールを入れるのはNGです
出来れば、シェルスクリプトを叩いただけでアカウントリストを元にパスワードポリシーに沿ったパスワードを自動生成し変更してくれるのを想定しています。
ただし何度も言いますが追加でツールを入れるのはNGです。

誰か知恵をかして下さい




804 :名無しさん@お腹いっぱい。:2011/11/16(水) 18:59:51.53
perlか何かで書いちゃえば?

805 :名無しさん@お腹いっぱい。:2011/11/16(水) 19:05:16.46
>>804
出来ればbashでお願いしたい

806 :名無しさん@お腹いっぱい。:2011/11/16(水) 19:56:12.23
TeraTermでマクロ書いてガシガシ通したって記事ならある

807 :名無しさん@お腹いっぱい。:2011/11/16(水) 20:00:07.77
expectくらい入れさせてもらえよ

808 :名無しさん@お腹いっぱい。:2011/11/16(水) 20:01:24.92
適当なLinux上でchpasswdでpasswdファイルを作成後、
ファイルをsolarisに転送してsolarisのpasswdとマージしろ。

809 :名無しさん@お腹いっぱい。:2011/11/16(水) 20:14:38.81
>>803
Solarisでもバージョンによって入ってるツールに差異があるし
システム側で要求される仕組みも若干違うぜ。
9までか、10か11か、10ならどのバージョンなのか。
まさかいまさら1.1.2や2.xあたりってことはないと思うが


810 :名無しさん@お腹いっぱい。:2011/11/16(水) 20:19:47.13
>>809
とりあえずは10でお願いします
10のどのバージョンかは見て見ないと分からないので即答は出来ませんが…

811 :名無しさん@お腹いっぱい。:2011/11/16(水) 20:25:35.06
Solarisのpasswdコマンドには、
引数でパスワードを指定できる隠しオプション(manに載ってない)が
あったような気がしないでもない。

passwd -? パスワード ユーザーネーム
みたいな形式で

812 :名無しさん@お腹いっぱい。:2011/11/17(木) 22:05:16.21
質問です。

viでプログラミングしているときに、=をそろえたい場合がありますが、何かいい方法ありますでしょうか?

----------------
aaa = 10
bbbbbbb = 11
c = 12
----------------
↑を↓のようにしたい。
----------------
aaa = 10
bbbbbbb = 11
c = 12
----------------

viでは出来ないみたいなので、シェルスクリプトで出来ないかなと考えた次第です。



813 :>>812:2011/11/17(木) 22:07:17.88
すいません、、複数の空白文字が消えたようです。。
下の例では、=がそろっているイメージを出したかったのでした。


814 :名無しさん@お腹いっぱい。:2011/11/17(木) 22:10:43.97
>>812
そういった書き方は関心しないが・・・
ttp://d.hatena.ne.jp/secondlife/20060203/1138978661
このサイトを授けてやろう

viでと書いてるけど多分vimだよね?
実際にviならなんとも言えないが・・・

815 :名無しさん@お腹いっぱい。:2011/11/17(木) 22:26:52.67
なんで vim 前提よ。

変数名なんてリファクタリングとかですぐ名前変わっちゃうので、
先頭の字下げ以外、揃えようという努力は無駄。

816 :名無しさん@お腹いっぱい。:2011/11/17(木) 22:39:39.69
vim前提なのはvi=vimとなってるのがいくつかあるから。
一般的によく使われてるFedoraやUbuntuはvi=vimだったりするし。


817 :名無しさん@お腹いっぱい。:2011/11/17(木) 23:14:36.83
ここはlinux板じゃないよ

818 :名無しさん@お腹いっぱい。:2011/11/17(木) 23:39:57.95
プログラミングというものは、もはや統合開発環境でやるものよ実際

近頃の環境でシェルスクリプト作る場合は、そういった統合開発環境で書いてビルドすりゃ
ターゲットマシンへの転送から起動からログ取得からできちゃうし、いわゆるステップ実行も
できるし、変数の評価ロジックも確認できるしと、シェルでゴニョゴニョやる以上のことが
できるものだよ
仮にターゲットマシン上でごちゃごちゃ弄っても差分は分かるし、それぞれの差分についても
取り込むかどうかの取捨選択もできる
シェルを開いて各種コマンドの実行したり、manを見たりもできるし、満足したものができたら
そのままプロダクトへのデプロイだのレポジトリへのコミットだのもできるものだよ

819 :名無しさん@お腹いっぱい。:2011/11/17(木) 23:52:02.89
話それてるな。

820 :名無しさん@お腹いっぱい。:2011/11/20(日) 01:25:01.61
>>818
スクリプトなんてプログラミングじゃないと申すか
いやまあ、人によって線引き違うから
何でも統合開発環境があるとは思わんほうがいいかと

>>812
shより、Perlとか使ったほうが楽そうだなあ
ただ、最近はイコール揃えるってあんまやらんと思うぞ

821 :名無しさん@お腹いっぱい。:2011/11/20(日) 01:49:19.07
>>818 は頭悪そう

822 :名無しさん@お腹いっぱい。:2011/11/20(日) 06:36:13.74
>>812
vimならAlignプラグインがあるけどね。
http://www.vim.org/scripts/script.php?script_id=294

823 :名無しさん@お腹いっぱい。:2011/11/20(日) 08:48:47.38
>>818
シェルスクリプトのIDEなんてあんの?
なに使ってるか教えてほしい

824 :名無しさん@お腹いっぱい。:2011/11/20(日) 18:05:30.82
あんまりかまうな。

825 :名無しさん@お腹いっぱい。:2011/11/21(月) 05:39:40.78
bashのシェルスクリプトで
cp -R -- src dest
のようにコピーしてたりするものがあるのですが
--ってどういう意図があってやるものなんですか?
単なるオプションってわけでも無さそうですし・・・

826 :名無しさん@お腹いっぱい。:2011/11/21(月) 06:49:43.47
>>825
srcが変数で、- で始まるファイルだった場合でもオプションと解釈されないように
するために -- を付けておく。

827 :名無しさん@お腹いっぱい。:2011/11/21(月) 07:06:13.35
>>825
man cp に書いてないの?

828 :名無しさん@お腹いっぱい。:2011/11/21(月) 07:22:25.34
こことかは、cpには書いてない、rmには書いてある
http://www.jp.freebsd.org/cgi/mroff.cgi?subdir=man&lc=1&cmd=&man=cp&dir=jpman-8.2.2%2Fman§=0
http://www.jp.freebsd.org/cgi/mroff.cgi?subdir=man&lc=1&cmd=&man=rm&dir=jpman-8.2.2%2Fman§=0

829 :名無しさん@お腹いっぱい。:2011/11/21(月) 08:22:48.80
man bash に書いてあるよ。

830 :名無しさん@お腹いっぱい。:2011/11/21(月) 09:03:25.40
たかだか3行のスクリプトなのですが、期待通り動いてくれません>_<

#!/bin/sh
TARGET=' -name "*.txt"'
find . $TARGET #< もしや-nameと"*.txt"が1引数とみなされてしまっている??

findの行をeval find…に変更することで期待動作にはなったのですが、
どのように記述するのが正しかったのでしょうか?

831 :名無しさん@お腹いっぱい。:2011/11/21(月) 09:18:41.49
>>830
eval find . ....

832 :名無しさん@お腹いっぱい。:2011/11/21(月) 09:28:27.46
>>830
#!/bin/sh
set -- -name '*.txt'
find . "$@"

833 :名無しさん@お腹いっぱい。:2011/11/21(月) 09:48:42.85
>>829
それは cp の -- の話じゃなく bash の -- の話だよ。

834 :名無しさん@お腹いっぱい。:2011/11/21(月) 11:34:26.28
>>827-829
レスありがとうございます。
CPのmanには>>828さんが書かれてる通り書いてありませんでした。
rmやbashには書かれてるんですね。

rmのmanでoptionの取り回しはgetoptを使っているという事が書かれており
getoptのmanを見たらなるほどって感じでした。


835 :名無しさん@お腹いっぱい。:2011/11/21(月) 11:44:19.34
>>834
一番早く回答してる >>826 はありがたくなかったのか?

836 :名無しさん@お腹いっぱい。:2011/11/21(月) 12:00:05.07
>>835
ごめんなさい>>826さんのレスを読みつつも
レスの範囲に入れ忘れてました・・・

>>826
改めて的確なレスありがとうございます。

837 :名無しさん@お腹いっぱい。:2011/11/21(月) 12:02:27.67
>>828
これ載せてもらうよう言った方がいいんじゃないの。

838 :名無しさん@お腹いっぱい。:2011/11/21(月) 13:51:11.09
>>831>>832
レスありがとうございます!
evalによる方法と"$@"による方法ですね。勉強になりました!

839 :名無しさん@お腹いっぱい。:2011/11/22(火) 21:14:07.06
ttp://www.library.city.hiroshima.jp/cgi-bin/Sopcsbrd.sh?p_mode=1
ここのCGIってシェルスクリプトなのかなぁ

840 :名無しさん@お腹いっぱい。:2011/11/22(火) 21:25:22.93
拡張子だけじゃ何とも言えないっしょ。
shやbashでのCGIは個人的には結構作ったりするけど
大規模になってくるとrubyとかpythonの方が楽なんだよな。当たり前だけど。

841 :名無しさん@お腹いっぱい。:2011/11/23(水) 20:43:58.07
市立図書館なら何でもありそうだ。1秒に1リクエストしか捌けない物すらあったんだし
CSVをgrep、awk、sedで検索、切り出し、整形してるだけかも

842 :名無しさん@お腹いっぱい。:2011/11/24(木) 15:32:51.87
たんに表示するだけみたいだし
いいんじぇね?

843 :名無しさん@お腹いっぱい。:2011/11/25(金) 14:12:30.85
みんなでアクセスしてサーバが落ちたりすると、業務妨害で逮捕されますよ。

844 :名無しさん@お腹いっぱい。:2011/11/25(金) 14:26:08.57
シェルスクリプト内で、
「telnet www.test.com 80」でtelnet接続し、
「GET /testurl」コマンドでリクエストを投げたいのですが、
どのようにしたらよろしいでしょうか?

845 :名無しさん@お腹いっぱい。:2011/11/25(金) 14:27:53.24
>>844
wget とか curl とか fetch あたり使うとか。
netcat 使うとか。
perl か何かのライブラリ使うとか。

846 :名無しさん@お腹いっぱい。:2011/11/25(金) 14:28:29.89
あ、telnet を使わなきゃいけないのか。
なら expect かなぁ。

847 :名無しさん@お腹いっぱい。:2011/11/25(金) 15:01:15.87
>>844
test.comの中の人でもこんな基本的なことも知らないんだ・・・

848 :名無しさん@お腹いっぱい。:2011/11/25(金) 16:23:11.75
select文で打ち込む数字を引数としても渡せるようにしたいのですができますか?

849 :名無しさん@お腹いっぱい。:2011/11/25(金) 19:33:39.91
つ eval

850 :名無しさん@お腹いっぱい。:2011/11/25(金) 20:25:23.25
>>847
何言ってるんだ?
>>844はwww.test.comに(通常とは異なる手段だが)アクセスをしたいと
言ってるだけだぞ?w

851 :名無しさん@お腹いっぱい。:2011/11/25(金) 23:16:19.19
test.comの中の人、日本語お上手ですね

852 :名無しさん@お腹いっぱい。:2011/11/25(金) 23:30:45.46
こんにちは。
シェルスクリプトの中で su を実行して、パスワードを自動で入力したいのですが、
それって可能でしょうか。パスワードを無しにすることはセキュリティ上できないので
いい方がないか悩んでいます。

853 :名無しさん@お腹いっぱい。:2011/11/25(金) 23:36:11.53
はい、可能です。

854 :名無しさん@お腹いっぱい。:2011/11/26(土) 00:01:05.32
>>852
visudoして設定しておくとか……

855 :名無しさん@お腹いっぱい。:2011/11/26(土) 08:41:18.71
>>844
telnetじゃないがbashならソケットも扱えたはずだから外部プログラムなしでも同じことができるはず
bashだけで頑張ればhttpdって実装できるかな?netcatやinetdを使った例ばかり見つかる

>>852
思いつく別の方法はsuで実行したいプログラムにsetuidする。オススメしないが

856 :名無しさん@お腹いっぱい。:2011/11/26(土) 12:27:24.65
>>854
>>855
ありがとうございます。
シェルスクリプトではなく、python等のスクリプト言語を使う方が良いかも?と思いました。
どちらも全くの素人ですが、勉強してみます。

857 :844:2011/11/27(日) 13:25:18.87
curlで解決できました!
エスパーな皆様ありがとうございました!

858 :名無しさん@お腹いっぱい。:2011/11/28(月) 15:46:17.07
perl -e 'print $1 if /href="(¥d¥d¥d¥d-¥d¥d¥-¥d¥d)"/'
と同じことをawkでやろうとしているのですがわかりません。
awk -e '/href="(¥d¥d¥d¥d-¥d¥d¥-¥d¥d)"/ { print ??? }'
グルーピングしたあとにそれを取り出す方法を探したのですが、わかりませんでした。
awkまたはsedでのやり方を教えて下さい。



859 :名無しさん@お腹いっぱい。:2011/11/28(月) 15:53:57.88
>>858
awk ファンクラブ
http://hibari.2ch.net/test/read.cgi/linux/1215431118/

860 :名無しさん@お腹いっぱい。:2011/11/28(月) 19:47:08.90
>>859
そっちできいてみます。

861 :名無しさん@お腹いっぱい。:2011/11/28(月) 20:39:18.82
>>855
シェルスクリプトってsetuid無視されるシステムの方が多いんじゃね?

862 :名無しさん@お腹いっぱい。:2011/11/28(月) 20:42:13.82
環境変数PS1辺りを無視して、
実行される環境の方が多数派かと。

863 :名無しさん@お腹いっぱい。:2011/11/28(月) 21:18:14.33
>>862
お前は何を言ってるんだ?

864 :名無しさん@お腹いっぱい。:2011/11/28(月) 21:32:46.97
IFSと間違えたw

865 :名無しさん@お腹いっぱい。:2011/11/28(月) 23:10:34.82
>>861
ラッパー作ってsystemで呼べばいい

866 :名無しさん@お腹いっぱい。:2011/11/29(火) 00:30:21.12
>>865
とんだセキュリティホールになりそうだなw

867 :名無しさん@お腹いっぱい。:2011/11/29(火) 07:21:05.92
>>865
system(3)のことなら、
system(3)は sh -c 'コマンド' の形で外部コマンドを呼び出すので、
shを通している時点で setuidビットはshによって無効化される。

だから、やるならexeclpあたりだな。戻る必要はないのでforkは不要。

868 :名無しさん@お腹いっぱい。:2011/11/29(火) 11:51:43.00
どのシステムならそんな挙動するんだよ…余分なプロセス生成を減らすためにexec系を使うのは分かるが

869 :名無しさん@お腹いっぱい。:2011/11/29(火) 12:07:48.71
>>868
/bin/sh -c を経由するのはどのOSでも同じだよ。

870 :名無しさん@お腹いっぱい。:2011/11/29(火) 12:21:22.53
>>867
スクリプトの方じゃなくてラッパーの方を setuid するんだよ。
スクリプトを setuid すると、system(3) じゃなくてexec系の関数を使ったとしても
先頭に #! と書いてある時点で結局 setuid は効かない。
ラッパーの方を setuid しても効かない環境があるなら教えてほしい。

# cat id.sh
#!/bin/sh
/usr/bin/id -un
# cat hoge.c
#include <stdlib.h>
main(){
system("./id.sh");
}
# gcc hoge.c
# chown nobody a.out
# chmod u+s a.out

$ ./a.out
nobody

とはいえ、system() ではなく exec 系関数を使った方がいいというのはそのとおり。
system() は引数に含まれる sh の記号を解釈してしまうので、
`...` のような文字列が system() に渡ってしまうと>>866が言うように穴になる。


871 :名無しさん@お腹いっぱい。:2011/11/29(火) 12:26:10.37
>>870
ラッパーの方を setuid するのはわかってるよw

そのラッパーから system()を呼ぶと、
system()ライブラリ内部で /bin/sh -c '....' が実行されるので、
この /bin/sh が setuid を無効にする。

よってラッパーは意図通りに動かない。(動作確認済み)

もし動くとしたらそれは setuid を無効にしないタイプの /bin/shなので、
それだったらそもそもラッパーを使わずにシェルスクリプト自体を setuidしても
動くはず。

いずれにしてもラッパーの意味がないことがわかったかな?w

872 :名無しさん@お腹いっぱい。:2011/11/29(火) 12:29:54.84
>>870 をコピペして実行しても nobody にならなかったよ

873 :名無しさん@お腹いっぱい。:2011/11/29(火) 12:40:40.21
FreeBSD と Debian で試したがちゃんと nobody になるぞ。

…とふと思いついて、ラッパーを
system("/bin/bash ./id.sh");
に変えてみたら確かに nobody にならないな。
bash の勝手仕様か。


874 :名無しさん@お腹いっぱい。:2011/11/29(火) 12:52:09.04
ash, dash, ksh93, pdksh, zsh いずれも nobody になる。
おかしいのは bash だけか。


875 :名無しさん@お腹いっぱい。:2011/11/29(火) 13:21:28.74
ほらbashなんか使ってるからww

876 :名無しさん@お腹いっぱい。:2011/11/29(火) 13:26:12.46
検証してる所を見つけた
ttp://stackoverflow.com/questions/556194/calling-a-script-from-a-setuid-root-c-program-script-does-not-run-as-root
bashだけが特殊で、>>871は勘違いしているみたいだが一般のshはそんな挙動はしない
Debianのbashはshで起動した時にはsetuidを引き継ぐパッチが当たっている

877 :名無しさん@お腹いっぱい。:2011/11/29(火) 13:39:33.77
一応>>867=>>871として、その名誉のために補足するとman systemやman bashにexec使えって書いてあるってよ
ttp://stackoverflow.com/questions/1051370/why-do-i-need-setuid0-within-a-setuid-root-c-program-that-calls-an-administrat

878 :名無しさん@お腹いっぱい。:2011/11/29(火) 13:42:37.06
ごめん。補足したつもりがexeclpは使うなって書いてあったわ

879 :名無しさん@お腹いっぱい。:2011/11/29(火) 13:55:27.06
UNIX使いの心得に excelは使うなって書いてあったよ

880 :名無しさん@お腹いっぱい。:2011/11/29(火) 15:02:24.21
>>871 の勘違いをもうひとつ正しておく。

>もし動くとしたらそれは setuid を無効にしないタイプの /bin/shなので、
>それだったらそもそもラッパーを使わずにシェルスクリプト自体を setuidしても
>動くはず。

動かない。
setuid スクリプトの実行を禁止しているのは sh ではなくカーネル。
なので、sh だけでなく、perl やら ruby やらその他もろもろのスクリプト言語全般で
setuid されたものは動作せず、どうしてもやりたいならラッパーを書く必要がある。
# perl はビルドのときのオプションで suidperl という専用ラッパーも
# いっしょにコンパイルできる。


881 :名無しさん@お腹いっぱい。:2011/11/29(火) 21:50:53.83
珍しくないようがあるようだ

882 :名無しさん@お腹いっぱい。:2011/11/29(火) 21:57:53.87
bash使いはバカといういつもの結論のどこに内容があるのだ?

883 :名無しさん@お腹いっぱい。:2011/11/30(水) 00:07:23.52
内容が

884 :名無しさん@お腹いっぱい。:2011/11/30(水) 00:46:23.13
shに拘ってるのはこの板だけだよ

885 :名無しさん@お腹いっぱい。:2011/11/30(水) 01:02:43.17
それでいいじゃない

886 :名無しさん@お腹いっぱい。:2011/11/30(水) 02:07:10.67
sh (BusyBox, ash)
dash (Debian, ash)
sh (FreeBSD, ash)

どれが一番素のshに近いの?

887 :名無しさん@お腹いっぱい。:2011/11/30(水) 02:20:50.99
>>886
個人的な感覚的に、一番近いのはFreeBSDのsh

だがそれでも、shから拡張されてる

xmkmf厨目指してるんでもないかぎり、shとの互換性は、もういいんじゃね?
俺はもう、#! /bin/kshばっかだわ

888 :名無しさん@お腹いっぱい。:2011/12/01(木) 12:46:34.07
普段使いの環境で動いて、互換性そこそこいけるのを選べばいいと思う
FreeBSDなら最初からあるashだろし
Busybox使われてるならそれのashだろうし
Debian系Linuxにらdashかと

それ以外の環境ならdashが比較的導入しやすいか?
OSXとかでも動くし、互換性のためにBusybox…てのは違和感がw

889 :名無しさん@お腹いっぱい。:2011/12/01(木) 15:45:00.08
>>886
>>1にある通り、OpenSolarisのheirloom shが一番v7 shに近い。
ash系はどれも大差ない。

890 :sage:2011/12/01(木) 16:59:14.89
質問があるんですが現在あるシェルスクリプトをprocmailから動かそうと思っています。
シェルスクリプトはすでにできあがっていてターミナルに直接sh test.shと打ち込むとちゃんと
動作するのですがprocmailから動かそうとするとうまく動作しません。
どんな原因が考えられるでしょうか?

891 :sage:2011/12/01(木) 17:00:35.73
質問があるんですが現在あるシェルスクリプトをprocmailから動かそうと思っています。
シェルスクリプトはすでにできあがっていてターミナルに直接sh test.shと打ち込むとちゃんと
動作するのですがprocmailから動かそうとするとうまく動作しません。
どんな原因が考えられるでしょうか?

892 :名無しさん@お腹いっぱい。:2011/12/01(木) 17:02:18.71
>>890
スクリプト自体の書き方の話じゃないから
こっちで聞いた方がいいんじゃね。

Internet Mail System 総合スレ 3
http://hibari.2ch.net/test/read.cgi/unix/1128256415/

893 :sage:2011/12/01(木) 17:18:44.60
>>892
ありがとうございます。
そっちで聞いてみます。

894 :名無しさん@お腹いっぱい。:2011/12/01(木) 17:37:56.91
エスパーがいればいいな

895 :名無しさん@お腹いっぱい。:2011/12/01(木) 18:32:44.70
PATHが違う

896 :名無しさん@お腹いっぱい。:2011/12/01(木) 18:37:09.18
もう>>892に移動したみたいよ。

897 :名無しさん@お腹いっぱい。:2011/12/01(木) 19:07:09.89
わざわざ追っかけて行って答える気などない。

898 :名無しさん@お腹いっぱい。:2011/12/01(木) 22:19:42.22
ならここでも答えなくていいよ。

899 :名無しさん@お腹いっぱい。:2011/12/03(土) 00:25:02.07
質問させてください。
先日からシェルスクリプトの勉強を始めたのですが、
取得した引数をもとにif文のORで条件分岐を行おうとした際、うまくいきません。

以下がソースコードになりますが、どのようなコーディングを行えばよいか教えてください;;

#!/bin/sh
if test ${1} ; then
#第1引数が"str1"または"str2"以外の時はメッセージ("hoge")を表示する
if test [ "${1}" != "str1" -o "${1}" != "str2" ] ; then
echo "hoge"
fi
else
#第1引数がnullの時はメッセージ("foo")を表示する
echo "foo"
fi

900 :名無しさん@お腹いっぱい。:2011/12/03(土) 00:41:31.42
>>899
机上ですまが、まずは、4行目のtestを取ったらうまくいくかね

で、同じくそこのOR条件なんだが、str1だろうがstr2だろうが何だろうが何か設定されてりゃ
常に真になっちまいそうだな

901 :名無しさん@お腹いっぱい。:2011/12/03(土) 00:43:38.72
#!/bin/sh
if test -n "${1}" ; then
#第1引数が"str1"または"str2"以外の時はメッセージ("hoge")を表示する
if [ "${1}" != "str1" -a "${1}" != "str2" ] ; then
echo "hoge"
fi
else
#第1引数がnullの時はメッセージ("foo")を表示する
echo "foo"
fi

902 :名無しさん@お腹いっぱい。:2011/12/03(土) 00:44:14.17
case使っちゃダメなの?

903 :名無しさん@お腹いっぱい。:2011/12/03(土) 00:51:31.05
勉強だからどっちも勉強すればいいんじゃないの?

904 :名無しさん@お腹いっぱい。:2011/12/03(土) 01:06:55.60
ド・モルガンの法則って高校の時にやんなかったけ?

905 :名無しさん@お腹いっぱい。:2011/12/03(土) 01:13:57.67
日本語だと「または」と「以外」は「または」のほうが結合が強い、でいいよね。

906 :名無しさん@お腹いっぱい。:2011/12/03(土) 01:49:25.13
>>904
ゆとり最盛期は範囲外だったかも

907 :名無しさん@お腹いっぱい。:2011/12/03(土) 07:17:36.26
同級生が高校生だった頃、俺は建築現場で働いて夜はスナックで飲んでた。

908 :名無しさん@お腹いっぱい。:2011/12/03(土) 08:57:13.30
>>906 の言うとおり、ゆとり高校ではド・モルガンは教えない。
大学でデジタル回路でブール代数やる時に、ド・モルガンから教えなければ
ならないらしい。

909 :名無しさん@お腹いっぱい。:2011/12/03(土) 10:18:51.95
>>888
HP-UX、AIXは、POSIXシェル(実体はほとんどksh)

910 :名無しさん@お腹いっぱい。:2011/12/03(土) 17:15:32.40
>>907
わっかるかなー、わっかんねぇーだろなー♪

911 :名無しさん@お腹いっぱい。:2011/12/03(土) 22:40:21.19
フォルダ毎にzip圧縮してzipにフォルダの名前をつけるにはどうすりゃいい?

912 :名無しさん@お腹いっぱい。:2011/12/03(土) 23:00:29.41
フォルダ毎にzip圧縮してzipにフォルダの名前をつけるようなスクリプトでも組め

913 :名無しさん@お腹いっぱい。:2011/12/03(土) 23:07:50.95
>>912
なるほどー、そんな方法があったんですね。目から鱗です。ありがとうございました!!

914 :名無しさん@お腹いっぱい。:2011/12/03(土) 23:08:58.25
for d in .[^.]* ..?* *; do test -d "$d" && zip -r "$d.zip" "$d"; done

915 :名無しさん@お腹いっぱい。:2011/12/04(日) 17:17:50.60
>>914
ありがと。
すごい馬鹿なことを聞くけど
.[^.]* ..?* *
の意味がわからない。
パス名に見えるけど"/"がない。
OSによる差?
ちなみにUbuntu9.04です。


916 :名無しさん@お腹いっぱい。:2011/12/04(日) 17:20:29.85
>>915
正規表現

917 :名無しさん@お腹いっぱい。:2011/12/04(日) 17:32:17.08
いいえ、Pattern Matching Notationです。
http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13

918 :名無しさん@お腹いっぱい。:2011/12/04(日) 17:48:50.29
globって言った方が伝わり易いんじゃね

919 :名無しさん@お腹いっぱい。:2011/12/04(日) 18:08:46.97
man 7 glob かな?


920 :915:2011/12/04(日) 18:17:19.52
いろいろありがとう。
globについてはよくわからないけど、
やろうと思っていたことはできそうだ。
ちなみに、シェルスクリプトに書かなくても
ターミナルの上で実行できるのは少々驚いた。

921 :名無しさん@お腹いっぱい。:2011/12/04(日) 18:19:35.63
ちょっと不安に思ったら端末でユニットテストですよ。

922 :名無しさん@お腹いっぱい。:2011/12/05(月) 22:01:50.15
質問です。

あるプログラムファイルのある関数だけ、sedで変数の置き換えをしたいのですが、
そのような場合、どうすればいいのでしょうか?


言語はphpです。プログラムファイルはたとえば以下のようなかんじです。
-----------------------
function aaa() {
}
function bbb() {
  $hoge = "";
  $foo = $hoge;
  $bar = $hoge;
}
function ccc() {
}
---------------------
この中でbbb関数のhoge、foo、barという変数をぞれぞれ、$_hoge、$_foo、$_barという名前に置き換えたいです。
よろしくご教示お願いします。


923 :名無しさん@お腹いっぱい。:2011/12/05(月) 22:40:21.52
sed '/^function bbb() {$/,/^}$/s/$\([a-z]\+\)/$_\1/g'

924 :名無しさん@お腹いっぱい。:2011/12/05(月) 22:59:20.70
>>899です。
レスが遅くなって申し訳ありません。

>>900-905さん有難うございます!
おかげで解決出来ました。

こんな質問してしまい、お恥ずかしい限りです・・・。
シェル始めたばかりなので、いろいろ試しながら勉強していきたいと思います。

有難うございました。

925 :名無しさん@お腹いっぱい。:2011/12/06(火) 20:59:50.18
execについて質問させてください。
次のようなスクリプトbazを書きました。

#!/bin/sh
switch=yes
if [ "$switch" = "yes" ]; then
 exec tac "$@" | cat -n | tac
fi
exec cat -n "$@"

このスクリプトを
cat file | baz
のように適当なファイルを対象にパイプで実行した場合は最初のexecしか実行されないのに、
ファイルを直接引数にして
baz file
のように実行すると、最初と次のexecが両方実行されてしまいます。
これはどうしてなんでしょう?

926 :名無しさん@お腹いっぱい。:2011/12/06(火) 21:35:42.72
>>925
結論からいうと、どちらの場合でも最初と次のexecが両方実行されている。

execの後をパイプでつなぐと、パイプ全体がサブシェルになるため、
execは意味をなさず、execなしで普通に実行したのと同じになる。
そのため、if文の次のexecのコマンドのところまで実行されてしまう。

cat file | baz の場合、標準入力がパイプのため、
1回目の execのところで標準入力がEOFになり、
2回目の execのところではコマンドは起動されるけど
EOFなのでそのまま何模せずに終了して、
1回目しか実行されていないように見えるだけ。

927 :>>922:2011/12/06(火) 21:45:53.55
>>923
ありがとうございます

928 :名無しさん@お腹いっぱい。:2011/12/07(水) 00:37:24.68
grepのwオプションや、egrepの\bみたいな単語を指定する方法は、sedにはないですか?


929 :名無しさん@お腹いっぱい。:2011/12/07(水) 00:50:31.31
どのsed?

930 :925:2011/12/07(水) 11:44:41.50
>>926
パイプでつないだコマンドをexecしても意味ないのかなくらいまでは思ったのですが、
なるほど、とてもよくわかりました。すごく勉強になります。ありがとうございました!

931 :>>928:2011/12/07(水) 23:24:39.62
>>929
freebsdのsedです。
manのhistoryでは以下のようにかいてました
A sed command, written by L. E. McMahon, appeared in Version 7 AT&T UNIX.


932 :名無しさん@お腹いっぱい。:2011/12/07(水) 23:46:43.23
-Eつけたら使えるんじゃない?多分


933 :名無しさん@お腹いっぱい。:2011/12/08(木) 00:08:56.20
[[:<:]]と[[:>:]]ではさむ。
man re_format

934 :名無しさん@お腹いっぱい。:2011/12/08(木) 21:24:33.01
ヒヤドキュメントをワンタイマーで書けないんでしょうか?
初心者シェラーですいません

935 :名無しさん@お腹いっぱい。:2011/12/08(木) 21:55:36.72
ワンタイマーってなんだよ。

936 :名無しさん@お腹いっぱい。:2011/12/08(木) 22:03:19.92
シェラーもな

937 :名無しさん@お腹いっぱい。:2011/12/08(木) 22:32:36.71
つっこんだら負け。

938 :名無しさん@お腹いっぱい。:2011/12/09(金) 00:10:56.90
>>936
教えてあげるざます
熱狂的なミーのファンざます!シェー!

939 :名無しさん@お腹いっぱい。:2011/12/09(金) 02:27:08.30
シェリストじゃないの?

940 :名無しさん@お腹いっぱい。:2011/12/09(金) 02:41:37.55
チャロに出てたハーフの娘?
最近よくバラエティに出てるよね

941 :名無しさん@お腹いっぱい。:2011/12/09(金) 18:32:29.45
ワンタイマーはシェラーの基本だと聞いたのですが、
冷やドキュメントには対応していないんでしょうか?

942 :名無しさん@お腹いっぱい。:2011/12/09(金) 21:43:50.73
シェルラーじゃね?

943 :名無しさん@お腹いっぱい。:2011/12/09(金) 21:49:41.96
シェルスクリプター

944 :名無しさん@お腹いっぱい。:2011/12/10(土) 01:31:36.35
シェルスクリプティストだろ

945 :名無しさん@お腹いっぱい。:2011/12/10(土) 01:36:21.71
シェルスクリプタリストが
シュラシュシュシュー

946 :名無しさん@お腹いっぱい。:2011/12/10(土) 03:09:32.72
こんなスクリプトあったら、どうやって書き直しますか・・・

#!/bin/sh
# params
CSV="no"
EXEC_OPTS="-f1"
TARGET=${TARGET:-"/var/tmp/test"}

# functions
process_args ()
{
if [ "${1}" = "yes" ]; then
CSV="yes"
fi
}

exec_cut ()
{
if [ "${CSV}" = yes ]; then
EXEC_OPTS="-d, ${EXEC_OPTS}"
fi

cut ${EXEC_OPTS} ${TARGET}
}

# main
process_args
exec_cut

947 :名無しさん@お腹いっぱい。:2011/12/10(土) 03:26:46.58
俺ならvimを使って書き直すな。

948 :名無しさん@お腹いっぱい。:2011/12/10(土) 03:30:24.96
>>946
わざわざ関数にしてるってことは、書いてるモノのほかに hogehoge する部分があるんだろうけど…

#!/bin/sh
EXEC_OPTS=""
TARGET=${TARGET:-"/var/tmp/test"}
[ "${1}" = "yes" ] && EXEC_OPTS="-d, "
cut ${EXEC_OPTS} -f1 ${TARGET}

本気でそれだけだったらこう書き直すかも。
僕のアタマだと TARGET に入れてる内容も理解しきれない。
CSV に no を入れる理由がよくわかってないし( no であることを case とかでチェックしないなら何でもいいじゃん)、
関数で全部済ます理由もわかんない。

>>947
間違いない。

949 :名無しさん@お腹いっぱい。:2011/12/10(土) 03:45:31.51
こんな不自然なスクリプト見ると、例によって学校の課題で出された問題だと邪推してしまうな。
例えば
>>946に機能を追加して ./hoobar.sh 6
とか引数を追加することによってCSVの6番目の要素を列挙できるようにせよ」
とかな。

950 :名無しさん@お腹いっぱい。:2011/12/10(土) 04:35:09.82
冷やしドキュメントをラーメンタイマーで書けないんでしょうか?
初心者シェラー始めました♪

by Amemiya

951 :名無しさん@お腹いっぱい。:2011/12/10(土) 05:56:59.44
csvは扱いが面倒だよね。
"1,000","2,000",,,
なんてのがあるからね。

952 :名無しさん@お腹いっぱい。:2011/12/10(土) 07:57:45.11
gawkのexampleにあったな。gawk限定だが
というかちょっとしたデータベースもどきにCSVは使うけど
やっぱりシェルスクリプトでもSQL使った方がいいのか?
別にSQLでなくてもいいけど、SQLiteくらいしか思いつかない

953 :名無しさん@お腹いっぱい。:2011/12/10(土) 09:10:35.73
>>952
シェルスクリプトで、ってんなら
cutやawkで使える形式がいいなー
何にしろcsvよりは空白区切りでやると思う

954 :名無しさん@お腹いっぱい。:2011/12/10(土) 09:33:06.82
csvならexcelに食わせろよ。色々と捗るぞ。

955 :名無しさん@お腹いっぱい。:2011/12/10(土) 09:50:18.17
中級者シェラーによくある無駄

(1)空文字列の代入に無駄なクォート
HOGE="" → HOGE= だけで桶

(2)変数展開等がないのにダブルクォート
HOGE="hage boke" → HOGE='hage boke' シングルクォートで桶

(3)変数の条件展開等がないのにブレース
hoge "${var}" → hoge "$var" で桶

956 :名無しさん@お腹いっぱい。:2011/12/10(土) 11:53:49.05
シエラって何かあったよな?
なんだっけ、ブラウザだったかな……。

957 :名無しさん@お腹いっぱい。:2011/12/10(土) 12:20:37.97
>>952
CSVなら他のスクリプト言語使う。
大抵読み込みライブラリあるから。

958 :名無しさん@お腹いっぱい。:2011/12/10(土) 13:58:15.94
>>955
(3) は、もしかして
hoge "${var}boo"
と後で変更するかもと考えると悪くないと思う。

959 :名無しさん@お腹いっぱい。:2011/12/10(土) 14:18:43.32
>>958
そう変更するなら

hoge "${var}"boo

とするべきで、だったら

hoge "$var"boo

とした方がいいので、やはり { } は無駄。

960 :名無しさん@お腹いっぱい。:2011/12/10(土) 14:24:49.13
diff -q ${var}{_old,} || ...
とかふつうに { } 使わない?
で、こういうとこだけ { } 使ってるのやだから、全部 ${var} にしとこ、とか?
まあ、元のスクリプトの使い方が単純なケースだから、{ } 不要じゃねと言われればそれまでだけど

961 :名無しさん@お腹いっぱい。:2011/12/10(土) 14:45:58.29
無駄とかそういう理由で省略するもんじゃないから。

962 :名無しさん@お腹いっぱい。:2011/12/10(土) 15:01:05.57
>>960
それは

diff -q "$var"{_old,} || ...

だな。${var}だと、varの中身にスペースがあった時に誤動作するから。

963 :名無しさん@お腹いっぱい。:2011/12/10(土) 15:04:52.03
{}が要る場所とか要らない場所とか考えるの面倒だから俺は全部省略せずに${hoo} って書くことにしてる
${hoo}って変数名を${bar}に一括置換したくなった時にも便利だしね。

964 :名無しさん@お腹いっぱい。:2011/12/10(土) 15:08:23.35
>>963
だったら全部 "$hoo" って書けば良い。タイプ数は同じ。
"$hoo" って変数名を "$bar" に一括置換するのも同じこと。

問題なのは、${hoo} って書いて、それがスペースを含んでいた場合に誤動作する
ということを知らないで書いている人。
{ } で囲んでもスペース問題は解決しない。
。囲む時はダブルクォートを徹底すること。

965 :名無しさん@お腹いっぱい。:2011/12/10(土) 15:42:50.52
なんでそんなに${hoo}の表記法を憎むのか理解出来ない。
もしかしてソースに${hoo}って書いたせいで親が殺されたり恋人に振られたりした経験でもあるのか?

966 :948:2011/12/10(土) 16:28:58.88
>>955
中級者に格上げありがとう。

正直 EXEC_OPTS="" 自体も要らないんだけど、Excel マクロとかも使ってて
クセになってるんですよね。気をつけます。

TARGET の中身に入れてる内容がどういう意味なのか説明していただけると、
とてもうれしいです。初心者を自覚してたのでわかりません…

967 :名無しさん@お腹いっぱい。:2011/12/10(土) 16:35:27.61
>>966
この辺を読めば分かるかも
http://jaduks.livejournal.com/7934.html
http://tldp.org/LDP/abs/html/parameter-substitution.html

968 :名無しさん@お腹いっぱい。:2011/12/10(土) 16:43:21.45
>>967
ありがとう。

TARGET=${TARGET:-"/var/tmp/test"}

TARGET の中で、未定義の $TARGET が展開されてる理由は
たぶんシェルスクリプト実行前に環境変数へ入れてるんだろうな〜
というのだけは分りました。


969 :名無しさん@お腹いっぱい。:2011/12/10(土) 17:04:30.12
俺も${var}はできるだけ使わない派だけど、
{}使ってるスクリプト見ても無駄だから省略しろとは思わない。

970 :名無しさん@お腹いっぱい。:2011/12/10(土) 17:17:29.57
>>968
TARGET=${TARGET:-"/var/tmp/test"}

よりも、

: ${TARGET:=/var/tmp/test}

の方がいい。

971 :名無しさん@お腹いっぱい。:2011/12/10(土) 19:28:05.23
>>959
boo などが引用符に囲まれてないと、ちょっといやだ。

自分は * や ~ などパターンマッチをしたいときだけ引用符なし、
それ以外は基本引用符で囲むことにしてる。

972 :名無しさん@お腹いっぱい。:2011/12/10(土) 19:31:53.87
シェルスクリプトのパイプの受け取り方わかんない(´・ω・`)

Path通してコマンド化しようとしてる2つのシェルスクリプトA,B。
例だからNRで1行でできるとかは、なんせんすな

A:Gen (file名).dat なんか適当な数字を発生させる 
B:Ave (file名).dat 平均を求める

B:
#Average of Time-series

#Ave ***.dat
line=`wc -l $1 | awk '{print $1}'` ←行数読む

awk '{a+=$1/'$line'}END{print a}' $1 ←平均出す

たとえばAで発生させた数字列をパイプで Gen (file名).dat | Ave で
つないで平均もとめようとするとと空出力。Ave単体だとちゃんと動く。

大規模計算だからできればawk使いたい。おじさんたちたすけて。

973 :名無しさん@お腹いっぱい。:2011/12/10(土) 20:15:28.22
何を聞きたいのか全然わからない。一見日本語のようだが日本語と異なる言語のようだ。

974 :名無しさん@お腹いっぱい。:2011/12/10(土) 20:22:05.58
>>973
Aveがこの内容だとパイプ受け取れない(´・ω・`)
どうすればいいですか?



975 :名無しさん@お腹いっぱい。:2011/12/10(土) 20:29:03.68
>>972 awk スレで聞いたほうがいいんじゃ?

とりあえず次スレ。
http://hibari.2ch.net/test/read.cgi/unix/1323515200/

976 :名無しさん@お腹いっぱい。:2011/12/10(土) 20:35:47.78
awkスレ以前だろ。引数でファイル渡すようにスクリプト書いてるのに
それにパイプでデータを渡したいって話だろ?書き直せ

977 :名無しさん@お腹いっぱい。:2011/12/10(土) 20:39:23.91
/dev/stdin w

978 :名無しさん@お腹いっぱい。:2011/12/10(土) 20:52:55.03
スクリプトの中で標準入力の内容を何度も処理したい場合は、とりあえず
cat > $tmpfile
しておく。んでもって
line=`wc -l < $tmpfile`
awk ... $tmpfile
とかかしらん。
ファイルも引数に取れるようにするには、最初の部分を
cat "$@" > $tmpfile
にしておけばいいし

979 :名無しさん@お腹いっぱい。:2011/12/10(土) 21:00:49.19
ファイルに出力するのと標準出力に出力するのは別だってのを
理解していないように思えるが?

#!/bin/sh
# --- GEN.sh version 2.0 ---
OF=$1
if [ "$OF" = "" ] ; then OF=rand.txt ; fi

echo 10 > $OF
echo 20 > $OF
echo 30 > $OF
echo 40 > $OF

echo 100
echo 200
echo 600

exit 0


980 :名無しさん@お腹いっぱい。:2011/12/10(土) 21:06:38.43
>>980 なら次スレ行ってみます。


981 :名無しさん@お腹いっぱい。:2011/12/10(土) 21:10:23.67
すまん、重複してしまった...
削除依頼出してきます。


982 :名無しさん@お腹いっぱい。:2011/12/10(土) 21:29:33.51
>>979
if [ "$OF" = "" ] ; then OF=rand.txt ; fi

無駄

: ${OF:=rand.txt}

983 :名無しさん@お腹いっぱい。:2011/12/10(土) 21:39:07.89
独りよがりもいい加減にしとけ。な。

984 :名無しさん@お腹いっぱい。:2011/12/10(土) 21:52:42.52
>>979

if [ "$OF" = "" ] は無駄だな。ifで書くとしても、
せめて if [ -z "$OF" ] だな。

985 :名無しさん@お腹いっぱい。:2011/12/10(土) 22:02:04.40
しつこいねぇ。
$ fgrep -1 ' = ""' /usr/bin/xmkmf

if [ "$topdir" = "" ]; then
args="-DUseInstalled "$configdirspec
$ head -n 7 /usr/bin/xmkmf
#!/bin/sh

# $XFree86: xc/config/util/xmkmf.cpp,v 1.3 2000/11/06 21:57:10 dawes Exp $
#
# make a Makefile from an Imakefile from inside or outside the sources
#
# $Xorg: xmkmf.cpp,v 1.3 2000/08/17 19:41:53 cpqbld Exp $

986 :名無しさん@お腹いっぱい。:2011/12/10(土) 22:04:20.48
>>985
Xの付属のシェルスクって無駄な書き方多いよ。
全然参考にならないし、その例挙げても反証にならない。

987 :名無しさん@お腹いっぱい。:2011/12/10(土) 22:13:36.04
>>978のやりかたでできた。
ありがとうございました。


988 :名無しさん@お腹いっぱい。:2011/12/10(土) 22:31:22.50
-z って、どっちだっけってわからなくなるんだよね。
だから自分はいつも
if [ "$args" = "" ]; then
って書くよ。-n もあるしね(-zと-nはどっちがどっちだっけってなる)。

989 :名無しさん@お腹いっぱい。:2011/12/10(土) 22:35:36.88
>>988
シェルによっては、
if [ "$arg" = "" ];
という書き方だと argが -f とかの特殊な値だと誤動作するんだよ。
だから、if [ X"$arg" = X ]; みたいなバッドノウハウもあった。

それを避ける意味でも if [ -z "$arg" ] の方が良い。

990 :名無しさん@お腹いっぱい。:2011/12/11(日) 03:24:48.74
-z とか -n ってどういう意味なん
毎回覚えられなくて調べるんだけど

991 :名無しさん@お腹いっぱい。:2011/12/11(日) 03:59:41.24
>>990
$ man test

992 :名無しさん@お腹いっぱい。:2011/12/11(日) 08:33:08.10
zeroとnonzero
これが覚えられないなら頭を使う仕事はやめた方がいい。

993 :名無しさん@お腹いっぱい。:2011/12/11(日) 11:21:55.47
ああ一番肝心なの調べてなかったのかthx
覚えられないのは普段使わないからだよ

994 :名無しさん@お腹いっぱい。:2011/12/11(日) 11:44:00.77
こんな覚えやすいのに…

995 :名無しさん@お腹いっぱい。:2011/12/11(日) 11:48:46.85
-s "$var" もあるから紛らわしいんだよね。
その場でちょこっとスクリプト書いてささっと作業済ませたいときにmanとかかったるい

996 :名無しさん@お腹いっぱい。:2011/12/11(日) 13:22:04.62
>>993
頭は普段から使うようにした方がいいぞ。

997 :名無しさん@お腹いっぱい。:2011/12/11(日) 13:34:44.99
ブロック壊したり、アイテム出したりするのにいつも頭を使っているから、凄く頭はいいと思うんだが
なぜか毎回姫を攫われてしまう。何かいいアイデアはない?

998 :名無しさん@お腹いっぱい。:2011/12/11(日) 14:40:10.86
>>992
大木金太郎やボボブラジルみたいな使い方もあるしー
君が勝てるかなあ?その頭で。

999 :名無しさん@お腹いっぱい。:2011/12/11(日) 16:27:00.77
bash で waf つくるよ

1000 :名無しさん@お腹いっぱい。:2011/12/11(日) 16:41:38.19
-z って変数が空か入ってるかぢゃ無いのかよ

1001 :1001:Over 1000 Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。

245 KB
★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)