1 :
1様 :
2009/04/03(金) 22:17:43 ID:0qFlvOW9
2 :
1様 :2009/04/03(金) 22:19:41 ID:pwv0zYsr
3 :
1様 :2009/04/03(金) 22:20:49 ID:pwv0zYsr
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(
>>1-6 くらい)をご覧ください。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
'Part4'のテンプレになってたから'その13'のテンプレも張っておいた。
8 :
login:Penguin :2009/04/04(土) 01:12:36 ID:Tp2VlfaD
どうしてこのスレは忘れられてしまったのか!?
このスレは 「シェルスクリプト総合@LINUX Part14」 です。
違うよね。 UNIX版とごっちゃになっててごめん。 Part5であってる。
(例えば)zshをシェルにしてて高度な機能とかつかっていると、"正規な"/bin/shで動かそうとした時にハマるってことだよね。 Linuxで各シェルの追加仕様とか機能とかつけずにsh相当の機能というか仕様で実行させるにはどうしたらいいの? たとえばDebianとかはbashじゃなくってdashの方がいいのかな?
>>11 heirloom-sh か UNIX 板の方へいけばいいんじゃね?
>>12 なるほど。
#/bin/sh --posix
で始めればいいってことかな?
>>13 Heiroom shってぐぐるとPOSIX標準から外れているとかなんとか。
まcsh系みたいな論外系とは違うだろうし実用問題ないくらいには書けるそうなんだけど。
./resize input_img.png output_img.png 60 のような引数を渡すプログラムに ./resize img/*.png rlt_img/*.png 60 のように、ワイルドカードでファイルを読み込み、 そのワイルドカード部のファイル名で出力したいのですが このようにするには、どのように記述すべきでしょうか?
16 :
15 :2009/04/09(木) 01:13:00 ID:fmCo0sq3
for file in *.txt do cp "$file" "$file.bak" done これで解決です、ありがとうございます
チョンプ
シェルスクリプトで小数の比較って出来ないのでしょうか if [ 1.1 -le 1.2 ];then 〜 else 〜 fi ということをやりたいんですが。
>>18 それはexprとかの外部コマンドを使わずに、ということか?
>>19 いえ、外部コマンドの有無は特に気にしていないです
test コマンドは整数にしか対応していないとのことでしたので
別の方法でもあるのかなと
echo "scale=1; 1.1 < 1.2" | bc
22 :
login:Penguin :2009/04/12(日) 16:23:36 ID:zY73Wyps
>>21 なるほど。bc コマンドでも数値の比較が出来るのですね
ありがとうございました
23 :
login:Penguin :2009/04/13(月) 17:38:44 ID:1oC+4w67
質問です。 カレントディレクトリ内のファイルの拡張子を ".m4a" から ".m4b" に 変更するスクリプトを作ろうと思いました。 #!/bin/bash for oldName in `ls *.m4a`; do newName=`echo "$oldName" | sed s/\.m4a/\.m4b/` mv "$oldName" "$newName" done しかし "ファイル 名.m4a" のようにファイル名に空白が含まれると、 "ファイル" と "名.m4a" の2つに分割して処理されてしまいました。 1つのファイルとして処理させるにはどうしたらよいでしょうか? よろしくお願いします。
24 :
23 :2009/04/13(月) 17:40:46 ID:1oC+4w67
すいません書き込みに無駄な空行がたくさん入ってしまいました
rename コマンドじゃダメ?
>>23 for name in *.m4a; do
mv "$name" "${name%.m4a}.m4b"
done
でどうでしょうか
27 :
23 :2009/04/13(月) 21:05:06 ID:jrO4FfOZ
>>25 検索したところ使えるようですね。
ありがとうございました。
>>26 うまくいきました。変数の構文も参考になります。
ありがとうございました。
IFS=""とかじゃダメなんかな
rename -v 's/\.m4a$/.m4b/' * これでいいじゃん。 スクリプトじゃないけど実態はPerlでevalしてるだけだし。
BSD 系 (FreeBSD, OpenBSD のみ)と Linux 系で動く sh で1〜100までのループを表現したいんですが、どうすればいいんでしょうか? 妥協して、bash で書いてしまうのもありなんですが、Unix like OS 標準の s hで行きたいところです また、CentOS の環境に /bin/awk は入っていたんですが、OpenBSD には、標準で入っていないんですよね あと三番目の bash バージョンは、CentOS だと #!/bin/bash --posix でも #!/bin/sh でも動いてしまうんですが、正当な sh で動かすには、どうしたらいいのでしょうか? /* c */ for(i=1; i<=100; i++){ printf("%d ",i); n} # sh with awk for i in `awk 'BEGIN { for( i=1; i<=100; i++ ) print i }'`; do echo -ne "$i " done # bash for (( i=1; i <= 100; i++ )) do echo -ne "$i " done
自己解決しました emacsテンプレートの馬鹿w command-listがまだ慣れないっすね
>>30 forにこだわらないなら
i=1
while [ $i != 101 ]; do
printf "%03d " $i
i=`expr $i \+ 1`
done
こんなんのもアリかも。
seqでforを回す人が以前いたよね。 for i in `seq 1 100`
for i in `seq 100`; do echo $i; done 俺この方法好き
35 :
login:Penguin :2009/04/18(土) 16:40:49 ID:h9pcedkY
for i in `seq -w 100`; do echo $i; done の方が好き
もまいら、なかなかうまいな
37 :
login:Penguin :2009/04/24(金) 12:57:30 ID:b7e2t/yg
trapについて教えてください ------hoge.sh---- #!/bin/bash trap '' INT sleep 1 echo hoge sleep 1 echo hoge ----------------- 上記のスクリプトを実行し、Ctrl+c を押しっぱなし にしても正常に最後までechoし終了するのですが、最後にscpをいれると固まります ------hoge.sh---- #!/bin/bash trap '' INT sleep 1 echo hoge sleep 1 echo hoge scp hostname:file1 ./file2 ----------------- これの回避方法を教えてください。
38 :
login:Penguin :2009/04/25(土) 18:13:43 ID:xpy/PYPF BE:1185862267-S★(614436)
ファイル名の一括変換なんかができたらなぁと思っています。 まいにちフランス語_4月13日放送分.mp3 → FR20090413.mp3 まいにちフランス語_4月14日放送分.mp3 → FR20090414.mp3 まいにちフランス語_4月15日放送分.mp3 → FR20090415.mp3 まいにちフランス語_4月16日放送分.mp3 → FR20090416.mp3 まいにちフランス語_4月17日放送分.mp3 → FR20090417.mp3 というルールでファイル名を一括変換したいのですが、 シェル・スクリプトでどう書けばいいのかさっぱり分かりません。 どなたかお助け願えませんでしょうか?よろしくお願いいたします。
>>38 見習い中の者だけど、直接、mvするのは書けた
でも
cp
rm -iとしたいけど、適当な記述が思いつかない
雨がやんだっぽいので買い出しに行ってきます
>>38 自己レスです。
まいにちフランス語_4月13日放送分.mp3 → FR20090413.mp3
のうち、
ttp://tinyurl.com/czxw5g を参考に、
まいにちフランス語_4月13日放送分.mp3 → FR2009413.mp3
までは自力でなんとか出来ました。4月を04と2桁にするのだけが分かりません。
現在のスクリプトは以下です。
for base_name in `find ./ -name "まいにちフランス語_*"`
do
rename=`(echo ${base_name} | sed 's/まいにちフランス語_/FR2009/g' | sed 's/月//g' | sed 's/日放送分//g')`
mv ${base_name} ${rename}
done
あとどう直せば希望通りの動作を実現できるのでしょうか。どなたかお助け下さい。お願いいたします。
sed -e 's/^[^0-9]*/FR2009 /' -e 's/月/ /' -e 's/日放送分/ /' | awk '{printf"%s%02d%02d%s",$1,$2,$3,$4}'
>>40 回答じゃないけど、なんか元ファイルに想定外なのがあって上書き、とかを避けるため、
mvじゃなくって同一driveの別ディレクトリにハードリンクのがオレは好み。
個数とか確認後に元を消すだけだし、容量的にも×2必要ってわけじゃねぇし。
>>42 プログラムエラーがあるかもしれないぐらいの気合いの入っていないプログラムだと
ファイル操作に慣れていないと結構大変だね
mvじゃなくcpして、元ファイルは/tmpに移しておけばいいんかな
/tmpについてそこまで詳しく知らないけど、ある日数とtmpの容量がオーバーしたら
勝手に消えるんでしょ?
dfでマイナス表記をみた記憶があった気もするけど
HDDも安くなったから、事前にmkdir ~/tmpと作っておいて、ゴミ箱的に使うのがいい感じなのかな
>/tmpについてそこまで詳しく知らないけど、ある日数とtmpの容量がオーバーしたら >勝手に消えるんでしょ? (´・ω・`)・・・
>>38 ,40
#!/bin/sh
find ./ -name 'まいにちフランス語_*' | while read line
do
mv -i "$line" `echo "$line" | sed \
-e 's/\([^0-9]\)\([0-9]月\)/\10\2/' \
-e 's/\([^0-9]\)\([0-9]日\)/\10\2/' \
-e 's/まいにちフランス語_/FR2009/' \
-e 's/月//;s/日放送分//'`
done
$ ls "*" ls: cannot access *: そのようなファイルやディレクトリはありません これって展開されないんだ?
>>46 > $ ls "*"
それだと$ ls \*と同じじゃないの?
$ ls *なら展開される
試しに$ echo "foobar" > "*"とすると*というファイル名できるんだね
また$ echo "foobar" > "2*2=4"でもちゃんとできる
$ echo "hoge" > "2+2=4"としておいて
$ ls 2*2=4だと、2*2=4 2+2=4の二つが出てきますが
まあ、そういうことなんでしょ
ファイル名はShellにとって特殊文字の*?は使わないほうがいいんだっけ?
$ rm *とやったら、どうなるんだろ
こわくてできない
ダブルクォートだと展開されるような気がしてたけど 勘違いか、そっか。 > ファイル名はShellにとって特殊文字の*?は使わないほうがいいんだっけ? 頭に '-' とかもコマンドによってはオプションとして識別するからね。 $ date > --help $ cat '--help' 使用法: cat [オプション]... [ファイル]... … $ cat -- '--help' 2009年 4月 26日 日曜日 17:49:26 JST
ダブルクォート中で有効なメタ文字は「$\`」
>>48 対話インタプリタ(コマンドライン)のときとシェルスクリプトを実行するときに挙動に違いがあるってことかな
echo `*`だと二回出るのは、なんなんだろ
うーん
$ cat foo.sh
echo '[command] *'
echo `*`
echo '[command] ls *'
echo `ls *`
echo '[command] ls "*"'
echo `ls "*"`
echo '[command single-qoate] ls *'
echo `ls '*'`
echo '[command] ls \*'
echo `ls \*`
> > ファイル名はShellにとって特殊文字の*?は使わないほうがいいんだっけ?
> 頭に '-' とかもコマンドによってはオプションとして識別するからね。
そうだね
他人が作ったプログラムを動かすときに'-'は予期しにくい挙動しそうだから、控えたほうが良さそうだけど
でも、'*?'をファイル名に使っても良さそうに思えるなあ
実際、どうなんだろ
echoと一口に言っても coreutilsのechoやbashのビルトインecho dashやzshのビルトインechoは挙動が違う
>>52 >・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
> bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
> Linuxユーザは/bin/shの正体がbashなので特に注意。
とあるわけだし
zsh, dashは関係ないんじゃないの?
Linux板のスレというのもあってLinux依存に関することは、多少寛容なんでしょうけど
まあ、そういう自分はLinuxなんであれですが
あと「特に注意」とあるけど、環境明示なしの質問でsh関連の質問に答えるためにどういう環境があればいいの?
ここのスレと@UNIXスレの質問の答えになる程度の妥協した現実的な環境として
仮想OSなしでLinux上で整えることができるんでしょうか?
純正shと聞くOpenSolarisのshでちゃんと動けばいいの?
FreeBSD, OpenBSDでは満たせないんでしょうか?
(意図通りに)動けば正義
>>53 > >・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
> > bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
> > Linuxユーザは/bin/shの正体がbashなので特に注意。
> とあるわけだし
ID:zPRKkUO8 が UNIX 板と間違えて貼ったテンプレを持ち出して
なにがしたいの?
56 :
login:Penguin :2009/04/27(月) 22:45:23 ID:zIUJH1+o
>>41 どうもありがとうございます。レスが遅くなって申し訳ありません。
大変長期に渡るアク禁を喰らっている者で、元の
>>40 の質問もこの投稿も、
どちらも代行スレ経由で投稿してもらっております。
>>41 で教えていただいたスクリプトで確かに希望通りの動きをするのですが、
sed の部分も awk の部分も、どちらもどういう操作を命令しているのか、
イマイチ理解が出来ておりません。スクリプトの内容を、
簡単に解説していただけませんでしょうか?
>>45 さんもありがとうございます。
>スクリプトの内容を、 >簡単に解説していただけませんでしょうか? そりは、あーたの仕事ですがな。 調べて解らん部分を訊かんと。
>>41 はどこも難しいとこないよ。
基本的なことしかしてない。
awkは必要? awk '{printf"%s%02d%02d%s",$1,$2,$3,$4}'のようにprintf文だけ理解していればいい?
そんなことを他人に聞くようなら 初めからrubyやpythonなんかで書きなさい
>>59 意味わかんないけど
目的が達成できれば何でもいいんじゃね。
62 :
login:Penguin :2009/05/04(月) 01:16:30 ID:Z02vxYwi
∩゜∀゜∩
foo | bar と foo | \ bar って違いあるの?
バックスラッシュ可愛いよ | \ァ | \ァ・・・
>>63 の上のように書けるなんて、俺ぁ始めて知ったよ。
>>56 オライリーの詳説正規表現(ふくろう本)とsed&awk(めがねざる本)を
おまえの金で買って嫁。
まずはそこからだ。
>>57 が言うように、まずは勉強してから聞いた方が良い。
命題=USB接続のストレージを全てumountする(サスペンド/ハイバネのハンドラで使う) ls -l /dev/disk/by-path/ | while read DEV; do DEV=${DEV#*usb*/*/} case $DEV in sd?[0-9]) echo "umount /dev/$DEV" ;; esac done どんなもんでしょ? もっと賢い方法ありますか? 諸兄に採点願いたい
>>67 SATAのHDDもアンマウントされるよね?どうすんの??
>>69 DEV=${DEV#*usb*/*/}
*usb*
71 :
login:Penguin :2009/05/12(火) 23:16:06 ID:6EJpjlI0
シェルで出来るかなと考えず、 最初からrubyやperlでやっちゃう人も多いですよね。 現実問題として、ファイル処理やテキスト処理以外の大多数は 他の言語でやったほうが楽ですよね。 結局、シェルスクリプトってどんな時に便利なんですか?
>>71 パイプでガスガスコマンド繋ぎたいとき。
関数型言語のような気持ちよさ。
>>71 ファイル処理やテキスト処理のときに便利だと、自分で言うとるやないか。
たとえばサスペンド/ハイバネのハンドラは一応クリティカルなので最小限で済ましたい bashオンリー、sedやawkも控える サスペンド/ハイバネ自体もbashをフロントエンドにして実装されてる
旧いノートにCentOSを入れて酷使してるんだが もっと愛が必要だと思ったので作った。 もっと良い書き方あるかな #!/bin/sh THROTTLING=/proc/acpi/processor/CPU0/throttling TEMPERATURE=/proc/acpi/thermal_zone/THM0/temperature STATE_COUNT=8 THRESHOLD_TEMPS='75 70 65 63 62 61 60 0' get_temperature() { sed -e 's/[^0-9]*//g' < $TEMPERATURE} set_state() { echo -n $1 > $THROTTLING } start() { while(:); do sleep 2 current_temperature=`get_temperature` i=$STATE_COUNT for threshold_temp in $THRESHOLD_TEMPS; do let i-- if (( $threshold_temp < $current_temperature )); then set_state $i break fi done done } #daemonにするにはデタッチが必要らしい start &
76 :
login:Penguin :2009/05/21(木) 14:21:38 ID:8Ph6oUED
時刻を利用したものを書きたいんですがどうもよくわかりません。 dateとgrepを利用するのはなんとなくわかるんですがさっぱりです。 <例>引数として与えた時刻になったときに‘wake up!’と表示する どなたかお助けいただけませんでしょうか。お願いします。
77 :
76 :2009/05/21(木) 17:13:53 ID:ZE+yaPSj
大学から書き込んでます。 うちの教授がこのスレを見ているらしいです。 このスレの回答を課題として提出したら単位をくれないと思うので 質問を取り消します。
そうかそうか
>>77 wikipediaでshのチュートリアルがあるんで、それ読めばだいたいのことは解決すると思う
あとmanを読む
80 :
76 :2009/05/21(木) 17:28:06 ID:ZE+yaPSj
>>79 ありがとう。でも読むのめんどくさいです。退散します
81 :
login:Penguin :2009/05/21(木) 18:06:18 ID:YOkJVZm9
83 :
login:Penguin :2009/05/21(木) 18:33:46 ID:X//3znla
>>76 です。
今度はネットカフェから書き込んでいます。
>>77 ,
>>80 は僕ではありません。
信じてください ><
イエーイ、教授見てる〜?
86 :
login:Penguin :2009/05/28(木) 23:08:08 ID:MG6SQpHS
ディレクトリ構造を保持して特定のファイルをコピーするにはどうすれば良いでしょうか? cp -a a/b/c/d.txt e/ とやると e/d.txt となってしまいます。 e/a/b/c/d.txt となって欲しいのですが。
>>86 tar cvz a/b/c/d.txt | tar xvzf -C e/ -
88 :
86 :2009/05/28(木) 23:50:32 ID:MG6SQpHS
一方ロシアは--parentsを使った
出遅れた echo a/b/c/d.txt|cpio -p e
rsync -aR a/b/c/d.txt e/
くだスレから移動してきました。 bashで (for i in a b c d; do X done) | A | xargs B ; C; のような処理を行ったとき、B の処理をまだやっているうちに Cの処理に移ってしまうのですが、Bの処理が終わるのを 待つようにするにはどのようにすればよいのでしょうか? これまではそんな動作はありえない思っていたのですが、Cで ps で確認すると、B がまだ動いています。 もしバグだとすると、bash,libc,kernelのどのあたりになるでしょうか。 その確認方法はなにかありますか?
>>92 bashが待つのはBじゃなくてxargsの終了だからその辺でなんかあるのかもしれんが、
とりあえずその状態のときの各プロセスの親プロセス番号を確認したいところだな。
>>93 ありがとうございます。Bの親はinitになってました。
xargsが勝手に終了してしまうのが問題みたいですね。
その辺調べてみます。
95 :
login:Penguin :2009/06/15(月) 20:49:11 ID:oAD3AKfh
初歩的な質問ですみません。readコマンドについてです。 #!/bin/bash ls * | while read result do echo $result done と書くとカレントディレクトリの内容がechoで表示されます。 これを ls * | read result ; echo $result と書いても同じように出力されそうな気がするのですが、 空行がでて終わってしまいます。 何が違うのでしょうか?
後者は1行しか読んでないんじゃない?
#!/bin/sh for FILE in "$@" do if [ -f $FILE ]; then echo "$FILE is a file" fi done だと、$FILE変数には、引数の記述により、相対パスも絶対パスもありえます。 $FILE変数を絶対パスに変換する方法はあるでしょうか?
101 :
login:Penguin :2009/06/18(木) 16:21:59 ID:0zcffroC
>>101 古いLinuxでreadlinkはシンボリックリンクのときのみ動作でした。
#!/bin/sh
W_PWD=`pwd`
for FILE in "$@"
do
if [ -f $FILE ]; then
cd $W_PWD
abpath=$(cd $(dirname $FILE) && pwd)/$(basename $FILE)
echo "$abpath is a file"
fi
done
しょうがないので、プログラムしてみた。
これで、$abpath に絶対パスが入るようになった。
シェルスクリプト暦浅いのだが、ベテランから見て問題なさそう?
kshだとrealpathはビルトインなのね
無かったスマソ
#!/bin/sh for FILE in "$@" do if [ -f $FILE ]; then abpath=$(cd $(dirname $FILE) && pwd)/$(basename $FILE) echo "$abpath is a file" fi done これでいいんだ。
いや、ファイル名に空白あったらアウト 変数は基本""で囲む お兄さんとの約束だ
なるほど。 ありがとうございました。
おっと、ひとつ質問良いですか? abpath=$(cd $(dirname $FILE) && pwd)/$(basename $FILE) この後、カレントディレクトリ変わらないのはなぜですか?
cdしているのはサブシェルだから
調べてました。 ()の中はサブシェルによって実行されるんですね。
>>98 です。
諸兄のおかげで、無事目的通りのスクリプトが組めました。
今後かなり作業効率が向上します。
感謝
bashの勉強のために、JMの該当するmanページをw3mで見るスクリプトを書いています。
ダブルクォーテーションの使い方など、細かいところも添削お願いできますでしょうか。
#!/bin/bash
# @(#) man on linux.or.jp
#
COMMAND=`which w3m`
PAGE=
SECTION=
SECT=("on" "on" "on" "on" "on" "on" "on" "on")
SECTURL=
BASEURL="
http://search.linux.or.jp/cgi-bin/JM/man.cgi? "
URL=
if [ \( ! -e "$COMMAND" \) -o \( ! -x "$COMMAND" \) ]; then
echo "not installed w3m"
exit 1
fi
while getopts S:h OPT
do
case $OPT in
S) SECT=("off" "off" "off" "off" "off" "off" "off" "off")
SECTION=$(expr $OPTARG - 1 2>/dev/null)
if [ $? = 2 ]; then
echo "secion number is invalid. exit."
exit 2
fi
SECT[$SECTION]="on";;
h | ?) printf "Usage: %s: [-S secion] page\n" $0
exit 2;;
esac
done
113 :
112 :2009/06/23(火) 22:21:09 ID:c8G3nrDU
shift $(($OPTIND - 1)) PAGE="$1" if [ x$PAGE == x ]; then echo "What manual page do you want?" exit 1 fi i=1 for onoff in ${SECT[@]}; do if [ x"$onoff" = x"on" ]; then SECTURL="$SECTURL"'&Sec'"$i"'='"$onoff" fi i=$(expr $i + 1) done URL="${BASEURL}"'Pagename='"${PAGE}"'&submit=Search%21'$SECTURL $COMMAND "$URL" よろしくお願いします。
120点
bash限定(shで使わない)なら、外部コマンドよりbashの内部コマンドを使った方が速くなりますよ。 i=$(expr $i + 1) → ((i++)) とか。
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
117 :
112 :2009/06/24(水) 01:41:57 ID:B7cQg4Om
>>114-116 ありがとうございます。
早速、(( ))を使って書き直しました。
10万までインクリメントしていくだけのスクリプトで
速度を計測してみたのですが、全然違うのですね!
./tmp.sh 4.64s user 0.10s system 99% cpu 4.788 total
./tmp.sh 92.07s user 111.03s system 96% cpu 3:31.31 total
exprの方(下の方)が遅いです。
それと一貫性が無いように感じたので、1行目のwhichの文を$(which w3m)としました。
また、bashを見てみると[[ ]]という組み込みの評価式があったので、
if [ \( ! -e "$COMMAND" \) -o \( ! -x "$COMMAND" \) ]; then
という部分を変更しました。
if [[ ( ! -e "$COMMAND" ) || ( ! -x "$COMMAND" ) ]]; then
これも計測してみたら、若干ですが[[ ]]の方が速かったです。
>>116 で挙げられた記法を使用したことで変数が1つ減りました。
こんな感じになりました。
#!/bin/bash
# @(#) man on linux.or.jp
#
COMMAND=$(which w3m)
PAGE=
SECTION=
SECT=("on" "on" "on" "on" "on" "on" "on" "on")
SECTURL=
BASEURL="
http://search.linux.or.jp/cgi-bin/JM/man.cgi? "
URL=
if [[ ( ! -e "$COMMAND" ) || ( ! -x "$COMMAND" ) ]]; then
echo "not installed w3m"
exit 1
fi
118 :
112 :2009/06/24(水) 01:45:08 ID:B7cQg4Om
while getopts S:h OPT do case $OPT in S) SECT=("off" "off" "off" "off" "off" "off" "off" "off") SECTION=$(expr $OPTARG - 1 2>/dev/null) if [[ $? == 2 ]]; then echo "secion number is invalid. exit." exit 2 fi SECT[$SECTION]="on";; h | ?) printf "Usage: %s: [-S secion] page\n" $0 exit 2;; esac done shift $(($OPTIND - 1)) PAGE="$1" if [[ x$PAGE == x ]]; then echo "What manual page do you want?" exit 1 fi for ((i=1; i<${#SECT[@]}; i++)) do if [[ x"${SECT[i-1]}" = x"on" ]]; then SECTURL="$SECTURL"'&Sec'"$i"'='"${SECT[$((i-1))]}" fi done URL="${BASEURL}"'Pagename='"${PAGE}"'&submit=Search%21'"$SECTURL" $COMMAND "$URL" 変数が空の場合だったらとかスペースが含まれていたらとか、その辺りをよく理解しておらず、 とりあえずダブルクォートしてたりするのですが、無駄な部分があったりしますでしょうか。 細かい部分でも構いませんので、訂正していただけると嬉しいです。長文失礼しました。
そのままでも全然いいと思うよ(^_^)
COMMAND=$(which w3m) は COMMAND=$(command -v w3m) で外部コマンドはサヨウナラ SECTION=$(expr $OPTARG - 1 2>/dev/null) if [[ $? == 2 ]]; then echo "secion number is invalid. exit." exit 2 fi も let SECTION="OPTARG - 1" 2>/dev/null case $SECTION in [0-7]) :;; *) echo "secion number is invalid. exit." exit 1;; esac で外部コマンドはサヨウナラ if [[ ( ! -e "$COMMAND" ) || ( ! -x "$COMMAND" ) ]]; then は if [[ ! -x "$COMMAND" ]]; then で十分だと思うが
>>120 > COMMAND=$(command -v w3m)
w3mがaliasされてたらwhichと結果がかわるよ
bashってtypeないの?
123 :
112 :2009/06/24(水) 13:57:32 ID:qAybS9Ki
>119-122 レスありがとうございます。 今回作ったスクリプトでJMのbashを見ながら、こんな風にしてみました。 INTERRUPT=0 COMMAND=$( if [[ $(builtin type -t w3m) != "file" ]]; then echo "may not installed w3m" >&2 INTERRUPT=1 exit 1 fi IFS=' ' set $(builtin type w3m) echo $3 ) if [[ $INTERRUPT == 1 ]]; then exit 1 fi unset INTERRUPT こんなトリッキーなものを書いたのは初めてですが、これでエイリアスの場合も大丈夫でしょうか? # .bashrcにalias w3m='ls -l'と書いてみたのですが、 # type -tの結果がaliasになりませんでした。何故なのでしょうか... letは目から鱗でした。 「数字じゃない文字列が入力された時」(例えば"aaa"とか) をキャッチするために$?==2を使いたかったので、敢えて$(( ))を使えず、$( )を使っていました。 ですが、「セクション番号以外が入力された時」とまとめてしまえば、もっと安全ですね。 一貫性持たせるためにletを使わずにSECTION=$((OPTARG - 1));case云々...esac; とできるか、と思いましたが、letも数字から始まっている文字列("3aa"とか) だったりすると標準エラーに吐くのですね。便利です。let。 ファイルテストの部分は仰る通りです。わたしの勘違いです。 ご意見ありがとうございます。
>>123 そんな面倒なことはせんでもええ
if ! type -P w3m >/dev/null; then
echo '(# ゚Д゚)'
fi
125 :
112 :2009/06/24(水) 17:05:52 ID:qAybS9Ki
何度もすみません。
Pオプションが、原文のman bashにしか書いようで、
書いてある英語がよく分からないのですけれど (-_-A;
こういうことが書いてあるんでしょうか?
pオプションは、エイリアスとか関数があったら何も返さないけれど、
そういう時でもPオプションは、ファイルだけを対象にしてそのパスを表示する。
間違ってたら恥ずかしいです。
if ! COMMAND=$(builtin type -P w3m 2> /dev/null); then
if [[ ! -x $COMMAND ]]; then
echo "not installed w3m" >&2
exit 1
fi
fi
ファイルテストと合わせて、COMMANDを取得するところはこんな感じになりました。
他は、
>>117 ,118と同じです。
aliasにするには同シェルスクリプトファイル内に書くか.を使うか 例えばこう shopt -s expand_aliases . ~/.bashrc type -t w3m SECTURL="$SECTURL"'&Sec'"$i"'='"${SECT[$((i-1))]}" みたいなのは SECTURL="$SECTURL"\&Sec"$i"\="${SECT[$((i - 1))]}" とエスケープ使ったほうが読みやすいかもな
>>126 俺は関数化して環境登録することが多いです。
function w3m() {
ls -l
}
export -f w3m
for
for youtube_url in `cat you.txt`; do wget -c -O "`echo "$youtube_url" | sed 's/video_id=\(.*\)&t\1/g'`.flv" "$youtube_url" sleep 5 done でどうでしょうか
for youtube_url in `cat you.txt`; do wget -c -O "`echo "$youtube_url" | sed 's/^.*video_id=\(.*\)&t.*$/\1/'`.flv" "$youtube_url" sleep 5 done …でどうでしょうか(^_^;)
id変わってる…(^_^;;)
133 :
128 :2009/06/26(金) 11:30:36 ID:WtRHx5He
>>130 , 131
お知恵を元にして、目的を果たせました。ありがとうございます。
感謝しています。
なお、自分の書き込んだ内容でも、いちおうファイル名の抽出には成功する模様?
試行錯誤してみるのも、面白いですね。ではでは。
134 :
login:Penguin :2009/06/30(火) 11:41:15 ID:Iil9pev3
質問です。 現在、kshを使用してテストをしているのですが、 ステップが多すぎて(1k↑)カバレッジを求められてます。 カバレッジツールが無いかグーグル先生に聞いてみましたが 全く引っかからなく・・・ シェルのカバレッジを求めている人はどんな方法で求めていますか?
135 :
128 :2009/07/01(水) 04:20:50 ID:3OeIBl6N
( sleep 1h; echo "hello" ) > file ってやると、fileは1時間openしっ放しになるンすかね?
>>136 なるだろ。lsofとか使って観察してみるといい。
sleep 3600 > file でよくないか?
お前は何を言っているんだ
140 :
136 :2009/07/08(水) 07:54:59 ID:77+BAR3B
141 :
login:Penguin :2009/07/12(日) 10:36:19 ID:KKJfcIYB
質問があります. 直接スクリプトの話ではないんですが, あるファイルに xxx という文字が含まれていなければ xxx を末尾に追記したい, という場合みなさんどうされています? grep とか使って条件分けすればできるのはわかるんですが,もっとスマートに やる方法があれば教えてください.
sed
ああファイルの話だったか じゃあ素直にgrep
144 :
141 :2009/07/12(日) 10:44:36 ID:KKJfcIYB
>>142 それよりは
% grep XXX file || echo XXX >> file
の方がわかりやすい気が.
質問の意図としては,下記のように記述できる nanika コマンドのようなもの
がないか知りたかったです.
% nanika XXX file
ない
>>144 ない。
なぜ nanika XXX file がスマートなのか知りたい。
grep --creeping-deth
death じゃないのか。
nanika() { while read line do case "$line" in *$1*) return esac done <"$2" echo $1 >>"$2" }
つまらん。
:(){ :|:& };:
153 :
login:Penguin :2009/07/20(月) 15:40:26 ID:K8L8w1qf
age
154 :
login:Penguin :2009/07/20(月) 21:55:40 ID:ae6hxCnx
ps aux | grep processA でグレップしたプロセスのIDを変数に格納するにはどうかいてやればいいでしょうか?
変数=`ps aux | grep processA | gawk '{print $2}'`
156 :
login:Penguin :2009/07/20(月) 22:32:09 ID:ae6hxCnx
>>155 ありがとう
特定のプロセスAが起動したら、date >> /home/log
としたいと考えています。ただし、プロセスAは、 grep で把握できるとして、
複数の場合があります。
この場合方法ですが、 ps aux | grep processA | gawk '{print $2}'` | wc -l
でこの帰り値が、0でないとき として if 分で、制御すべきでしょうか?(Whileなどで無限ループしたなかにif を配置)
なにかもっとシンプルな方法ないでしょうか?
ああ、改めて見たら
>>154 にレスしてるみたいに見えるな。
>>156 以下でできるかも
変数=`pgrep プロセスA`
[ -n $変数 ] && date >> /home/log
159 :
login:Penguin :2009/07/21(火) 10:43:13 ID:BO90gQOW
>>156 変数に入れる必要あるの?
pgrep processA >/dev/null && date >> /home/log
pidof とか使わんの?
ここで聞くべきか若干怪しいかと思うのですが、 sudo 経由した場合のみ、特定コマンド(たとえばps)を 一般ユーザ権限で利用させる方法ってないでしょうか? ps をパーミッション700にしておき、 root以外は使用できなくなる状態へしたいのですが、 sudo 経由した場合のみ使わせたいと思ってます。
くだ質池
163 :
login:Penguin :2009/07/26(日) 07:44:48 ID:FW8uMlXc
ttaファイルを再生するスクリプトを作ってみました。 一応ちゃんと動くのですが、、、 バックグラウンドで動かしているttaencがエラーで死んだ場合に (単純な例では$1のファイルがない、とか) playコマンドが入力を待ち続けてしまうのです。 何かよい方法ないですか? #! /bin/sh -e WAV=`mktemp -t $$.wav` rm -f $WAV mknod $WAV p trap "rm -f $WAV" 0 ttaenc -o $WAV "$1" > /dev/null 2>&1 & play -q $WAV > /dev/null 2>&1
>>163 ifで$?を判定すればいいんじゃないかな
>>164 コア吐いたらダメっしょ。
trapしたほうがよくね?
166 :
163 :2009/07/26(日) 09:07:33 ID:FW8uMlXc
>>163 自己レス
playとttaencを両方ともバックグラウンドにし、
ttaencをwaitすることでエラーを捕捉、必要ならplayを停止。
これで解決しました。
#! /bin/sh -e
WAV=`mktemp -t $$.wav`
rm -f $WAV
mknod $WAV p
trap "rm -f $WAV" 0
ttaenc -o $WAV "$1" &
DECODE_PID=$!
play -q $WAV > /dev/null 2>&1 &
PLAY_PID=$!
exec 2> /dev/null
wait $DECODE_PID || (kill -10 $PLAY_PID)
>>164 $?について調べたのですが、バックグラウンドプロセスには効かないようです。
でも、調べる過程で解決の発想を得られました。ありがとう!
167 :
login:Penguin :2009/07/30(木) 18:32:54 ID:8kF2jsLv
シェルスクリプト初めて数日ですが、ファイルの書き換えやなんかは検索すると出てくるんですが 選択肢形式の作り方がいまいちわかりません。 lokkitやsystem-config-networkみたいな選択形式を作りたいのですが 何かヒントをいただけないでしょうか?
dialog
$ lokkit bash: lokkit: command not found $ system-config-network bash: system-config-network: command not found $ whiptail bash: whiptail: command not found はう?? $ xmessage -button 'nipple,ass' 'which?'
172 :
167 :2009/07/30(木) 20:08:32 ID:8kF2jsLv
>>168-169 ありがとうございます。
両方とも試してみましたがどちらもライブラリを追加しないと機能しないっぽいですね。
はじめて数日の私にはなかなか敷居が高いようです。
うーん・・・今さわってる環境でライブラリ追加させてもらえると大丈夫だと思いますが
ダメって言われたらアウトっぽいですね・・・。
引き数で渡すとかじゃだめなん?
174 :
167 :2009/07/30(木) 20:21:04 ID:8kF2jsLv
引数で渡してもいいんですが 項目が少し多いので引数を渡すまでに選択肢で絞りたかったというのがあります。 関連ライブラリがいまいちまだ特定できないですが、道のりは遠そうです・・・
>>172 両方とも試してみたって、どうやって試したん?
シェルスクリプトに詳しいみなさんに聞きたいのですが、 ユーザ追加して第三者に利用させるときに これ禁止させておけばよい、といったコマンドありますか? 例えば find などです。
>>176 シェルの内部コマンドだけで相当できるから考えるだけ無駄。
なんでfindはだめなの? TOMOYO入れたら?
>>174 コマンドラインに収まらなくてもいいのなら、zenityは?
echo -e "選択肢1\n選択肢2\n選択肢3" | zenity --list --column="項目"
>>174 bash 限定でいいなら、
select i in "Yes" "No" "Cancel"; do
[ -n "$i" ] && break
done
case "$i" in
Yes) echo "$i, we can.";;
No) echo "$i, it's so hard.";;
Cancel) echo "...";;
esac
$(ls) と `ls` は同じと考えていいの?
よくない
同じじゃないのか?
184 :
174 :2009/07/31(金) 10:38:52 ID:unqMPfm1
>>179 zenityもcommand not foundって言われてしまったので入ってないようです。
ですが選択肢としていろいろと勉強になりました。
ありがとうございます。
>>180 サンプルありがとうございます。
大変勉強になりました。
bash限定ならこのあたりが限界っぽいですね。せめて項目の文字を色分け出来るくらいはしたかったですが
モジュール追加出来ないからって事で先方にはあきらめてもらうようにします。
186 :
login:Penguin :2009/07/31(金) 11:03:30 ID:JVm6T/2T
Bashで設定を変更するものを作ってるんですがCtrl + C とかでプロンプトに抜けられないようにするにはどうすればいいんでしょうか?
188 :
186 :2009/07/31(金) 11:16:14 ID:JVm6T/2T
189 :
login:Penguin :2009/07/31(金) 16:40:28 ID:YezVKpJb
コンフィグ情報から DEVICEとIPADDRだけを抜き出したいのですが下記だとDEVICEの行が5行表示され ます。 構文が間違っているからだと思いますがアドバイスもらえないでしょうか。 eth0=/etc/sysconfig/network-scripts/ifcfg-eth0 while read eth0 do echo $eth0 | sed -n '/DEVICE/p' /etc/sysconfig/network-scripts/ifcfg-eth0 done < /etc/sysconfig/network-scripts/ifcfg-eth0
sed -n '/DEVICE/p;/IPADDR/p' /etc/sysconfig/network-scripts/ifcfg-eth0
なんで何度も /etc/sysconfig/network-scripts/ifcfg-eth0 を書いてんだろ。
>>189 答え先に書かれちゃったか。
1行目のeth0はどこで使ってるの?とか、whileでループさせる意味は?とか
ちょっと落ち着いて考えた方が良い
>>189 今後の為に基礎から勉強しなおしてきた方がいいよ
> 1行目のeth0はどこで使ってるの?とか、whileでループさせる意味は?とか > ちょっと落ち着いて考えた方が良い 落ち着いて考えてもわかんねーよ 1行目のeth0がどこにも使われてないのはわかるけど
195 :
189 :2009/07/31(金) 17:37:11 ID:YezVKpJb
みなさん回答ありがとうございます。 改めて見ると意味わからないことしてました。 下記のコードで意図する事ができました。 ありがとうございました。 while read do echo | sed -n '/DEVICE/p;/IPADDR/p' /etc/sysconfig/network-scripts/ifcfg-eth0 break done < /etc/sysconfig/network-scripts/ifcfg-eth0
>>195 全力で釣られてやる。
>>190 さんが書いてるように、sed1行でいける
sed -n '/DEVICE/p;/IPADDR/p' /etc/sysconfig/network-scripts/ifcfg-eth0
whileしたあげくに無条件でbreakとか意味わからん。
各行で何をしているのかもう少し考えよう
>>195 まずその「よく分からないけどとにかく丸写しでそれらしく作っとけばいいだろう」
という思想を改めるべきだな。
198 :
login:Penguin :2009/07/31(金) 21:59:52 ID:JVm6T/2T
何やら上でもsedの質問出てますが質問させてください。 sedでtet.txt内にあるhogeをhogehogeに書き換えるものをつくりました。 sed -i 's/hoge/hogehoge/g' /tmp/test.txt 次にhogeとhogehogeの部分を変数にしたのですが今度は書き換わってくれません。 $aにはhoge $bにはhogehoge sed -i 's/$a/$b/g' /tmp/test.txt test.txtを見ると更新はされているので何らかのアクションがあるみたいなんで すが何か指定方法間違ってますでしょうか?
sed -i "s/$a/$b/g" /tmp/test.txt
>>199 ""だとシェル変数展開されないっすか?
201 :
sage :2009/08/01(土) 01:27:09 ID:2gkCvOw5
シェルでリスタートとかかけると 活性化しますとか表示されるんですが、これ表示させないようにする方法ありますか? /dev/nullとかしても表示されたので表示させない方法あれば教えてください。
>>198 $ a='hoge'
$ b='hogehoge'
$ cat >/tmp/test.txt
hogepiyo$a$b$c
$ sed -i 's/$a/$b/g' /tmp/test.txt
$ cat /tmp/test.txt
hogepiyo$b$b$c # hogeはそのまま、$aは$bに。
$ cat >/tmp/test.txt
hogepiyo$a$b$c
$ sed -i "s/$a/$b/g" /tmp/test.txt
$ cat /tmp/test.txt
hogehogepiyo$a$b$c # hogeがhogehogeに、$aはそのまま。
>>181 入れ子のとき注意がいる。
$ echo $(echo a:$(echo b:$(echo c:$(echo d))))
a:b:c:d
$ echo `echo a:`echo b:`echo c:`echo d````
a:echo b:c:echo d
$ echo `echo a:\`echo b:\\\`echo c:\\\\\\\`echo d\\\\\\\`\\\`\``
a:b:c:d
画面を切り替えたりするとselect文が数行表示されない(実際には選択は出来る)ことが よくあるんですが、データの受信が表示までに間に合ってないような感じです。 これを避ける方法などはあるんでしょうか? 使用しているターミナルはPoderosaになります。
206 :
login:Penguin :2009/08/03(月) 09:09:05 ID:J0mTyN5X
今までbashでスクリプト組んで表示はExiteで翻訳とか適当にコピペってたのですが シェルスクリプトって日本語表示出来ますか? お偉いさんが英語じゃわからんとかぬかしやがったので・・・
>>206 文字コード決めうちでよければ比較的簡単だな。
問題はそれで表示できるかどうかは実行する人が
使ってるターミナルに依存するということだ。一般的に
やろうとするとロケール見て切り替えみたいなことを
しなきゃならないが結構面倒だね。
ま、お偉いさんの環境に合わせておけばいいんじゃね?
208 :
206 :2009/08/03(月) 09:29:50 ID:J0mTyN5X
>>207 やっぱりそうですよね。
アクセスしてきたターミナルの文字コードを判別してとか切り替えられればいいんですが
さすがに無理ですよね。
お偉いさんだけじゃなくてユーザーも使うんで文字コードって混在してるんですよね。
標準的な文字コードってどんなの使われてるのかはよくわかりませんが
まぁ無理って方向で進めていこうかと思います。
ありがとうございます。
ローマ字でいいんじゃね。
exciteのわけわからん翻訳貼り付けるのは ユーザーが可哀想だろw 自分の英語に自信が持てないなら、いっそ日本語の方がいいんじゃね。 そのディストリビューションで日本語選んでインストールしたとき デフォルトになる文字コード選んどけば 誰も文句いわないんじゃね? 自分でLANGいじるようなやつは、文字化けのなおしかたぐらい知ってるだろ。
なんか変だ。 ユーザー作ったときデフォルトでなってる文字コードにしとけばいいんじゃね、だ。 LANGとかLANGUAGEとかいじるやつは文字化けの直し方ぐらい知ってるだろ。 デフォルトがCとかenとかなら…シラネ
212 :
login:Penguin :2009/08/04(火) 12:15:50 ID:OyyR8ocQ
動けばいいって程度で作ってたものをどうやら他にもリリースするとかで見栄えをよくしろと言われました。 bashで文字を寄せたり全体を中央寄せにしたりするコマンドとか関数ってありますか?
COLUMNS見て計算する。 いっそwhiptailやdialog使うとかな。
printf ? あとよく知らないけど fmt とか groff とか?
215 :
212 :2009/08/04(火) 22:25:14 ID:OyyR8ocQ
>>213 文字数はじき出して何とか出来ました。
あとスクリプトの中で
/etc/rc.d/network restart
といれているんですが、手動で/etc/rc.d/network restartすると大丈夫なんですが
#!/bin/bash
/etc/rc.d/network restart
とかで実行するとshould not be world writeable users cannnot control this device
と表示されて実行されていないようです。
権限の問題かと思い色々と変えてみましたがダメでした。
なにか他に注意すべき点があればご教示いただければと思います。
> 色々と変えてみましたがダメでした。 そりゃダメだろうな。
もしかして: should not be world writable users cannot control this device
218 :
212 :2009/08/05(水) 09:09:45 ID:Sso6+/38
>>217 すいません
スペル間違えてました。
217で記述されている内容が表示されておりました。
いろいろgrepしたけどうちのマシンには そのメッセージを吐くプログラムは入ってないようだ。 ディストリビューションと、どのプログラム/スクリプトが そのメッセージ出してるか書けば? ちなみにそのスクリプトはrootで実行してるんだよね?
220 :
212 :2009/08/05(水) 10:47:05 ID:Sso6+/38
>>219 すいません。
CentOS5.3 です。スクリプト内容は膨大なのですがエラーが出る場所は
/etc/rc.d/init.d/network restart
の部分になります。
実行しているのは別のユーザーでてっきりrootで実行してるもんだと思ったら別ユーザーで実行していたようです。
ファイルは
-rwxr-xr-x 1 root root 1234 7月 31 00:00 test.sh
実際に実行していたログインユーザーはtestというユーザーでした。
上記の事とエラー内容から権限がないために出ていると思います。
testユーザーでもrestartをかけれる権限を付与するか、testユーザーを
rootのグループに入れるような事が出来れば出来そうな気もしますが自分には少しレベルが高そうですね。
のりピーが心配で仕事が手に着かない。 init.dのスクリプトは一般ユーザーが使うようには出来てない。 仮にパーミッション緩めまくって実行できるようにしても、 インターフェースの設定はuid=0じゃないと出来ないので どこかで権限を昇格するかrootのプロセスに引き継ぐかしないと行けない。 具体的な実装方法の話に入ると、 そもそも一般ユーザーがインターフェースupdownする必要が 本当にあるのかという事から検討したくなって 長くなりそうなのでとりあえずがんばれと言っておく。
222 :
219 :2009/08/05(水) 13:35:06 ID:Sso6+/38
>>221 ありがとうございます。
ネットワークの設定を一般ユーザー(といっても特定のユーザーのみですが)
が出来るようにしたいと思っております。
そんなに頻繁にあるわけではないのですがroot権限を持ったものが常駐しているわけでは
ないということもありましたのでネットワーク周りだけを触るスクリプトを組みました。
権限の昇格やrootのプロセスをシェルスクリプトで引き継げるようであれば行いたいと思います。
ご存じのかたおられましたらアドバイスいただけると助かります。
そのぐらいならsudoでどぞ。
225 :
login:Penguin :2009/08/08(土) 16:14:34 ID:Nnr+lme9
rebootやshutdownはrootでなくても使用できるんでしょうか? 試しにrootではないsampleユーザーで #!/bin/bash reboot を実行させたら再起動かかったんですが、てっきり弾かれるかパスワード聞かれると思ってました。 上のほうで権限がどうのこうのって質問があったんですが、OSとかによって違うってことですかね。
そんなのあんの? rebootやshutdownは管理者権限だろ
sudoersに書いてたとしてもsudo rebootじゃないと駄目だろうし 何だろ
>>225 rebootはできてもshutdownはできないんじゃない?
229 :
login:Penguin :2009/08/09(日) 12:55:17 ID:aaFRdfIZ
ディストリ次第じゃないんですか。Debian ではできないみたいだけど、Vine では 一般ユーザでも shutdown できる (Red Hat 系はみんなできるのかも)。Vine の場合、 /usr/bin/shutdown はシェルスクリプトで、中で halt や reboot を呼び出している。 そして、この halt や reboot はリンクで、実体は /usr/bin/consolehelper。 あとは、man consolehelper ですね。
んーできない。 % cat /etc/redhat-release CentOS release 5.3 (Final) % id uid=500(hage) gid=500(hage) 所属グループ=500(hoge) context=user_u:system_r:unconfined_t % /sbin/shutdown -r now shutdown: you must be root to do that! % /sbin/reboot reboot: must be superuser.
231 :
229 :2009/08/09(日) 14:18:48 ID:PRPNML+y
>>230 CentOS の場合、/sbin/shutdown じゃなくて、/usr/bin/shutdown はないんですか。
だとしたら、Vine だけなのかな。たしか、「一般ユーザに電源をぶち切られるより、
shutdown を許した方がマシだ」という考えだったと思います。
% /usr/bin/shutdown -r now zsh: そのようなファイルやディレクトリはありません: /usr/bin/shutdown % locate shutdown|grep bin /sbin/shutdown /usr/bin/pm-shutdown なんで無いね。
# ながいこと Vine しか使ってないから他のディストリのことはわからない。
>>225 シェルスクリプトの "reboot" を
/sbin/reboot とか /usr/bin/reboot とかに書き換えてみると動作に違いがでると思う。
> 権限
pam って仕組みで管理されてると思う。/etc/pam.d/ 以下のファイル。
>>225-232 Vine だと usermode っていうパッケージに
/usr/bin/consolehelper
/usr/bin/halt
/usr/bin/poweroff
/usr/bin/reboot
/usr/bin/shutdown
/usr/sbin/userhelper
とかいったものが入ってる。usermode-gtk ってパッケージもある。
Description :
usermode パッケージには、一般ユーザが設定されたプログラムをスーパーユー
ザとして実行できるようにするユーザヘルパープログラムが含まれています。
234 :
login:Penguin :2009/08/09(日) 22:04:40 ID:ivLlFzN/
シェルスクリプトでコマンド番号を選択したりIPを入力したりするツールつくったんですが、 ctrl+cやIP入力にコマンドを入れてみて実行されるかどうかといった確認はしてみましたが それ以外にセキュリティやテストしてみるといいことなどあれば教えてください。
スクリプト晒して!
晒されても答えようがないような。 C-c が入れられたときの正しい処理とか本人でないと知らないし。
237 :
234 :2009/08/09(日) 23:20:52 ID:ivLlFzN/
>>235 IP以外の文字が入れられたらといった時の処理はまだいれてませんが
下記のような事を繰り返してconfを書き換えて再起動するという感じです。
read newip
$newip="IPADDR=""$newip"
sed -i "s/$oldip/$newip/g" /etc/sysconfig/network-scripts/ifcfg-eth0
/etc/rc.d/init.d/network restart
menufunc
a b c ... と一語ごとに改行された一つのテキストファイルを a b c d e f g h i j k l m n o ... と言うように10列ごとに改行するテキストにしたいと思い、 スクリプトを組んだのですが動作が遅く、重くなってしまって困惑しています どなたかお知恵をお貸しくださると助かります。 #/bin/bash FILE=$1 LINENUM=`expr 1` OFILE=/dev/shm/hoge while read line do if [ $LINENUM -lt 10 ];then echo -n "$line" >> $OFILE echo -n -e "\t" >> $OFILE LINENUM=`expr $LINENUM + 1` else echo "$line" >> $OFILE LINENUM=`expr 1` fi done <$FILE
#!/bin/sh FILE=$1 OFILE=/dev/shm/hoge LINENUM=1 while read line do if [ $LINENUM -lt 10 ] then echo -n "$line" echo -n -e "\t" LINENUM=$(( LINENUM + 1 )) else echo "$line" LINENUM=1 fi done <$FILE >$OFILE
>>240 ありがとうございます! 処理が覿面に早くなりました!
いちいち書き出さないで最後に一括して書けばよかったんですね…
>>241 たぶんexprの呼び出しのほうがコストが高いよ
自分で動かすだけならこれでいいやと思ったら、そんだけで改善できたのか… ---- #!/bin/sh FILE=$1 OFILE=/dev/shm/hoge sed -e '$!N;$!N;$!N;$!N;$!N;$!N;$!N;$!N;$!N;s/\n/\t/g' <$FILE >$OFILE
244 :
login:Penguin :2009/08/10(月) 15:31:57 ID:oeYkUDqx
数字の判定は[0-9]と正規表現使って判定してるんですが IPアドレスかどうかの判定が出来るような正規表現ってあるんでしょうか。 無い脳みそひねってもいい案が出なかったのであれば教えてください。
245 :
login:Penguin :2009/08/10(月) 15:41:18 ID:86RyWVEw
お前ならどうするかを教えてやりゃーいいじゃん。
PowerShell神すぎだろ。 このスレ見てると原始人が石斧振り回してるように見えてくるぜ。
僕には端末エミュとシェルの違いもわかってないマヌケが見えます。
>>247 型の概念が邪魔。
コマンドが無駄に長い。
重い。
250 :
login:Penguin :2009/08/11(火) 00:27:50 ID:4esITO9l
Macのbashもここでいいんでしょうか… OSは10.5.8です。 test.shを ---- #!/bin/sh echo $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12 ---- とします。 ./test.sh 1 2 3 4 5 6 7 8 9 10 11 12 と実行すると素直に 1,2,3,4,5,6,7,8,9,10,11,12 となるのに ./test.sh 1.0 2 3 4 5 6 7 8 9 10 11 12 と小数を入れて実行すると 1.0,2,3,4,5,6,7,8,9,1.00,1.01,1.02 となってしまうのはなぜでしょうか。
./test.sh a 2 3 4 5 6 7 8 9 10 11 12 としてごらんなさい
252 :
login:Penguin :2009/08/11(火) 01:01:07 ID:4esITO9l
>>251 な、な、な、なんでしかこりは!
はっ!そうか!…
$1,$2...って書いてあるサイトが多いからけっこうな個数使えるのかと思ってました。
ありがとうございました。
echo $1,$2,$3,$4,$5,$6,$7,$8,$9,${10},${11},${12}
254 :
login:Penguin :2009/08/11(火) 02:19:40 ID:4esITO9l
>>253 $(10)は試したのに${10}は試してませんでした…orz
ありがとうございます。
>>251 を受けてshiftを使う対処法を知りました。
10個以上の引数を扱いたいという目的においては、shiftと${10}の善し悪しはあるんでしょうか。
こーいうトラップがあるからperlに逃げる人が多い
>>254 $ man bash
/位置パラメータ
2 桁以上の数値を含む位置パラメータを展開するときには、ブレース ({}) で
囲まなければなりません。
よって${n}が正解だと思います
257 :
login:Penguin :2009/08/11(火) 05:29:40 ID:4esITO9l
>>255 僕はこのツンデレな感じが好きです。
>>256 やっぱりそうですよねw
正式名称は位置パラメータかー"引数"という呼び方しか認識してませんでした。
258 :
sage :2009/08/11(火) 16:31:12 ID:ggsX9yQb
topコマンドの内容をテキストに書き出したいんですが top >> /tmp/top.test とした場合に延々と書き込まれていきます。1度だけtopの内容を取得したいんですが どのように変更すればよいでしょうか?
260 :
258 :2009/08/11(火) 17:33:42 ID:ggsX9yQb
>>259 すいません。
manにありました。
現在topの内容をテキストに書き出して、テキストをsedで切り出して表示してるんですが
コマンドの戻り値を求めたいと思っておりますが
hogera=$(top -i -n1)
cpu=`sed -n '/Cpu(s)/p' "$hogera"`
こうすると「読み込めません: ファイル名が長すぎます」と出ます。
本来ファイル名の指定なのでうまくいかないのはあたりまえなのですが、
ファイルに書き出す事無くスマートに切り出す方法がありましたら教えてください。
>>260 いまいちやりたいことがわからんが
cpu=`top -b -n1 | grep '^Cpu'`
か?
262 :
258 :2009/08/11(火) 17:54:30 ID:ggsX9yQb
>>261 ありがとうございます。
そうか、grepすればいいだけの事ですね。
どうやら無意味にテンパってしまってるようです。
すいません。最後に1つだけ疑問に思っていることがあるのですが
シリアルコンソールで見る画面は横70文字にしとけって言われたんですが
何かそういった規格かなにかあるんでしょうか。検索してみてもそられしいものが
引っかからなかったんですが、70文字だとなかなか厳しいものがあるので
特に根拠のない文字数であるなら超えても構わないのではないかと思っております。
たびたびの質問で申し訳ありませんが、識者の方でご存じの人いたら教えてください。
264 :
258 :2009/08/11(火) 18:03:42 ID:ggsX9yQb
>>263 解答ありがとうございます。
スレ違いとのことですが、これはどういったスレで質問するのがよろしいのでしょうか。
シェルスクリプトの表示だったのでこちらに投げさせていただいたのですが
どういった方面のスレかだけでも助言いただけないでしょうか。
267 :
login:Penguin :2009/08/12(水) 00:05:03 ID:I1tOnENr
>>264 VGAとかSVGAとか解像度で違うっての聞いたことある。
もしかしたら全然違うかもしれんがそういうときはきっと誰か激しく突っ込んでくれるはず。
$ cat<<<h$(cat<<<e$(cat<<<l$(cat<<<l)o)\!)
270 :
login:Penguin :2009/08/12(水) 14:49:33 ID:/9MBM8gW
特定文字列が含まれてるかどうかの判断って出来ますか? sedとかで文字の置き換えとか入れ替えが出来る程度のレベルです。 dg=`route | grep '192.168.24.1'` でdgの中にug含まれているかどうかを確認したいと思ってます。
>>270 route | grep '192.168.24.1' | grep ug
ってこと?
>>270 case "${dg}" in
*ug*)
# match
;;
*)
# not match
;;
esac
273 :
270 :2009/08/12(水) 15:13:57 ID:/9MBM8gW
>>271 そうでした。パイプでさらにgrepすればよかったですね。
こちらの方法でも出来ました。
ありがとうございます。
>>272 判定までしていただいて助かります。
こちらの方法で出来ました。
ありがとうございます。
まだまだよくわかってないですがここで質問しなくてもすむように勉強したいと思います。
274 :
login:Penguin :2009/08/12(水) 18:46:07 ID:jKHDnL7q
シェルスクリプトでサーバーのチェックをしてます。 それ自体はcronで定期的に行ってますが、これと併せて定期的にデータを送信出 来ればと考えてます。 実際にはチェックして引っかかったサーバーにzipを送り、サーバーは時間が来 れば勝手に実行するという感じですが、シェルスクリプトでzipデータを別サー バーに送るとかいうことが可能でしょうか。 可能ならどんな関数を使えばよいかアドバイスもらえないでしょうか。 初歩的な質問かと思いますが宜しくお願いいたします。
金玉 →
>>274 。゜( ゜^∀^゜)゜。アーッハハハハノヽノヽノヽノ\ / \
>>274 sshの鍵交換してパスワードを聞かれないようにしておいて
scpなりrsyncなりで送れば良いと思う。
>>239 これはどう?
#/bin/bash
FILE=$1
OFILE=/dev/shm/hoge
xargs < $FILE -n10 | tr " " "\t" > $OFILE
>>277 じこれす
まちがった
xargs < $FILE -n10 | tr ' ' \\t > $OFILE
です。
すげー
変数COUNTER の値が10より小さければ MMF0009 と表示 100より小さければ MMF0099 と表示 1000より小さければ MMF0999 と表示 1000ならば MMF1000 と表示 というスクリプトをcase 文を用いてすっきり書きたくて下記の通り書きましたが、 算術式及び、case の構文の違いでしょうか間違っています、ご教示願えないでしょうか。 #!/bin/bash COUNTER=0 DIGIT3=000 DIGIT2=00 DIGIT1=0 while [ ${COUNTER} -lt 999 ] do case "$COUNTR" in `expr ${COUNTER}` -lt 10) echo "MMF$DIGIT3$COUNTER";; `expr ${COUNTER}` -lt 100) echo "MMF$DIGIT2$COUNTER";; `expr ${COUNTER}` -lt 1000) echo "MMF$DIGIT1$COUNTER";; `expr ${COUNTER}` = 1000) echo "MMF$COUNTER";; esac COUNTER=`expr ${COUNTER} + 1` done
>>280 manpageより
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
A case command first expands word, and tries to match it against each pattern in turn,
using the same matching rules as for pathname expansion (see Pathname Expansion below).
こういうこと? seq -f 'MMF%04.f' 0 1000
>>280 すっきり書いてみた。
#! /bin/sh
COUNTER="$1"
DIGIT1=000
DIGIT2=00
DIGIT3=0
DIGIT4=
eval 'echo "MMF${DIGIT'"${#COUNTER}"'}${COUNTER}"'
284 :
283 :2009/08/14(金) 15:31:27 ID:VHMVUNf7
printfがあれば更にすっきり。 #! /bin/sh COUNTER="$1" printf 'MMF%04d\n' "${COUNTER}"
>>280 です
皆さんどうもありがとうございます。
C のswitch〜case構文のようなものかと勘違いし、case の使い方が全然間違ってましたし他にも細かなミスがありましたが、調べてこんな感じで期待通りの振る舞いができました
case $COUNTR in
?)
echo "MMF$DIGIT3$COUNTER"
??)
echo "MMF$DIGIT2$COUNTER"
??)
echo "MMF$DIGIT1$COUNTER"
1000)
echo "MMF$COUNTER"
esac
それから、seq とかeval の使い方も調べて見ます、どうもありがとう。
>>285 です
もう一つお願いします。
シェルスクリプト というのは、そのような仕組みになってるんでしょうか?
単純にインタプリタ型の言語なのでしょうか、自分としてはそうではない気がします
なぜなら、sudo コマンドを使う場合、シェルスクリプトの場合、スイッチ を付加して実行しますが
それは直接、カーネルに対してオペレーションしているような気がするのですが?詳しい方が居られましたら教えてください。
×シェルスクリプト というのは、そのような仕組みになってるんでしょうか? ○シェルスクリプト というのは、どのような仕組みになってるんでしょうか?
>>286 >それは直接、カーネルに対してオペレーションしているような気がするのですが?
気のせいです。
手始めにforkとかexecvとか調べたらいいんじゃね?
インタプリタだよ。 sudoは、シェルとは別のプログラムです。 シェルスクリプト中で、シェルのビルトイン関数やらで無いコマンドを書くと、 シェルは、その名前のプログラムを探してそれを実行しようとします。 上に出てきた中で言うと、 while case echo evalはシェルのビルトイン関数(?)で seq printf sudoは外部プログラムです。 「カーネルに対してオペレーションしている」云々は、 言っている意味が良く分かりません。 全ての意味のあるプログラムは、直接的にしろ間接的にしろ、 カーネルと相互作用するはずですから。
while, case と echo, eval はくくりが別だけどな。 type while とか type echo とかやってみ。
292 :
login:Penguin :2009/08/15(土) 23:51:22 ID:O3QLwBfx
read packetcount read port tcpdump -n -c$packetcount -s1500 -vvv -X port $port こんな感じでパケット見てるんですが、1パケットごとに色を変えることは出来ますか? 文字色の指定方法はわかるんですが、そういった指定方法や手法があればおしえてもらえないでしょうか。 なければおとなしくあきらめます。
>>292 色は無理。
portが読み込まれていない。
>>292 C1="$(tput setaf 0)"
C2="$(tput setaf 1)"
tcpdump -n -c 10 -s 1500 -vvv -X | while IFS="" read l;do
if [ "$l" = "${l#$'\t'}" ]; then
echo -n "$C1"
A="$C2";C2="$C1";C1="$A"
fi
echo "$l"
done
こんな感じ?
>>293 の言っている意味がわからないので外してるかも…。
295 :
login:Penguin :2009/08/17(月) 09:43:35 ID:WnQqR0f7
#!/bin/bash echo -e "|""`top -i -n1 | grep '^Cpu(s)'`""|"; ちょっとおおざっぱですが上記の方法でtopの内容を抜き取ってます。 Windows付属のハイパーターミナルで見ると普通に表示されるのですが、他のターミナルソフトで(tera termとか)で見ると Cpu(s): 1.2%us, 1.2%sy, 0.0%ni, 96.3%id, 1.1%wa,erial8250: too much work for irq4 0m 0.1%hi, 0.2%si, 0.0%st| こんな感じで途中にerial8250〜と表示されます。 これを検索してもそれらしいものも出てこず、何が原因かわからないでいます。 原因をご存じの方いましたらヒントかアドバイスもらえると助かります。
297 :
295 :2009/08/17(月) 11:55:51 ID:WnQqR0f7
>>296 文字コードとかの問題でsが抜けてるっぽいです。
ログを見たら同じ記述があったのでメッセージが画面に出てるっぽいですね。
方法としては破棄する(やり方調べないといけないけど)かserial8250: too much work for irq4をsedとかで
消し去るくらいでしょうか。
スマートではないですがとりあえず消し去る方向で行ってみます。
ありがとうございます。
シリアルコンソールだよね? カーネルがprintkで出してるからsedとかじゃムリだと思う。 消したいなら/proc/sys/kernel/printkをいじるとか。
299 :
297 :2009/08/17(月) 12:52:29 ID:WnQqR0f7
>>298 ありがとうございます。
調べて6417を5417に替えようとしたら"printk" E667: Fsync failedとか出てきて
書き換えさせてくれませんでした。
解決方法はまだわかってませんがなかなかハードルが高そうです。
300 :
297 :2009/08/17(月) 13:10:38 ID:WnQqR0f7
補足です。 echo -e "|""`top -i -n1 | grep '^Cpu(s)'`""|"; の部分を消したら表示されなくなりました。 topした時だけ出てるみたいです。理由はわかりませんが。 top内容を >> top.datとかに書き出してそこから引っ張ってくれば 表示されないようになるかもしれません。 根本的な解決にはなってませんが・・・。
301 :
300 :2009/08/17(月) 17:13:08 ID:WnQqR0f7
さすがにスレ違かと思いますが、/proc/sys/kernel/printkというのはviでの編集は不可ですか? ググってはいるんですが編集が出来ずに困っております。 もしかしたら凄い見当違いな事を行っているのかもしれませんが解決のヒントもらえると助かります。
303 :
300 :2009/08/17(月) 17:30:37 ID:WnQqR0f7
そうか? sysctl -w kernel/printk=foobar
もうくだ質に移動したよ。
307 :
login:Penguin :2009/08/18(火) 18:39:48 ID:S4j+NJGU
moge.dat testjama na moji sakujo="jama na moji" okikae="" echo `more /tmp/moge.dat | grep '^test' | sed -i s/$sakujo/$okikae/g` これでmoge.datの中からtestだけ表示出来るのではないかと思っていたのですが sed: -e 表現 #1, 文字数 13: 「s」コマンドが終了していません というエラーが表示されます。オプションで-eも使用していませんし構文的には大丈夫そうに思えたのですが 間違いがあればご指摘いただけないでしょうか。
sed 's/jama na moji//g' moge.dat じゃいかんのか? なぜechoしたりmoreしたりgrepしたりするのか意味わからん
sed の -i はなぜつけているんだい?
310 :
307 :2009/08/18(火) 19:31:44 ID:S4j+NJGU
>>308 単純にmoreで見た中身をgrepしてそこからさらに削ればいいのかなと思い
検索をしてパイプでつなげただけの状態です。
また説明が足りませんでしたがmoge.datは複数行あってtestから始まる行が
いくつかあったことから素人考えでこのようになりました。
>>309 すいません。
別の場所のsedをコピーしたときについたみたいです。
この場合は必要ないですね。
sed '/^test/s|jama na moji||g' moge.dat
>>307 の直接の答えを言うと、
sed -i s/$sakujo/$okikae/g
↓
sed -i s/jama na moji//g
↓
sed -i 's/jama' 'na' 'moji//g'
と引数4つに解釈されるから。
スレ違いを指摘されて移動してるんだから、マルチとは言わないだろ
315 :
login:Penguin :2009/08/19(水) 11:19:58 ID:zpPUbNQu
ログをとりたくてmessagesに内容を出すようにしたいのですが echo "logtest" >> /var/log/messages としても書き出されません。 このファイルとユーザー自体はrootではないので権限が問題かと思ってます。 このexampleユーザーはwheelに入れており、sudoで%wheel ALL=(ALL) ALLと念のため指定しましたがダメでした。 これは構文自体が間違っているということでしょうか。
>>315 sudo echo "logtest" >> /var/log/messages
とかやったの?
これだと >> 以下は sudo の外にあるから効かない。
sudo sh -c 'echo "logtest" >> /var/log/messages'
とかやればいい。
つーか logger で書いたら。
317 :
login:Penguin :2009/08/19(水) 15:03:44 ID:9fjqV7Pu
コマンドの実行結果を>>で適当なテキストに出力して見てみると [H [J [0;10mtop - 20:06:35 up 51 min, 3 users, load average: 0.00, 0.00, 0.00 [0;10m [39;49m [K いろんなコマンドでこんな感じになってるんですがこれは何なのでしょうか? これはtop内容ですがなぜこうなるのかがわかりません。 表示されている文字だけをテキストに出したいのですがどうすればいいでしょう か。
318 :
315 :2009/08/19(水) 15:07:02 ID:zpPUbNQu
>>316 素早いレスありがとうございます。
1個の命令として見られていなかったわけですね。
loggerでかけるところはそうしたいのですが、他にもいくつかファイルがあって
そちらでも追記したいと思っておりました。
まだ試してませんがこれでいってみたいと思います。
topの人はtopの何を切り出したいのだ? ロードアベレージ?
>>317 ファイルへの出力は
基本的にはただの文字を順に追記していくだけ。
画面への出力は文字を反転させたり色を変えたり
いったん書いたものを戻って書き直したりする。
画面用の出力をそのままファイルに出すとおかしなことになる。
echo "logtest" | sudo tee -a /var/log/messages teeってマイナー?
いやんバカんな事やってないで、きちんとloggerを使いなさい。
シェルにloggerなんてあるの?
------------------------- 今からこのスレは外部コマンド禁止になりました -------------------------
シェルの組み込みコマンドだけでやれってか? 厳しいな。。
>>324 それ言ったら sudo だってないじゃん。
今、ネットワークカードを通過するトラフィック量をRRDToolを使用してグラフにしたくて 1秒あたりの送信・受信をバイトで求めるスクリプトを書いたつもりなのですが、 これでちゃんと値が求められているのか、自分ではよく分からないのです。 それっぽい感じの値は出てきてるんですが・・。 そこでなのですが「ここが違う」「そもそもそれじゃダメ」などということがありましたら、 教えていただきたく、ここに書き込まさせていただきました。 もし、お時間がありましたら添削していただけると嬉しいです・・・。 func_ethernet() { UserName="UserName" AuthPass="AuthPassWd" PrivPass="PrivPassWd" HostName="localhost" if [ $1 = "send" ]; then LogName="/tmp/log-send" LogOld=`cat ${LogName} | sed -n 2p` LogOldTime=`cat ${LogName} | sed -n 1p` date +"%Y-%m-%d %k:%M:%S" > ${LogName} /usr/bin/snmpget -a MD5 -A ${AuthPass} -l authPriv -u ${UserName} -x AES -X ${PrivPass} -v 3 ${HostName} .1.3.6.1.2.1.2.2.1.16.2 | awk '{print $NF;}' >> ${LogName} LogNew=`cat ${LogName} | sed -n 2p` LogNewTime=`cat ${LogName} | sed -n 1p` echo | awk '{print ( (newValue - oldValue) / (newTime - oldTime) );}' newValue=${LogNew} oldValue=${LogOld} newTime=`date -d "${LogNewTime}" +"%s"` oldTime=`date -d "${LogOldTime}" +"%s"` elif [ $1 = "recive" ]; then 略 fi } rrdtool update ${RRD_PATH}/ethernet.rrd N:`func_ethernet send`:`func_ethernet recive`
329 :
login:Penguin :2009/08/20(木) 12:00:54 ID:3vJ7EKjF
文字色と背景色ついて質問です。 わかりやすく色をつけてみたのですがこの場合は文字の部分のみが緑文字と黒背景となります。 #!/bin/bash echo -en "\033[32;40m"; select i in "123" "456"; do [ -n "$i" ] && break done case "$i" in 123) func123;; 456) func456;; esac 文字ではない部分も黒背景とする事は可能ですか?
まずエスケープシーケンスを直接指定するのはよくない 端末によってサポートされている機能に違いもあるし 「文字ではない部分」の意味も不明 行単位ということなら #!/bin/sh tput setab 0 tput setaf 2 tput el echo "Hello"
331 :
login:Penguin :2009/08/21(金) 00:19:49 ID:F/0U9rwq
文字ではない部分ってのはその通りだろう。 文字の背景の色を指定は出来るが、文字以外のところの背景色はどうすってことじゃね? \033[32;40mはせめて ESC=\033[ midori=${ESC}32 とかにしたほうがいいと思う。もっといい方法あればえらい人が教えてくれるはず。
すみませんが組み込みコマンドだけでお願いします
>>333 busyboxにshとtputが入ってる場合はOK?
>>331 > 文字の背景の色を指定は出来るが、文字以外のところの背景色はどうすってことじゃね?
だから, 画面全体をそうしたければclearすればいいんじゃね
文字を書き込んでいない*どの部分を*背景色にしたいんだ, って話
336 :
331 :2009/08/21(金) 07:39:21 ID:F/0U9rwq
tputなんてあるわけね。
シェルに標準でそういうのあるの知らなかったよ。
>>335 文字がかかれてない場所全部じゃね?
ようは画面全体の背景色を指定したいってことだと思うけど。
文字と文字の背景色は\033[32;40mで指定できるけど
それ以外の全体の背景色という意味だと思う。
338 :
login:Penguin :2009/08/21(金) 11:30:52 ID:90eN5uxA
そういうの意識するほどたくさんの機器がないからだとおもうけど 俺はVT100でだいたい表示されてればOKかな〜とか勝手に思ってる。 ネットワーク機器だとやっぱりまだANSIとかが標準になってたりするのかな? さすがに最近のネットワーク機器でVT52が標準とかってことはないと信じたいけど。
>>336 > ようは画面全体の背景色を指定したいってことだと思うけど。
>>335 行単位なら
>>330 カーソル位置からscreenの最後までならelの代わりにed使えばいい
所謂、ブルースクリーンを作りたい。
# word.lst あいうえお aiueo かきくけこ kakikukeko さしすせそ sasisuseso #target.txt なにぬねの あいうえおキター たちつてと さしすせそ キターかきくけこ word.lst の区切文字はTAB 、またはSPACE とします target.txt を一行ずつ読込み、word.lst のキーとなる単語があれば、 置換しdest.txt に出力するシェルスクリプトの書き方を教えて頂けないでしょうか。 #dest.txt なにぬねの aiueoキター たちつてと sasisuseso キターkakikukeko
まず服を脱ぎます
343 :
341 :2009/08/22(土) 20:44:33 ID:iygx6FPk
while read line do 処理(TARGET=あいうえお、DEST=aiueo) done < word.lst 例えばこのように、line で読込んだ あいうえお aiueo を変数TARGET、 DEST に格納する方法を教えてもらえませんでしょうか。
set $line TARGET=$1 DEST=$2
すぐ書ける簡単なやり方で #!/bin/sh while read from to do echo "s|$from|$to|g" done <word.lst >program sed -f program <target.txt >dest.txt
>>345 さん、お世話になります
掲示していただいたスクリプトでの置換ですが、
>>341 で掲示したファイルの置換は期待通りの結果になるのですが
下記のような内容のファイルだと全く置換できません、なぜなのでしょうか?
#target.txt
CREATE TABLE `利用明細` (
`伝票番号` INTEGER AUTO_INCREMENT DEFAULT NULL ,
`商品ID` INTEGER DEFAULT NULL ,
`数量` INTEGER DEFAULT NULL ,
PRIMARY KEY (`伝票番号`)
);
#word.lst
伝票番号 DENNPYOUBANGOU
数量 SUURYOU
>>346 です
解決しました、文字コードを錯誤してました(^^;
1000文字ごとに改行を入れる簡単な方法を教えてもらえませんか
これ、俺は思いつかない、ラテン文字だけなのか、マルチバイト文字も混在してるのか こういうのは、やっぱ、perlやrubyが得意だ
nkf -f 1000
351 :
login:Penguin :2009/08/26(水) 14:07:13 ID:ehP4IQnp
abcdefgabcdefgabc ... と続く文字列にn文字ごとに「,」を入れてcsvにするにはどうしたらいいですか?
echo abcdefghijklmnabcdefghijklmnh | sed 's/\(.\{5\}\)/\1,/g'
echo 'abcdefgabcdefgabc' | sed 's/\(.\{変数n\}\)/\1,/g'
重複スマソ
とりあえず$OUTはOUTのtypoだよな あとはsedのマニュアルでも読んどけ
また重複してしまった。吊ってくる。 λ..
>>357-358 ありがとうございます.うまくいきました.$OUTはミスです.ありがとうございました.
>>359 ありがとうございます.区切り文字を変えてうまくいきました.
やったね!
UTF-8 BOM が付いててもshスクリプトが動くシェルってある?
スレ違い。
>>364 別にスレ違いじゃないんじゃね?
カーネルで、ファイルの先頭2バイトが'#!'の場合をスクリプトと
しているのでBOMついてたら実行できない。
sourceしたときって意味なら…試したこと無いからわからん。
>>366 シェルスクリプトってexecvできるってことか。てっきりsystemで動かしてると思ってた。
369 :
login:Penguin :2009/08/27(木) 13:09:03 ID:1TOKv6MA
ファイルを読み込んで最後の5行だけ表示したいんだけど 最後の5行ってのをどうすれば計算できますか? とりあえず #!/bin/bash while read LINE; do echo $LINE done < "test.file" ってので行けると思うんですが、行数カウントとかどうすればいいでしょうか?
tail
371 :
login:Penguin :2009/08/27(木) 15:06:58 ID:g/ERTIS/
>>369 一番簡単なのは、tailコマンドに丸投げすること。
初心者だが、シェルスクリプトで書いてみた。
queueを使おうと考えたが、配列の添え字が循環するデータ構造にしてみた。
うまく動きましたよ。
372 :
369 :2009/08/27(木) 15:59:46 ID:1TOKv6MA
#!/bin/bash dat=`tail -n 5 $logdat` SAVE_IFS=$IFS IFS=' ' CNT=0 for BUF in $(cat $logdat) do CNT=$(expr $CNT + 1) done IFS=$SAVE_IFS こうしてみたら cat : **************************** : そのようなファイルやディレクトリはありません とか出るんだけど何故ここで「cat」とか「そのような〜」とか出るのかわからん。 書き方間違ってますか?
よく見てみろ。7行目にcatがあるぞ
374 :
372 :2009/08/27(木) 17:02:32 ID:1TOKv6MA
うげっ! めちゃめちゃ初歩的ミスやらかしてる 修正してうまく動くようになったです。 恥ずかし・・・
375 :
364 :2009/08/29(土) 04:48:03 ID:oAtS9pnj
レス遅れましたが、ありがとうございます
>>366 bash等ではなくてカーネルに依るとは分かりませんでした。
winだとBOM付ける方がスタンダードっぽい
のでどうにかなるか、考えたもので。
>>375 >winだとBOM付ける方がスタンダードっぽい
SJISだろSJIS。
while [ 1 == 1 ] がキモイ。trueでええやん。
while :
grepは検索に一件もひっかからなかったら、何も返してきませんよね if [grep ほげほげ != ""] とnullと比較したいのですが、実行すると文句を言ってきます grep -c ほげほげ = 0とすることもできますが、勉強のために書いているので それはさけたいです 初歩的な事ですいません、ぜひエロい方に教えてもらいたい
381 :
login:Penguin :2009/09/10(木) 23:27:42 ID:kkfd/kxq
>>380 くだ質の人?マルチポスト乙。
とりあえず、もっと基本的な事を勉強した方がいいと思うよ。
grep .......
if [ $? ]; then
echo "マッチ成功"
else
echo "マッチ失敗"
fi
382 :
login:Penguin :2009/09/10(木) 23:35:17 ID:kkfd/kxq
>>380 あー、すまなかった。
>実行すると文句を言ってきます
どう文句言われるのかを書かないとね。
たぶん、[grep ほげほげ != ""] を [ grep ほげほげ != "" ] にすればうまく動くと思う。
'[' と ']' との間にはスペースを入れることに注意。
実は [ ] はコマンドだから、スペースを入れないと式が引数として扱われない。
こう説明すれば理解できるだろうか。
以下の(1), (2)は等価である。
(1) if test -f /etc/passwd; then 文; fi
(2) if [ -f /etc/passwd ]; then 文; fi
383 :
login:Penguin :2009/09/10(木) 23:41:36 ID:kkfd/kxq
コマンドじゃねーや。間違い。 ところで全角スペースがあるのが気になるのだが、そこは大丈夫なのか?
>>382 > 実は [ ] はコマンドだから、
[ がコマンド。(bash の内部コマンド)
> こう説明すれば理解できるだろうか。
かえって混乱するんじゃね。
[ は内部コマンドではない
cshです。 a.cshの実行中にb.cshを実行したいです。 で、a.cshで宣言した変数をb.cshでも引き継ぎたいのです。 さらに、b.cshに引数を渡して実行したいのです。 a.cshの実行中に csh b.csh だと引数をつけて実行できますが、変数が引き継がれないようです。 source b.cshだと変数は引き継がれますが、引数をつけて実行できません。 どうしたらいいのん。
/usr/bin/[の方も、昔は/usr/bin/testへのハードリンクだったが 今は違うんだな。やっぱり日々勉強しないと…
>>387 >source b.cshだと変数は引き継がれますが、引数をつけて実行できません。
引数をつけて実行できるんじゃない?
::::::::::::::
a.csh
::::::::::::::
#!/bin/csh -f
set val="hello"
echo "a.csh:$* $val"
source b.csh 1 2 3
echo "a.csh:$* $val"
::::::::::::::
b.csh
::::::::::::::
#!/bin/csh -f
echo "b.csh:$* $val"
% ./a.csh
a.csh: hello
b.csh:1 2 3 hello
a.csh: hello
391 :
login:Penguin :2009/09/14(月) 22:11:59 ID:VDeHYP1G
#!/bin/bash trap "logoutfunc_ctrl; logout" 1 2 3 15 最初の2行にこう記述してるんですが、logoutせずにプロンプト画面に戻る方法がありますか? bashにこのシェルを書いているのでログイン後は必ずこのシェルが立ち上がるようになってます。 このシェルを実行するのは特定のユーザーのみで、他にこのシェルがあるサーバーにログインは出来ません。 (他のユーザーはrootを除いて全てログイン出来ないようにしてます) プロンプト画面には触らせないようにしたいのですが、これでプロンプトに抜けれるという人がいるので どういった方法があるのか教えていただけないでしょうか。
なんかよくわからんけど ログインシェルを変えちゃったら。
393 :
login:Penguin :2009/09/14(月) 23:18:36 ID:DAW4cbiO
trapでlogoutしてるのにそんなこと出来るの? おれも悪さされないようにtrapでlogoutしてるからもしそういう抜け道あるなら対策したいな。
SIGTSTPもそうだけど、普通にbash起動できたりしないの?
現在、/ 配下に次のディレクトリがある(CentOS 5.3)。 bin boot dev etc home lib lost+found media miscmnt net opt proc root sbin selinux srv sys tmp usr var で、例えばの話なんだけど、/var以下と/etc以下のファイルで72時間以内に更新されたファイルだけを検索するために、 /var以下と/etc以下だけを検索するんじゃなくて、/varと/etcの両ディレクトリ以外を検索対象から除外した上で / を検索する、という手法をとる場合、次のようなワンライナーが考えられる(改行してるけど実際は一行)。 find / \( -path '/bin/*' -o -path '/boot/*' -o -path '/dev/*' -o -path '/home/*' -o -path '/lib/*' -o -path '/lost+found/*' -o -path '/media/*' -o -path '/misc/*' -o -path '/mnt/*' -o -path '/net/*' -o -path '/opt/*' -o -path '/proc/*' -o -path '/root/*' -o -path '/sbin/*' -o -path '/selinux/*' -o -path '/srv/*' -o -path '/sys/*' -o -path '/tmp/*' -o -path '/usr/*' \) -prune -o -type f -mtime -3 -print で、これを find / $OPT -type f -mtime -3 -print と書くために、 OPT=\( -path '/bin/*' -o -path '/boot/*' -o -path '/dev/*' -o -path '/home/*' -o -path '/lib/*' -o -path '/lost+found/*' -o -path '/media/*' -o -path '/misc/*' -o -path '/mnt/*' -o -path '/net/*' -o -path '/opt/*' -o -path '/proc/*' -o -path '/root/*' -o -path '/sbin/*' -o -path '/selinux/*' -o -path '/srv/*' -o -path '/sys/*' -o -path '/tmp/*' -o -path '/usr/*' \) -prune -o とシェル変数を定義する(改行してるけど実際は一行)。で、次を実行するとエラーとなる。 # find / $OPT -type f -mtime -3 -print find: パスは評価式の前におかなければならない Usage: find [-H] [-L] [-P] [path...] [expression] これ、エラーになる原因と対策方法分かる人いたら誰か教えて。
397 :
login:Penguin :2009/09/17(木) 16:45:22 ID:HEpWOKWA
>>396 とりあえずecho $OPTして良く考える。
でも目的からいって find /etc /var ... でいいと思うんだがなんでそんなめんどくさいことするの?
次のようなワンライナーが考えられる、って書いてあるし 宿題じゃないの
400 :
login:Penguin :2009/09/21(月) 16:40:00 ID:nYMA5TsQ
>>396 の方法の是非は置いといて、
一気に難しい事やろうとしてダメな場合にそのままデバッグしようとする姿勢からして間違ってるのね
最も確実にできる単純な所からOKなのを確認しつつ、少しずつ複雑化していけばいいのにね
単純化もせずにここにポストしちゃうのもダメなのね
>>396 > エラーになる原因
> OPT=略 -prune -o
-prune と -o は、OPT= って式の右辺とは認識されていない。
402 :
login:Penguin :2009/09/22(火) 21:32:32 ID:tUDMNFi9
WinでSJISだろSJISって言った人は誰ですか 無知はレスしなくていいと思うぞ
shでプロセス置換をすることはできますか?
exec ?
bashの<(hoge)のようなやつです
普通のshにはないんじゃないかな。実はshという名前でも実体はbashという こともよくあるが。ないときはmkfifo使えばなんとかなりそう。
>>406 mkfifoを使ってみます。
ありがとうございます。
一行目の #!/bin/sh みたいな表記ってなんていうんだけ?
ホラ吹きはやめなはれ
shebang
あるフォルダの中のフォルダのうち中身が空のフォルダをまとめて削除するにはどうすればいいですかね?
find あるフォルダ -type d -empty かな
find . -type d -exec rmdir --ignore-fail-on-nonemytp -p {} \;
418 :
login:Penguin :2009/09/27(日) 18:36:06 ID:251MLAqQ
>>417 rmdir: failed to remove `.': 無効な引数です
とのことでした。。
>>416 rm -r `find . -type d -empty`としたら期待通りの動作をしてくれました!
有難うございました。
何も言うまい
420 :
login:Penguin :2009/09/27(日) 21:31:53 ID:qHK4F1Gh
ストリームから特定のバイト数分だけ読み出すことは出来ますか? 例えば標準入力の先頭1024バイトだけ読みたいのですが、readやらheadでは できないみたいでつ。 外部の処理系に投げるしかないのでしょうか。
421 :
login:Penguin :2009/09/27(日) 21:33:25 ID:qHK4F1Gh
すみません head -c 1024 で事故解決しました。
422 :
login:Penguin :2009/09/28(月) 12:47:00 ID:VZAZLgKn
Bash で並列処理はできますか? バックグラウンドでプロセスを実行する方法が考えられますが 標準出力を変数に代入できません。 スレッドみたいなものがあればいいのですが。 アドバイスよろしくです。
>>422 凝ったことやりたいならちゃんとした言語使った方がいいんじゃないの。
>>422 標準出力の代わりにファイルを利用するだけでいいと思うけれど
何か制限とかあるの?
426 :
422です :2009/09/28(月) 22:48:49 ID:ZC7KG7rU
>>424 それも考えたのですが、ちょっとアレゲな文字列を渡したいので
なるべく標準入力経由で流し込めたらいいなーと。
>>425 waitするのはいいのですが、
s=`sleep 10; echo hi` &
これだと、確かにバックグラウンドで実行されますが、出力が変数sに代入されません。
とりあえずtmpfile作ってお茶を濁すか、
スレッドをサポートしている他の言語で書いてみます
ありがとうございました。
アレゲな文字列だとなぜ標準入力にしたいのだろう??
fifoが使えれば便利なんだけどな。
429 :
login:Penguin :2009/10/23(金) 00:04:27 ID:wj32ZQ75
bash@sygwinです。 echo -e `hoge.exe` みたいなスクリプトを書いて実行した場合、 hoge.exeの出力(標準出力へ出力)が改行されないのですが、 開業して表示されるようにするにはどうしたらいいですか?
hoge.exe
431 :
429 :2009/10/23(金) 00:07:47 ID:wj32ZQ75
サンプルとして hoge.exeとしましたが、 実際は引数をとるプログラムであり、そのためにスクリプトを書いています。
printfでおk
In the case of a clock it is, of course, infinitely unlikely. ,
>>429 | と nkf か iconv かなんか使って
改行コードを変換すればいいかと。
要するに、 $ echo `ls` で改行されないと言ってるんじゃないの? 素直に $ ls と打てカス じゃ駄目か。
echo "`ls`"
And you get to travel to interesting places and talk to interesting people about interesting questions. ,
Yes I like rice ball.
This is a Tom
441 :
login:Penguin :2009/11/04(水) 22:54:27 ID:MYi0pRqJ
Bash シェルスクリプトで、 実行後にコマンドラインに文字列を入力した状態にするのは 可能ですか? $ ./x.sh $ abc ←'abc' が入った状態にする シェルスクリプトでなくて、C とかでもよいですが。
>実行後にコマンドラインに文字列を入力した状態にするのは set ? >$ ./x.sh >$ abc ←'abc' が入った状態にする read ?
443 :
441 :2009/11/05(木) 19:29:56 ID:gkVZzLQn
x.sh が終了した後に、 コマンドラインにキーボードで 'abc' と入力した状態になっている という意味あいです。
それ、もしできるのなら セキュリティ的にマズーくないか?
446 :
login:Penguin :2009/11/06(金) 08:33:57 ID:mW6ePEE5
小数点第三位くらいの数値を1000で割りたいのですが、bcで計算すると0.123456が.123456にされてしまって正しくrrdtoolに値を渡せなくて困っています。 どなたか対策をご存知の方がいらっしゃいましたらご教授頂けないでしょうか。
448 :
441 :2009/11/06(金) 19:41:15 ID:/t9QHrwg
>445
ctrl-r で、history のリストから検索して、
ctrl-e とすると、実行ではなく編集になりますよね、
あれがやりたかったんです。
ただ、その検索の部分を(例えば)grep で検索したり、
選ぶ部分をメニュー形式というか対話型にしたり、(その他もろもろ)
結果を実行ではなく、編集にしたい。
なので、シェルスクリプトとかで実行した結果をコマンドラインに
入れられないかなと思ったんです。
ちと無理だったかな。
>>442 ,444,445 どうもです。
eshell使えば
>>448 コマンドラインに戻す必要あるのかな。
そのアプリの中で編集させて実行しちゃえば?
>>448 bashなら、↓で実現できないかな?
$ cat hoge.sh
echo `date` >> ~/.bash_history
$ sh hoge.sh
$ history -r
$ history | grep 2009
15 2009年 11月 6日 金曜日 21:37:38 JST
16 history | grep 2009
$ shopt -s histverify
$ !15
2009年 11月 6日 金曜日 21:37:38 JST
(histverifyがonだとカーソルはコマンドラインの行に位置したままで、編集可)
# 嘘書いてるかもしれんので、間違ってたら指摘求む
最初に HISTFILE=/tmp/.bash_history とかして一時ファイルにしたほうがよいかも
質問。環境はbashです。
URLをテキストファイルに溜め込むスクリプトを作りたくて
弄りはじめたんですが、詰まってしまったので‥ 他力本願!
希望する結果:
$echo ${URL} > url.txt
$cat url.txt
http://aaaa.co.jp http://bbbbaaa.com としたい。
#!/bin/bash
NUM=0
while [ ${NUM} -lt 5 ]
do
URL=`zenity --entry "$1"`
NUM=`expr ${NUM} + 1`
done
URLに複数の文字列を溜め込みたいのですがどうするべきでしょうか?
ググってみると配列?というやり方があるようなのですが、まだ理解できません
教えてください。
>>453 zenityって何のこっちゃ。配列を使うとこうなる。
$ URL=("foo" "bar")
$ for url in ${URL[@]}; do echo ${url}; done
foo
bar
…が、単に${URL}に空白区切りのURLを入れておいて、
sedなりtrなりを通して1行ずつ出力すれば良いだけの話ではないのか?
$ URL="foo bar"
$ echo ${URL} | sed 's; ;\n;g'
foo
bar
$ echo ${URL} | tr ' ' '\n'
foo
bar
>>454 >zenityって何のこっちゃ。
なんか便利そうだなぁと思ってw
zenity使わんでもいいんだけど、常に端末開いてるわけじゃないから操作的に楽かなぁと‥
んで、溜め込むURLは決まってるわけじゃなくて、ブックマーク的な感覚で使うつもり。
$ URL=("foo" "bar")
は、わかったけど
$ for url in ${URL[@]}; do echo ${url}; done
は、${URL[@]} を 一行づつ url に代入して、それを一行づつ出してるってこと?
ってことは、って考えた結果
while [ ${V_NUM} -lt 5 ]
do
URL=("${URL[@]}" `zenity --entry "$1"`)
V_NUM=`expr ${V_NUM} + 1`
done
echo "${URL[@]}"
a b c d e と順に打っていったら
$ echo "${URL[@]}"
a b c d e
と返ってきた。
結果だけみると動作してるように見えるけど、合ってますか?
なんとなく配列のイメージはわかったような気がする・‥
# sed とか 正規表現 とか覚えたら色々出来そうだ。。。と夢見てる段階w
>>455 配列の話をしているからbash前提で話すが、
・zenityが返す値(URL)を""でエスケープしておかないと、URLにスペースが含まれていたときにハマる。
・単純に5回繰り返すだけならwhileとカウンタを使うよりもforを使ったほうがいい。
for i in {1..5}; do [処理]; done
for i in `seq 5`; do [処理]; done
>>456 なるほど。わざとスペースを入れて試してみました。
単純に5回繰り返すつもりなので、アドバイス通りにfor文でもやってみたいとおもいます。
>>454 >>456 どうもありがとうございました。
bashの配列なのですが # ls お宝動画 有名女優の秘部大百科 というファイルがあって files=(`ls`) echo "${files[0]}" とすると「お宝動画」しか表示されませんよね これをちゃんとしたファイル名、空白を含む値を代入するには どうすればいいのでしょうか?
>>458 IFSがデフォで空白・タブ・改行になってると思うので
IFSから空白を除く
そのファイル名の部分をもっと当たり障りの無いファイル名に変えて書けよww
Bachで条件付バックアップスクリプトを組みたいのですが どう書いて良い物か分からなくなってしまったのでご教授 お願いします。 < やりたい事 > 任意のフォルダ配下でタイムスタンプがN日経過したものをtar.gzで 圧縮して、そのファイルを削除したい。 たとえば、/home配下に test1・test2・test3と言う3つのフォルダがあって 最終アクセス(ファイル操作)が30日以前のファイルを/home/backupに タイムスタンプ.tar.gz形式で保存し、バックアップ後そのファイルを削除する。 test1フォルダ内 -rw-rw-r-- 1 root root 10K 10月 09 00:00 /home/test1/hoge.txt -rw-rw-r-- 1 root root 10K 10月 10 00:00 /home/test1/higetxt tes21フォルダ内 -rw-rw-r-- 1 root root 10K 10月 11 00:00 /home/test2/hoge.txt -rw-rw-r-- 1 root root 10K 11月 01 00:00 /home/test2/higetxt test3フォルダ内 -rw-rw-r-- 1 root root 10K 11月 09 00:00 /home/test3/hoge.txt -rw-rw-r-- 1 root root 10K 11月 11 00:00 /home/test3/higetxt n日後のファイルを検索するところまで調べて下記のようなコマンドを 使うのだろうと思っているのですが、それ以降どうしてよいものか・・・・。 find /home -type f -daystart -mtime +30 |fgrep -v /. 長くなりましたがご教授お願いします。
教授は外出中です
バッハねぇ。
>>461 TARGET=`find /home -type f -daystart -mtime +30 |fgrep -v /. `
tar cvzf `date +%Y%m%d`.tar.gz $TARGET && rm $TARGET
466 :
login:Penguin :2009/11/13(金) 11:55:23 ID:YoLOfEvP
test=/var/www/.htaccess-log という風にしても-logのみが認識されているようでうまく機能しません。 最初に.がある場合のファイルを変数に入れるにはどうすればいいのでしょうか?
$ test=/var/www/.htaccess-log $ echo $test /var/www/.htaccess-log $ 認識してるが。
468 :
466 :2009/11/13(金) 12:09:11 ID:YoLOfEvP
>>467 すいません。
testの部分がtest-logでした。
$ test-log=/var/www/.htaccess-log
$ echo $test-log
-log
となります。
申し訳ないです。
>>468 変数名に-(ハイフン)は使えないと思ったが
470 :
466 :2009/11/13(金) 12:45:36 ID:YoLOfEvP
>>469 すいません。
そうなんですか。
最近WEB関連からシェル叩くことがあって作ってたんですがシェルでは変数にハイフン使えないんですね。
修正したらうまくいきました。
ありがとうございます。
区切りたいなら _ 使え。
>>466 >>5 >・思い通りに動かないときは、まずは sh -x でトレースしましょう。
[ string ] と、[ -n string ] の違いについてお尋ねします。 [ $(cat /dev/null) ] が偽になるのに対して、[ -n $(cat /dev/null) ] は真になってしまうのですが、何が違うのでしょうか。 [ -z $(cat /dev/null) ] は真になるので、なんだか -nだけが仲間外れな気がします。
>>473 それだと $(cat /dev/null) が消えて引き数がなくなって
[ ]
[ -n ]
[ -z ]
になる。
なんでそういう挙動になるかは bash の test.c でも読んでもらうとして、
その挙動を避けるには
[ "" ]
[ -n "" ]
[ -z "" ]
にすればいい。
475 :
473 :2009/12/07(月) 13:46:33 ID:5UzhKh29
>>474 なるほど納得です。
そう言えば変数が空文字列になってしまう場合を考慮してクォートしろと聞いた記憶があるような気がします。
素早いお返事ありがとうございました。ソースもあとで読んでおきます。
476 :
login:Penguin :2009/12/13(日) 00:31:23 ID:h59G/AZL
よくダウンロードとかすると何%まで完了してるかみたいなのを 動的に出力するのってどうやんの?
普通に wget でいいんじゃない?
478 :
476 :2009/12/13(日) 02:23:19 ID:h59G/AZL
>>477 ダウンロードに限らず
yumとかbuildするときに%を示す数値が動的に変わっていくじゃないですか。
あれ、どうやって実装してんのかなぁと。
誰かわかる?
>>478 バックスペースを然るべき回数売って表示し直し
画面制御の話題だったの? このスレ的には tput あたりでやるのが正しいのだろうか。
>>478 $ man console_codes
このスレ的には dialog とか whiptail じゃないの。
普通の文章を書いた平文テキストをxtermに関連付けして開くと 実行権もないのにxtermがいくつも開いてフリーズします。 なぜですか?
「関連付けして開く」ってどういう概念?
普通は表示とか端末で実行とか聞かれるので、右クリメニューに入れました
Ubuntu使ってるの?
>>486 ごめん。尋ねておいて悪いけど、
「関連付けして開く」や「右クリメニューに入れ」るってのが判らない。
なので助言できない。
>>484 Windowsの関連づけの感覚?
GNOMEであれば、プロパティから開くアプリ指定してるとかってことか?
試しにユーザーを新しいの作って再現するかどうか試してみたら?
もし再現できなければ ~/.gconf* ~/.gnome* とか退避して削除してログインしなおしてみるとか。
内容からして、くだ質のほうがアドバイスもらえると思うよ。
>>484 「xterm を起動できるかどうか」は
「xterm を実行する権限があるかどうか」で決まることだから、
「平文テキストを実行する権限」とは関係ない。
$ xterm /tmp/hoge.txt とかやると、
No absolute path found for shell: /tmp/hoge.txt
とかいったメッセージは出るけれど、xterm が起動する。
関連付け はよくわからないけれど、
テキストファイルをまとめて開こうとすれば、
ファイルの数と同じだけ xterm が一気に起動する ってことは想像できる。
CPUとか メモリ/swap とかが足りなければ、フリーズみたいな状況になるかもしれない。
492 :
login:Penguin :2010/01/05(火) 20:34:00 ID:nuI9c99Q
bashで手軽にオブジェクト指向モドキする方法ってありませんか? とりあえず試みたのですが、スッキリしません。 #!/bin/bash gal(){ eval "$1"_name="$2" eval "$1"_age="$3" eval "$1"_sex="$4" } aisatsu(){ eval echo "私は\"\$"$1"_name"、\"\$"$1"_age"歳です。よろしく ね。" } hanasu(){ eval echo "\"\$"$1"_name\"に何の用?" } gal "yuka" "由佳" "16" "女" aisatsu "yuka" hanasu "yuka"
>>493 すごいものがあるんですね。
ありがとうございました。
テキストファイルで、指定した文字列を含む最初の行を開始位置とし、先とは別の 文字列を含む行が見つかるまでを削除するにはどうすれば良いでしょうか?
>>495 ありがとうございます。
sedというのは強力なんですね。
>>498 文字/行削除程度しか知らない初心者にとっては、超強力。
500 :
497 :2010/01/08(金) 23:16:45 ID:KgmcRvHm
shの変数を
>>496 の/xxx/に使いたい場合についてお伺いします。
path=/aaa/bbb
sed "/$path/,/yyy/d"
の様にしても$pathが展開された時点で区切り文字がエスケープされておらず上手く
いきません。
前処理が必要なのか、それともスマートな方法が用意されているのでしょうか?
ファイル名はNUL文字以外なら全て使えるんだよね。 ということは、前処理の段階で区切り文字をエスケープする必要があるのかな。
502 :
497 :2010/01/08(金) 23:38:17 ID:KgmcRvHm
やはり自前で前処理するわけですね。 sedで簡単に出来そうですね。
503 :
497 :2010/01/08(金) 23:51:05 ID:KgmcRvHm
下でできました。 #!/bin/sh -x var=/aaa/bbb esc=$(echo $var | sed -e 's/\//\\\//g') $()の代わりに``を使うとパイプがあるせいか上手くいきませんでした。 実際はどうなのでしょう? 教えて頂けると嬉しいです。
sed "/\\$path/,/yyy/d" はどうなの?
区切り文字を変えるんだよ! sed '\@foo@,\@bar@d'
506 :
497 :2010/01/09(土) 00:07:36 ID:WfSq+WCG
>>504 それだと$pathの先頭にのみ区切り文字がある場合にしか対応していないと思います。
>>505 そういうときに使うのですね。
なるほど。
ありがとうございました。
com1 | com2 | com3 の様なとき、どこかでエラーが起こった場合に、それを知ることはできないでしょうか? bash3.0以降だと${PIPESTATUS[@]}で可能なようですがshでなんとかならないかと。
subshellを使って、 (( com1 判定)| com2 判定 )| com3 みたいな事を見た憶えがするけど、定かでない。
509 :
初心者 :2010/01/13(水) 23:30:52 ID:9IUNZoL1
run.shファイルの中で、script_file.shをsourceした場合。 sourceされているscript_fileの中でscript_file自身の絶対パスを得る方法を調べています。 bashの場合はscript_fileの中で$BASH_SOURCEから得られるが、他のシェル(zsh/tcsh/ksh)でscript_file.shのパスを得られる方法を 教えていただけませんか? >>>>>>>>>>>>>>>>>>>>>> script_file.shファイルのある場所 /path/to/script_file.sh >>>>>>>>>>>>>>>>>>>>>> 実行例: %./run.sh 期待結果: /path/to/ ファイル <run.sh>の中身 ------------- #!/bin/(sh/zsh/tcsh...) source $path/script_file.sh ------------- ファイル script_file: ------------- script_file_path=`******` echo $script_file_path; -------------
>>509 機能知らない分際で答えるとさ
単純に呼ぶんだからさ
source "$path/script_file.sh" "$path/script_file.sh"
とか引数として渡してecho $1とかしても
できちゃったりはするね
期待結果は/path/to/だったかorz ならsource "$path/script_file.sh" "$path" でまぁできるといえばできてるけど
/が抜けてたねorz
>>507 気になったので書いてみた
>>508 氏が言ってるようにもっと楽にできるんだろうけど
ちなみに頭悪いので間違ってる可能性ありと
使い物になってないと思うから 一応動いてるかも程度
function perror(){ stdout=`mktemp`;stdout2=`mktemp` first=on until test 1 -eq $# #引数一個の場合は何もしないので注意 do if test $first = on then first=off $1 1>$stdout 2>/dev/null judge=$? fi if test $judge -eq 0 then if ! test 2 -eq $# then $2<$stdout 1>$stdout2 2>/dev/null judge=$? shift else #最後は標準出力へ $2<$stdout #最後のcommandの失敗は判定してないので注意 shift fi else echo "$1" error 1>&2 break fi stdout_hold=$stdout # 入れ替え stdout=$stdout2 stdout2=$stdout_hold done rm $stdout $stdout2;unset stdout stdout2 stdout_hold first judge }
perror 'ls /usr/bin' 'sed 's/^/test/g'' 'grep gcc' less perror 'ls /usr/bin' 'sed 's/^/test/g'' 'tar xf' less まぁ一応動いてるのかな!?
sed -e '$-3,$d' file とすると sed: -e expression #1, char 2: unknown command: `-' というエラーがでます。 versionは4.1.5ですが上記の使い方間違ってますか?
vi じゃないんだからそんな指定できないよ
>>507 エラーが起こったかどうか *見えればいい* ってだけならこんなやりかたも。
(com1 ; echo $?>/tmp/test.log) | (com2 ; echo $?>>/tmp/test.log) | 略
(com1 ; xmessage com1:$?&) | (com2 ; xmessage com2:$?&) | 略
>>519 -nの値に負の数を与えられるんですね。
ダブルクォーテーションで囲まれた文字列を抜き出すってどうやればいいんだ? cutでもexprでも俺には無理だった、絶対サクッとできるはずなのに悔しすぎる…
grep -o '"[^"]*"'
1日限定かい。
$ df -h /tmp Filesystem Size Used Avail Use% マウント位置 tempfs 512M 89M 424M 18% /tmp の%の前の数字(ここでは18)だけ取り出したいんだけど、どうすればよいですか?
awk使う
とても安直な方法なので最適解には程遠いと思いますが df -P /tmp | grep '/tmp$' | awk '{print $5;}' | sed 's/%$//'
529 :
526 :2010/02/07(日) 19:06:47 ID:dchTEc3Z
>>527 おまwww
df -h /tmp | awk '/\/tmp/ { print gensub("%", "", "", $5) }'
いやそれくらい知ってる
複数行のキーワードをfgrepする手はないスか? キーワードの行数は不定。以下例では仮に2行とします。 $ cat -n text 1 abcdefg******* 2 [hijklmn-z] 3 abcdefg******* $ fgrep 'abcdefg*******なんとか[hijklmn-z]' text text:1:abcdefg******* text:2:[hijklmn-z] 1と2行目のペアはヒットするが、3行目がヒットしてはいけない。
532 :
531 :2010/02/07(日) 19:32:00 ID:Fd1qGpin
ああっと。 上の検索コマンドはgrepファミリーでなくても良いですが、perlは駄目です。
宿題は自分でやれよ
#!/bin/bash AWKFILE="/tmp/$0.$$" trap "rm -f ${AWKFILE}" 0 KV=0 echo "BEGIN{s=0;h=\"\"};" > "${AWKFILE}" for keyword in $*; do echo "/${keyword}/{if (s==${KV}){s=s+1;h=h NR \"\\t\" \$0 \"\\n\";} else {s=0;h=\"\"}};" KV=`expr ${KV} + 1` done >> "${AWKFILE}" echo "{if (s==$#){print h;s=0;h=\"\";}};" >> "${AWKFILE}" awk -f "${AWKFILE}"
いろいろ残念な部分があるけど、そこは使う人が直してね
>>534 んー。やっぱりスクリプト生成みたいになりますか。
私以外の人が考えてもすっきり行かない事が解りました。ありがとうございます。
>>533 この手の宿題を出す学校はあまり無いんじゃないかな。
自分でできない部分だけ聞きなよ
>>536 質問に答えようとしてない奴の発言にはいちいち反応するな。
「教えてくれ」ってやつと「宿題は自分でやれ」ってやつは
「歩み寄る可能性がない」からスルーしたほうがいい。
専ブラ使える環境なら、NGワードに「宿題」って単語を入れておいたほうがいいよ。
>>531 はいろいろ引っかかる部分があるから正直俺も最初は回答しようかどうか迷ったぞ
返事を聞いて
>>538 も出てああやっぱりかと思ったし...
と戯言はここまでにしとく
>>537 >自分でできない部分だけ聞きなよ
すっきりと実現できなかったので尋きました。というか、
往々にしてこの手のことを実現すると車輪の再発明になってしまってる事が多い。
なので、他の人も決定的な車輪を持ちあわせていないという情報はとても大切で、
有難く思っています。
典型的なゆとり脳というか なんでこんな上から目線なんだろ そういうのは自分で書いたの張ってから言えよ
>>540 実現できたなら実現方法そのものを聞く必要はない
実現方法を提示してより良くするにはどこを直せばいいか聞けばいい
他人のコストは格段に違うだろうし、回答も違ったものになる
というかお前
>>526 だろ?
543 :
526 :2010/02/07(日) 23:05:32 ID:sirvd3yi
こらこらw 静観してる俺まで巻き込むなよ
>>542 そうですね。その点は気をつけたいと思います。
>というかお前
>>526 だろ?
いや違う。
むしろ、
>>529 (526)にしろあなたにしろ"/tmp"をマッチさせている時点で、要求条件から逸脱していると思っている。
ID変えながら大変ですね。元に戻せないの?
どうやって戻すんだよw
昼間寝ていたら正規表現使う夢を見た気がする、なぜだ
同じIPが取れるまでトライ!(やったことないので同じになるのか知らん)
U7v7s3zMが取れるまでトライし続けてるのかなw
答えてもらっておいて「まあそんなもんだよね」 これはひどい
複数の数字に,同じ四則演算(+,−,*,/)を繰り返した計算結果を表示するシェルスクリプトを,cshシェルスクリプトで書け。 (基本仕様) @ コマンドとして実行できる.(シェルコマンドである.) A 入力した数字を計算できる. B 入力できる数字の個数は2以上とする. C 四則演算子(+,−,*,/)を選択,または直接入力して 数字1□数字2□・・・□数字N (□=+ or − or * or /,N≧2) の計算結果を出力する. D 四則演算子以外の記号が入力された場合,エラーメッセージを出力する. (ポイント) ? シェルコマンドにするには,スクリプトの最初に(#!で始まる)おまじないを書く. ? 標準入力から文字列を入力するには $< を用いる. ? コマンドラインに引数を指定した場合は,その引数は変数$argvに格納されている.その各要素を参照するには,$argv[1],$argv[2](または$1,$2)などとする. ? 四則演算には @ コマンドが使用できる.(ただし,整数しか扱えない.) 誰かわかるひとおねがいします(今週中にお願いします!)
何箇所でマルチしてんだよwww
554 :
sage :2010/02/08(月) 17:06:29 ID:kDoV0MXx
宿題は自分でやろうね。
後から読んで526にワロタ カワイソスw
df -h /tmp | sed 's/.*\([0-9][0-9]*\)%.*/\1/'
557 :
login:Penguin :2010/02/20(土) 23:34:54 ID:vDEbYPUT
以下の結果を出力するシェルを,bashスクリプトで書け. (基本仕様) ・コマンドとして実行できる.(シェルコマンドである.) ・ユーザーが10000以上99999以下の5桁の数字を入力する. ・その数字を7で割って1余り,かつ13で割って2余った場合は Daikichiと表示する. ・それ以外で,13で割って2余った場合は Chuukichiと表示する. ・それ以外で,7で割って1余った場合は Shoukichiと表示する. ・それ以外の場合は Hazureと表示する. ・入力した文字が10000以上99999以下の数字以外の場合はエラーメッセージを表示する. ・できる人は,コマンドライン引数でDaikichiなどの文字を変更できるようにする. (ポイント) ☆シェルコマンドにするには,スクリプトの最初に(#!で始まる)おまじないを書く. ☆標準入力から文字列を入力するには read を用いる. ☆コマンドラインの引数は,$@に格納されている.(その要素は $1 $2 ...) ☆四則演算には $(( )) コマンドが使用できる.(ただし,整数しか扱えない.) 誰かわかるひとお願いします
>>557 > 誰かわかるひとお願いします
まぁ、Linux使える人ならば、誰でも分かる
"学校" の課題ですわな(w
# "学校" は 大学 でない。
シェルスクリプトの課題を出す学校ってあるんだね。 ふつーは、CとかJavaを中心にやるものだと思ってた。
560 :
login:Penguin :2010/02/21(日) 00:00:05 ID:WDiWxw8N
#!/bin/bash read read echo $((read%3))`echo 5p$(echo e$(echo l5b$(echo 6M5)q2)744$(echo GsCg$(echo =$(echo =))))|base64 -d`
死ねばいいのに
何をお願いされているのだろう。アンケートかな? 回答「わかります」 上から2桁目で四捨五入したい(例: 15 -> 20, 312 -> 300, 9432 -> 9000) どうやるのが一番簡単かな?
563 :
login:Penguin :2010/02/21(日) 00:39:34 ID:y6fTjKHz
10を底とした対数とって 1.5*10^1 3.12*10^2 9.432*10^3 仮数部を小数点以下で四捨五入する
564 :
login:Penguin :2010/02/21(日) 01:05:26 ID:y6fTjKHz
全然対数じゃないや
>>557 お前UNIX板のシェルスクリプトスレでも宿題は自分でやれって言われてただろ
マジで死ね
566 :
login:Penguin :2010/02/21(日) 02:00:25 ID:y6fTjKHz
$ echo 'x=9432; beki=l(x)/l(10.0); scale=0; beki/=1; scale=10; y=x/(10^beki); y+=0.5; scale=0; y/=1; y*=(10^beki); scale=0; y/=1; y;' | bc -l 9000 一応、15, 312, 9432 については期待の値になった。
568 :
login:Penguin :2010/02/21(日) 08:29:04 ID:y6fTjKHz
違うかね?
4432613 = 4.432613 * 10^6
→ 4.4*10^6 → 4.0*10^6 = 4000000
>>562 さんに聞いてみようか。
入力4432613での期待値は、
上から2桁目の"4"で四捨五入して、4000000 でよろし?
3桁目の"3"でして、4400000 ではなくて。
569 :
login:Penguin :2010/02/21(日) 09:26:12 ID:y6fTjKHz
少しコメント入れました。ダメな場所はどなたか直してください。 echo 'x=4432613; # x=y * 10^d 表現にする d=l(x)/l(10); scale=0; d/=1; scale=1; y=x/(10^d); # yの小数点第一位を四捨五入して整数に。 y+=0.5; scale=0; y/=1; # 元の桁数に戻す。 z=y*(10^d); z; ' | bc -l
570 :
login:Penguin :2010/02/21(日) 11:49:45 ID:y6fTjKHz
アプローチを変えて文字列処理にしてみた $ echo 4432613 | perl -npe 's/^(\d)(\d)(\d+)/$1+($2>4) . 0 . 0 x length($3)/e;'
571 :
login:Penguin :2010/02/21(日) 12:23:46 ID:y6fTjKHz
$ echo 15 | perl -npe 's/^(\d)(\d)(\d*)/$1+($2>4) . 0 . 0 x length($3)/e;'
572 :
login:Penguin :2010/02/21(日) 13:04:19 ID:y6fTjKHz
#!/bin/ksh v="$1" a=${v:0:1} b=${v:1:1} c=${v:2} [ $b -gt 4 ] && a=$((a+1)) b=0 c=$(echo $c | tr 0-9 0) echo "$a$b$c"
ん、よくわからんけど…… 乙 w
574 :
562 :2010/02/21(日) 19:12:39 ID:R8eJDQx8
なんかすごいものがw
>>568 >入力4432613での期待値は、
>上から2桁目の"4"で四捨五入して、4000000 でよろし?
よろしです。
パッと見で
>>571 がスマートですね
シェルからこいつを呼ばせて貰おうと思います
ありがとうございましたm(_ _)m
575 :
login:Penguin :2010/02/21(日) 20:33:49 ID:y6fTjKHz
自分自身(ファイル)をサーバにuploadするシェルスクリプトって可能ですか? 具体的には、ちょこちょこ定期的にレンタルサーバにuploadしたいファイル群があるのでシェルスクリプトを書きたいのですが、 そのシェルスクリプトファイル自身もuploadしたいのです。
まず、なぜ不可能だと考えたのか、そこから聞こうか。
今実行中のファイルを操作するってのがいけないことなのかなぁと…
自身のunlinkすら可能だというに
アップロードどころか実行中のスクリプトを編集することもできるよー
581 :
login:Penguin :2010/02/26(金) 21:44:10 ID:ZUmR/bTp
以下の結果を出力するスクリプトを,UNIXシェルで書け. (基本仕様) ・コマンドとして実行できる.(UNIXシェルである.) ・主人公、妹1名、両親、自分の友人数名(うち最低1名は女性、半数以上は男性とする)、妹の友人(女性)数名が登場する. ・主人公、妹、自分の友人、妹の友人はいずれも生徒もしくは学生とする. ・両親のうち、父は総合商社勤務のサラリーマン、母は専業主婦とする. ・主人公の言動やイベントの発生にともない、各キャラのパラメータを変化させる. ・病弱な妹を思いやる兄と妹の交流を中心に、他の登場人物との友情や恋愛を描写する. ・エンディングは妹、もしくは妹の友人のいずれかと深い恋愛関係になるか、誰とも親密に慣れないバッドエンディングになるようにする. ・妹と恋愛関係が深まる場合、病弱な妹への思いやりが徐々に、自然に恋愛感情へ変化するように描写する. ・ゲームの操作方法はコマンド選択式またはコマンド入力式とする. ・すべてUNIXシェル内部で処理し,外部コマンドは呼び出さないこと. (ポイント) ☆UNIXシェルにするには,ファイルの最初に #!/bin/bashというおまじないを書く. ☆コマンド選択方式のゲームにする場合、select文を使用できる。 ☆四則演算には $(( )) コマンドが使用できる.(ただし,整数しか扱えない.) 誰かわかるひとお願いします
さようなら
自演ウザス
素直にワラタ
587 :
login:Penguin :2010/02/28(日) 01:11:29 ID:oz3AO1O4
シェルスクリプトとVBA、どちらが簡単ですか?
シェルスクリプト
>>588 シェルスクリプトと比較して、VBAはどこがどんな風に難しいのでしょうか?
用途が全然違う VBA=MS製品の補助、高度なことやろうと思ったらVBの型とか定数とかメソッドとかプログラミング言語として覚えないといけない シェルスクリプト=普段から使っているコマンド郡の応用、データの流れとアルゴリズムさえ判れば外部プログラム呼び出して何でも出来る
>>590 疑問なのは、なぜアプリケーションの補助がそんなに難しいのか、
もっと簡単にできなかったのか、それでは普通の人に使えないのではないか、
という点です。
Linuxで表計算っぽいことができる言語というとawkがありますけど、
あれくらい簡単だったら誰でも使えると思うのですが。
マクロ言語がエンドユーザ言語として使われるためには簡単でなければならないはず。
それなのにシェルスクリプトより難しいというのは、その目的にそぐわないような気がするのですが。
VBAの質問ならよその板でやっとくれ。
>>592 VBAについて知りたいというよりも、
シェルスクリプトとVBAの違いというか、
際立った特徴のようなものがあれば、それを知りたいんです。
>>593 そもそも活用シーンが全然違うのに比較してどうする。根本が間違っている。
比較するならWSHとだろう。
>>594 WSHもWindows PowerShellも
エンドユーザにはあまり受け容れられていないように見受けられます。
Linux/UNIX/MacOSXのエンドユーザでもスクリプトを全く書かない人はいますが、
Windowsよりはそういう人が少ないと思います。
単純にWindowsのほうがヘビーユーザ率が低いというもあるでしょうが、
それだけでなく、Windowsで使われるそれらの言語が
そもそもエンドユーザに適さない欠点を有しているからではないのでしょうか?
とすると、逆にシェルスクリプトはどういう点でそれらより優れているのでしょうか?
>>595 だからさー比較する前提条件が間違っている。
>>596 WSHと比較するようにアドバイスされたので、そうしたのですが。
シェルスクリプトと比較するべきはバッチファイル。 君の質問は「バッチファイルとVBA、どちらが簡単ですか?」という事になるから この板で聞く事じゃない。
>>598 バッチファイルなんて論外でしょう。
あれとシェルスクリプトを一緒にするのはやめましょう。
VBAと一口に言ってもWord、Excel、Access、Outlook…全然違うぞ?
っていうかスレチ。 いちいちageているし、これ以上続けるならレス乞食とみなしてあぼーんする。 くだ質いけ。
くだ質に来られても困るな。 ム板にでも行ってくれ。
WSH(VBScript)で「C:\TechEzo\Round23.txt」内の「ようこそ」を含む行を表示する Set fso = CreateObject("Scripting.FileSystemObject") Set regEx = New RegExp Set tempFile = fso.OpenTextFile("C:\TechEzo\Round23.txt") regEx.Pattern = "ようこそ" Do Until tempFile.AtEndOfStream tempLine = tempFile.ReadLine If regEx.Test(tempLine) Then WScript.Echo tempLine End If Loop これを見て「オブジェクト指向だから素晴らしい」とか 「シェルスクリプトに比べて簡単」とか思う人はいないでしょう。 管理者や一般のエンドユーザなど、ノンプログラマも使う言語を こんなふうに設計したMSは頭が悪いとしか思えないです。
マルチ相手によーやるな
>>603 Window Power Shellもしかり。ちょい使いするには厳格すぎる。
あまりハードルを下げるとMS専門鯖管にスキルが付いてLinuxに行っちゃうからじゃね?
指定したディレクトリ以下を再帰的に検索して 同じディレクトリに大文字小文字違いでファイル名が重複して存在してた場合 例) ABC.txt abc.txt abc.TXT どれか一つ(どれでもいい)を残してあと消去するってのをやりたいけどどうやんの
>>603 見たら、ハードル高くしたらむしろ出来る奴こそLinuxに行ってしまいそうにオモタ
>>606 perl か何かで書いた方が楽じゃないかな。
609 :
login:Penguin :2010/02/28(日) 11:58:42 ID:qTqfFliX
>>606 $ find /tmp/hoge* -type f
/tmp/hoge1/ABC.txt
/tmp/hoge1/abc.TXT
/tmp/hoge1/abc.txt
/tmp/hoge1/a b c.txT
/tmp/hoge1/a b c.txt
/tmp/hoge2/ABC.TXT
/tmp/hoge2/ABC.txt
/tmp/hoge2/DEF.txt
$ find /tmp -type f | uniq -i -d -D --all-repeated=prepend | perl -00 -a -F'\n' -ne '{foreach $i (1..$#F){print "$F[$i]\n";}}'
/tmp/hoge1/abc.TXT
/tmp/hoge1/abc.txt
/tmp/hoge1/a b c.txt
/tmp/hoge2/ABC.txt
ディレクトリの大文字小文字違いは考えてない。
>>609 それって答になってるの?
ただ表示させてるだけじゃん。
表示させるだけならもっと楽な方法あるし。
$ ls -R
.:
ABC.txt Aca.TXT abc.Txt sample.sh test2
./test2:
ABC.txt Aca.TXT abc.Txt test3
./test2/test3:
DDD.TXT aBc.tXt
$ find ./* -type f | grep -i 'abc.txt'
./ABC.txt
./abc.Txt
./test2/abc.Txt
./test2/ABC.txt
./test2/test3/aBc.tXt
$ find ./* -type f | grep -i 'abc.txt' | uniq -i
./ABC.txt
./test2/abc.Txt
./test2/test3/aBc.tXt
611 :
login:Penguin :2010/02/28(日) 14:46:18 ID:qTqfFliX
>>609 では、重複を探して、最初のを除いて、2つめ以降を出力してる。
この出方を
>>606 の評価基準で見てもらい、不満なければ、
あと xargs rm につなぐ程度で済むべ。
>>610 の例だと、それは全部消していいものなの?
612 :
login:Penguin :2010/02/28(日) 14:52:31 ID:qTqfFliX
もちろん
>>609 が最適解だなんて思ってないんだけど、
>>610 のやり方だと、abc.txt って人が与えてるよね。何百個かある時はどうするの?
613 :
login:Penguin :2010/02/28(日) 15:10:05 ID:qTqfFliX
ちょっと修正する。 $ find /tmp -type f | sort -f | uniq -i -d --all-repeated=prepend | perl -00 -a -F'\n' -ne '{shift @F; print join("\0",(@F,""));}' | xargs -0 ls -l 大丈夫そうなら最後の ls -l を rm に変更で。
A="" find . -type f | sort -f \ | while read F; do P=`echo "$F" | tr '[A-Z]' '[a-z]'` Q=`echo "$A" | tr '[A-Z]' '[a-z]'` if [ "$P" == "$Q" ] then echo "${F}を削除" # eval rm "$F" fi A="$F" done
すまん、evalはなくても動く。
617 :
login:Penguin :2010/02/28(日) 16:00:23 ID:diBS8T6m
>>614 いかにもシェルスクリプトらしい解決法だね
perl使うほうがメンドイ
618 :
login:Penguin :2010/02/28(日) 16:32:44 ID:qTqfFliX
感心しました。なるほど、うまいですね。 僭越ながら少し手を入れてみました。(sh 対応、外部コマンド実行回数減らす) #!/bin/sh A="" Q="" find . -type f | sort -f \ | while read F; do P=`echo "$F" | tr '[:upper:]' '[:lower:]'` if [ "$P" = "$Q" ]; then echo "${F}を削除" # rm "$F" fi A="$F" Q="$P" done
勉強になります
別ディレクトリになった時 Q="" しなくていいの?
621 :
login:Penguin :2010/02/28(日) 20:01:15 ID:qTqfFliX
>>620 >>609 で楽するためディレクトリの大文字小文字は考えないことにしたんだけど、
d/abc.txt と D/abc.txt を同一視しちゃってるので、本当ならダメ、なんでしょう。
find . -type d するループを外側につけるか、
ディレクトリ名見る if をつければ直せそう。改修頼みます
>>620
だからそういうのは
>>606 が決めることだって。勉強になります、じゃなかろうに
#!/bin/sh A="." find ./dir -type f | sort -f | \ while read F; do P=`dirname $F`/`basename $F | tr '[A-Z]' '[a-z]'` Q=`dirname $A`/`basename $A | tr '[A-Z]' '[a-z]'` if [ $P = $Q ]; then echo "rm $F" fi A=$F done
書き直したので貼り直しますね。 #!/bin/sh B="!" find . -type f | sort -f | \ while read F; do T="`dirname $F`/`basename $F | tr '[A-Z]' '[a-z]'`" if [ $T = $B ]; then echo "rm $F" fi B=$T done
>>624 スペースを含むディレクトリ作って実行してみ。
Windowsじゃあるまいし。
空白や日本語を許すかで世代間のギャップが存在するなw
用件的にsamba絡みと予想してたけどね。知らんけど
linuxでフォルダ名に空白入れることはないな、色々面倒だし
>>626 シェル変数参照の際、値に含まれるスペースや*などの
パス名展開の文字が解釈されてしまうのを防ぐため、
ダブルクオートで囲むのは常識。
Windowsじゃないとかいう問題ではなく、
シェルスクリプトを書く際の常識。
カラだったときエラーになっちゃうしね
わかった。わかった。次回からそうするよ。
>>610 >ただ表示させてるだけじゃん。
findでヒットした結果には任意のコマンドを適用可能。
馬鹿か?
俺は
>>628 だからそもそもどうでもいいけど、それかなりどーでもいいぞ
>>606 ファイル名を全部小文字に変えて、重複してたら上書きされて結果的に一つ残る。
ってやり方でも出来ると思う。(効率は良くない)
こんなスクリプト書いて /home/hoge/script/RENAME_lower.sh とか名前付けて chmod +x しておく。
#!/bin/bash
START_DIR="`pwd`"
while (test -n "${1}") ; do
if [ -d "${1}" ] ; then
cd "${1}" &&
(
pwd ; ls
for i in *\.[Tt][Xx][Tt] ;
do
if [ -f "${i}" ] ; then
mv "${i}" "`echo ${i} | sed y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/`"
fi
done
)
fi
shift
cd "${START_DIR}"
done
ディレクトリを find とかで検索して RENAME_lower.sh で処理。
$ find . -type d -exec /home/hoge/script/RENAME_lower.sh {} \+
#!/bin/shと#!/bin/bashはどちらがおすすめなの?
#!/bin/bash
#!/bin/bashだろjk
用途次第。以下はsh ・shで書いても機能・速度が許容範囲で簡単に書ける場合 ・shでないといけない場合(busyboxとか)
640 :
login:Penguin :2010/03/05(金) 08:08:46 ID:CTq7Tclv
そいつはこのスレのお約束+α。YOUのオススメを書きなよ
今どきのディストリなら sh -> bash が当たり前だろ
使い捨てなら深く考えずどっちでも OK。 別のマシンでも使うならよく考える。
ださw
>>641 それはUNIX板のシェルスクリプトスレと勘違いして貼られたもん
このスレのテンプレじゃあない
>>5-10 を見ろ
bashの構文を使ってれば#!/bin/bash、使ってなくても#!/bin/bash
おとなもこどもも、おねーさんも#!/bin/bash
BSD系の人たちはどうすれば?
板違いです
$ sudo -i # cd /bin;\rm -f sh;ln -s bash sh
>>651 sudo ln -fs bash /bin/sh
でいいんじゃね。
コピペはできないようにしたかったから二行 ln -f は嫌い rm -f が好き
654 :
login:Penguin :2010/03/06(土) 11:13:20 ID:8ckQdz96
・sh では、while中で代入した変数は、ループから抜けると使えなくなりますか? ・それがPOSIX仕様なら、一時ファイルを作る以外に、よい回避方法はありますか? $ date | while read line; do last="$line"; done; echo "THE LAST: $last" を Debian lenny の dash, bash, ksh で実行した場合、ksh 以外では値が残りません。
POSIX仕様は知らない シェル実装によって違いがあるけどパイプはサブシェルで実行される $ date | (while read line; do last="$line"; done;echo "THE LAST: $last") で回避になるならいいけど $ date | while read line; do last="$line"; done $ echo "THE LAST: $last" ということをしてkshを正解としたいなら一時ファイルくらいしか思いつかない
dateをパイプでwhileに放り投げる目的は何?
ただの例題
このスレで質問してるやつはほとんど約1名でただのキチガイだと思ってる 区別ができれば間違いなく回答しないんだけどねぇ
お前以外は全部俺の自作自演です
質問者以外はどっちでもいいけど
661 :
654 :2010/03/06(土) 22:34:04 ID:8ckQdz96
使っているbashの制約事項はどこに書いてある?
日本語でおk
>>662 /usr/share/doc/bash-doc-*/COMPAT
かな。
俺の認識不足なのかもしれんが dateコマンドを単独で使っても、1行しか出力しなくね? $ date 2010年 3月 7日 日曜日 15:50:25 JST whileにパイプでつなぐ意味がわからん。 もしlsみたく複数行で出力するコマンド実行したならわからなくもないけど、 それなら無理にパイプでwhileにつなぐ必要ないし。 $ ls sample.sh sample2.sh xyz.txt $ for i in `ls`; do X="$i"; done; echo "$i" xyz.txt 別の方法で簡単に解決できることをどうして難しくするのか意味不明。
>>665 おまえは質問者の質問意図がわかってない
>>666 わかるわけない。
whileにパイプでつないでサブシェルになるからどうとか、
そういうので困ったことないから。
668 :
667 :2010/03/07(日) 16:29:06 ID:CtU/xHgd
っていうか、 実用上、それをどうしても使わないと書けないものなんてあるの? 例を示せるなら示してほしいもんだね。
おい、誰かこの馬鹿をつまみだせ
>>669 だから、実用上どういう意味があるのか教えてくれれば
言われなくても出ていくけど。
変数の扱い方が知りたかっただけろ。 例としてとりあえず適当に思いついたdateを使ったんだろう。 ただの一例なんだから実用上は別に意味ない。
672 :
667 :2010/03/07(日) 16:47:13 ID:CtU/xHgd
catコマンドを使ってファイルの中身を出力してパイプでwhileにつないだとか、 そういうのならわかるんだがな。 もっとも、その程度ならパイプ使わないで書けばいいだけだが。 だから、どんなことをキッカケにそんな質問が出てきたのかよくわからん。 まぁ、興味本位で意味のないことする人ってのもいるんだろうけどさ。 ガソリン車に灯油を入れてみるとか、 トラックでレールの上を走ってみるとか。 俺から見ると、そういう変人と同レベルの質問に見えるのさ。
(キリッ
頭の中でdateを適当なものに置き換えればいいだけじゃん。 質問する上での便宜かもしれないってのに いちいち突っ掛かってくるヤツってなんなの?
>>674 dateだからダメとかだけじゃなく、それ以前に変な質問だろ。
>>654 の
>それがPOSIX仕様なら、一時ファイルを作る以外に、よい回避方法はありますか?
に対する答は「パイプを使うな」。
>>661 の
>3以上のfdを使う方向でいこうと思います。
に対しては「他に手段がないならさておいて・・・正気か?」。
だから、お前はそもそもまともなスクリプトも書けないのに、容喙せんでいい。
677 :
login:Penguin :2010/03/07(日) 23:06:32 ID:qcuqADXg
>>676 あれほどアホな質問しない程度には書けるが。
質問者が何をやろうとしてるか知らんが
意地でもパイプでwhileに投げて実現しようとしてんだろ?
まともな神経してたら別の方法でやるのにさ。
っていうか、質問者を擁護してる君も質問者みたいな書き方すんの?
合理性を考えたほうがいいよ。
見ない間に核心つかれてるし ここのキチガイはLIFEも低そうだし なむなむ
mkfifoでnamed pipe作って使う手もあるな。 mkfifo fifo; date > fifo& while read line < fifo ; do last="$line"; done; echo "THE LAST: $last" rm fifo
command 2>file.log で標準エラー出力をファイルに書き出しているのですが、 エラーでない場合も0バイトのfile.logが生成されてしまいます。 エラーでない場合はfile.logは生成しない方法などあるのでしょうか?
>>680 終了ステータスでエラーかどうかわかるじゃん。
↑ ウォーニングは無視ですか?
0バイトなら削除したらええがな
条件後出しか…
条件を甘く見たお前さんが悪い。
居直られちゃったよ。
>>683 削除することにしました。
ファイル作らないで良い方法はないのかなー?
688 :
login:Penguin :2010/03/09(火) 22:45:08 ID:wS8nnpNv
2>file.log でファイルが開かれるのは command が実行される前。 エラーがあったかどうか分かるのは、command の実行が完了した後。 file.log の中身が重要かどうかは、実行終了まで分からないのだから、 普通に考えて、後から削除するのが素直ですよね。 素直じゃない例。長くなっても大丈夫か分かりません。 #!/bin/sh exec 3>&1 cmd='{ ./some.sh 2>&3 1>stdout.log 3>&- ; } 3>&1 | grep -v warning' errout=`eval $cmd` exec 3>&- if [ -n "$errout" ]; then echo "there were one or more error" echo "$errout" >stderr.log fi
久しぶりにマニアックなコード見た。
読み解けん;_;
一回3に2の出力を出して、空ならthere were one or more errorを1に出力、空じゃなければstderr.logに出力
グロブで /etc/pass* のリストを得たいのだが、 list=/etc/pass* だと展開してくれない。 list=$(ls /etc/pass*) ならおkで、改行文字 '\n' 区切りのリストになる。 だが ls のために fork してしまうのが痛い。 どうにかならんのか。 お願いします m(_ _)m
あっさり解決した。 printf "%s\n" /etc/pass* これでいいのか。よくわからんが、printfは組み込みコマンドだったはず。。
昔はechoを使ったもんじゃ
>>695 本当貝?bash?
$ list=/etc/pass*
$ echo "${list[@]}"
/etc/pass*
ダメなんだが。。これをパイプで他のコマンドに渡したいから、ギリギリで展開されても困る。
>>696 echo だと改行文字 '\n' 区切りのリストにならない。
$ list=$(echo /etc/pass*)
$ echo "${list[@]}"
/etc/passwd /etc/passwd-
>>700 だからprintfを使うことにしたよ。
「一行ずつ」読むコマンドにパイプで渡さないといけないから。
後出しで文句言われても……。
>>702 いえ事故解決しました、と言った後であなたが展開できましたとおっしゃったので
私はレスをしただけです。
あ、どうもありがとう(^^)
for i in /etc/pass*; do echo "$i"; done | command...
>>705 すみません、また後出しですが、一応言っておきます。
わざわざ変数 list に格納しているのは、後で自分が参照するからです。
はいはい次どぞー
え、いいんですか?次
ファイルから丸括弧(開く) "(" だけの行を読み込んだ際、 if [ \( "$LINE" = "$CHK1" -o "$LINE" = "$CHK2" \) -a \( "$A" = "$B" -o "$C" = "$D" \) ]; then といったif文でエラーとなってしまいます。 何がまずいのでしょうか?
710 :
login:Penguin :2010/03/20(土) 07:41:24 ID:SCWfCSZ4
>>709 if [ \( "x${LINE}x" = "x{$CHK1}x"
だと通りませんか。
>>710 早速の回答、ありがとうございます。
マシンが平日しか使えないので、火曜日に試してみます。
ところで、$LINE="("の場合だと、
if [ \( "$LINE" = "$CHK1" \) ]; then だとエラーとなりますが、
if [ "$LINE" = "$CHK1" ]; then だとエラーとなりませんでした。
何か書き方が間違えているのでしょうか?
連投すません。 どちらの書き方も、$LINE="(A"とかだとエラーとなりません。 "("の場合のみ、エラーとなります。 なんでだろ?
例外処理ってどうすればいいだろうか。 for x in ... do 処理A && \ 処理B && \ 処理C && \ continue # エラー? 後片付け、そして次のアイテム done サブルーチン化するもの手だけど、それも大袈裟な場合ってどうやるのがスマートだろうか。 すべてを && を繋げる方法しか思いつかない。。
714 :
login:Penguin :2010/03/20(土) 22:33:44 ID:SCWfCSZ4
>>714 ありがとう。便利ですが、/bin/sh(DebianだとDASH)ではうまく動作しませんでした。
BASHなら問題ありません。
handler()
{
echo "Trap ERR!"
exit 1
}
set -e
trap ?handler? ERR
for x in $(seq 1 10)
do
echo $x
[ $x -eq 5 ] && false
done
実行結果:
1
2
3
4
5
Trap ERR!
SIGUSR1 30,10,16 Term ユーザ定義シグナル 1 SIGUSR2 31,12,17 Term ユーザ定義シグナル 2 これを使うのもアリか...
あともう一つ質問! #!/bin/sh echo $@ exit 0 というプログラムがあったとして(test.shとする)、 ./test.sh 'hoge' 'fuga' > fileA ./test.sh > fileB 'hoge' 'fuga' をすると、fileAとfileBの両方とも同じ結果になるんだけど、これはどう違うの?
シェルスクリプトで他のサーバにあるファイルを弄ることは可能ですか? 具体的には、 ローカルPC、サーバA、サーバBという3台のPCがありまして サーバA上の特定のファイルを編集してサーバBにアップロードし、さらにAにある他のファイルをBにアップロードする という処理をローカル上のシェルスクリプトで自動化したいのです。 しかしsshコマンドで他サーバに繋ごうとするとパスワードを聞かれる所で止まってしまいます。
つ公開鍵認証
なるほど…やはりそうなるのですね 公開鍵とやらを勉強することにします mysql -u root -prootみたいに指定できればいいのになぁ
というか、仮にsshで繋げたとしても 実行環境が他サーバに移るわけじゃないし他サーバのファイルをいじるのは無理なのかな? シェルスクリプトはcdコマンドの実行結果すら次の行に持ち込まないですよね 全ての実行行は独立したシェルで実行されるとか何とかで。
こんな感じで編集も転送もできる ssh -i 秘密鍵A ユーザ名A@Aサーバ "任意のコマンド(編集ならsedとかawk)" ssh -i 秘密鍵A ユーザ名A@Aサーバ "任意のコマンド(転送ならscp -i 秘密鍵B 編集したファイル ユーザ名B@Bサーバ:保存場所 )" エラー処理とかちゃんとしたいならAサーバに編集、転送用のスクリプト置いてクライアントからは引数だけ渡せばいいし
>>721 >シェルスクリプトはcdコマンドの実行結果すら次の行に持ち込まないですよね
#!/bin/sh
cd /tmp
./hoge.sh
上記は/tmpに移動して、/tmpにあるhoge.shを実行するけど?
ssh host cd /tmp ssh host ./hoge.sh こんなアホをやっていると予想。 シェルスクリプトを予めscpで送っておくとか、標準入力の内容をスクリプトとして実効できたり出来ないんかね。
726 :
login:Penguin :2010/03/21(日) 17:30:12 ID:cuEg7ODK
echo "( cd /tmp ; ./hoge.sh )" | ssh host でいいですよね。
>>712 -x をつけて実行してみるとなんとなくわかるかも。
文字列の比較のときは710氏の方式で前後に固定文字を入れたほうが誤動作しにくい。
ただタイプミスだと思うけど、中括弧の位置が間違ってて
if [ \( "x${LINE}x" = "x${CHK1}x"
だけどね。
>>727 ありがとう。
固定文字列を入れて比較するのは、いいアイディアですね。
(なんで思いつかなかったんだろう…)
お願いします。 ・forの入れ子構造ってOKなんでしょうか? #!/bin/bash #nekoneko.sh for var in aaa do for fstype in fs do hogehoge=neko done echo $var/$hogehoge done #sh nekoneko.sh aaa/neko 期待結果は得られているのですが、勉強中なのであっているかどうかがわかりません。 ・forでテキストファイルの読み込みってできないのでしょうか? dosのバッチで言うところの for /f %%a in (nekoneko.txt) do 〜のような方法です。 よろしくお願いします。
>・forの入れ子構造ってOKなんでしょうか? OK >・forでテキストファイルの読み込みってできないのでしょうか? DOSのforはしらんが for a in `cat nekoneko.txt` でいいのか?
>>729 インデントしようよ。
全角空白で書くけど、半角空白に変換してくれ。
#!/bin/bash
for var in aaa; do
for fstype in fs; do
hogehoge=neko
done
echo $var/$hogehoge
done
ファイル読んで回すのは while read とか使うんじゃね。
>>731 全角空白のインデントはやめろ!
半角空白のほうがいい
お前の専ブラ変えろ馬鹿
#!/bin/bash for var in aaa; do for fstype in fs; do hogehoge=neko done echo $var/$hogehoge done
恥ずかしいね。
おいおい、pre要素以外では連続する空白文字は一つにまとめられるのだが。 2ちゃんねるのデータ書式はウンコだけど、連続する空白文字をそのまま 表示する仕様なんてないぜ? そういうブラウザを押しつけるのはどうなの、って思うけど。
>>732 うちの環境では半角空白でも見えるけど
相手の環境で見えるとは限らないから。
これはブラウザ依存だと思うね。 空白文字をそのまま扱うものもあれば、HTMLの仕様に準じて無視するものもある。 を使う手もあるのだが、これを同処理するかもブラウザ依存。 まあ2ちゃんねるがクソなんだが。
おまいらスクリプトについても語ってやれよ・・・
>>737 アンタ良い人だね。
でもな、コード貼る事が多いスレを見てるんなら閲覧者のほうでインデントするブラウザにしたほうがお互いに楽だぜ。
貼るほうもコピーする側もそのまま使えるんだから。うっかり全角空白入れたまま使う事もない。
スクリプトスレなら困る事少いかもだが、全角空白の入ったパッチ貼られたりしたら目もあてらんねぇよ?
>>740 だから「変換してくれ」って書いたじゃん。
閲覧者の環境まで責任持てん。
良い人とかってよりも、portability を重視しただけだよ。 書く環境と読む環境が同じとは限らない。 こういう配慮はスクリプト書きもいっしょ。
とりあえず「全角空白を推奨」するのだけは勘弁してくれ。 それが無きゃ俺も黙ってさ。
推奨なんてしてないよ。
>インデントしようよ。 >全角空白で書くけど、半角空白に変換してくれ。 インデントは推奨してるが、改めて見直すと全角空白推奨ではないと言われたら確かにそうだな。 いきなり俺の言い方がきつかったのは謝る。数日前にム板で同じような事があってココでもか!と思ったもんだからついな。 すまんかった >ID:qcQ/2FhI
藻前ら、モティツケ /\⌒ヽペタン / /⌒)ノ ペタン ∧_∧ \ (( ∧_∧ (; ´Д`))' ))(・∀・ ;) / ⌒ノ ( ⌒ヽ⊂⌒ヽ .(O ノ ) ̄ ̄ ̄()__ ) )_)_) (;;;;;;;;;;;;;;;;;;;)(_(
全角文字やTABなどを記号で表示するようにしておけば、 そうそう事故はないのでは?jaspace.elとか便利だよ。
学習用のネタとかならともかくパッチを 2ch に貼んのはやめたほうがいいんじゃね 書き込み確認のとこに 投稿者は権利の何もかもを管理者に無償譲渡することを承諾しますみたいなこと書いてあるぜ
どうしたんだ突然
find -exec command {} + はもっと知れ渡るべき 日経Linux
xargsに慣れちゃって、手が勝手に打っちゃうんだよな
ちゃんと理解しながら読んでいればインデントなんて枝葉末節。 自分のコードならばこだわるかも知れないけどね。
754 :
login:Penguin :2010/03/25(木) 07:38:08 ID:woPIYugI
>>728 UNIX板で知った
ttp://www.opengroup.org/onlinepubs/009695399/utilities/test.html の、APPLICATION USAGE から先が勉強になったです。
-a や -o より && や || でつなぐ方がよいとか。お題の部分についてはこれ。
test "$1" = "bat" -a "$2" = "ball"
syntax errors occur if $1 evaluates to '(' or '!'.
One of the following forms prevents this; the third is preferred:
test "X$1" = "Xbat" -a "X$2" = "Xball"
test "$1" = "bat" && test "$2" = "ball"
test "X$1" = "Xbat" && test "X$2" = "Xball"
>>750 man find
したら、-exec command {} +の下に
-execdir command
とか
-execdir command {} +
とかを見つけた。勉強になった。
こういう事があると電子辞書より紙の辞書の方がいいかもと思う。
>>753 とかほざく輩に限ってテストパターンは無限大な開放系のソースを書いちゃうの。
要はモデル化ができてないと。愚直というか馬鹿正直と言うか。
>>758 より多くの人に読解できることを目的にしていないロジックはオナニーだろう。
つまり日本語はオナニー
セックスよりも気持ちいい
bashなどで標準出力はデフォルトで画面となっていますが、具体的にはどのファイルになりますか? debianですと/dev以下にあるのだと思いますが。
>>762 ls -l /proc/$$/fd/1
フラシュメモリ をマウントするとき # mount /dev/sdb1 /mnt/usb こんな感じでやると思いますが、 もし、フラシュメモリが挿されていて、かつ、マウントされていない場合これを実行し その他の場合、実行しないという、シェルスクリプトを教えてください
>>764 問題点は
・フラッシュメモリがささってないことをどうやって判定するか
・マウントされていないことをどうやって判定するか
でしょ。
それシェルスクリプトの話じゃないよ。
>>765 やはり無理ですか、
・フラッシュメモリがささってないことをどうやって判定するか
・マウントされていないことをどうやって判定するか
ここは、Cか何かで実装し、結果によって、振る舞いを決めるしかなさそうですね
/dev/disk/by-uuid/ 見てそのUSBメモリがささってるか判定して マウントは /proc/mounts とか /etc/mtab 見ればわかる
>>767 できました、ありがとう。
それにしても
>それシェルスクリプトの話じゃないよ。
とは・・・・
え、どこがシェルスクリプト?
シェルの機能に全く関係ない話だから、スレ違いと言われても仕方ない
>>769-770 君たちはきっとUNIX板のシェルスクリプトスレのほうが馴染むよ
向こうに移ったら?
シェルの文法と組み込みコマンド以外は スレ違い。
そこまでは言わないけどさ、
>>764 のスクリプトって
>>765 && mount /dev/sdb1 /mnt/usb
で終わりじゃん。
あとは
>>765 の条件をどう書くかだけ。
そこはシェルスクリプトの話じゃない。
退屈すぎるんだよ ただ手順を羅列していくだけの命題はこのスレではシェルスクリブトではない判定
/path//mydirというディレクトリが確かに存在します。 rm -rf path/mydir とすれば削除できるのに if [-d /path/mydir ]; then rm -rf path/mydir とすると削除できません。 何故でしょうか。
すばやくシェルスクリプトを作る方法を教えてください。
>>775 if [ -d /path/mydir ]; then rm -rf /path/mydir
>>776 俺は指におもりをつけて毎日8時間訓練している。
だいぶ重いスクリプトも楽々書けるようになった。
でもやり過ぎには注意な。
知り合いに、焦点性ジストニアになってシェルスクリプターへの道を絶たれたやつが何人も居る。
揚げ足はいいからさっさと答えろボケ
まず服を(ry
いきなりifとrmまとめずに if [-d /path/mydir ]; then echo hoge がhogeを出力するかどうかぐらい切り分けしようぜ。
最近の初心者は、[ も一つのコマンドであることすら知らんのか?
昔の初心者もそうだよ。
おじいちゃん、乙!
[ ってコマンドだったの? 玄人だけど始めて知ったよ?orz
LPICレベル3coreに受かったばかりの素人だけど []はtestコマンドの略式じゃなかったかな
>>791 構文。
C言語の == は関数ではないし。
昔は、[ は test へのハードリンクと決まってたもんだが、 いま手元のFedora 12を見たらそうじゃなかった。(ファイルサイズも違うし…) やっぱり日々勉強ですな。
>>793 coreutils の lbracket.c 読んでみ。
>>794 読んだ。
面白いけど、Coolとは言えんなぁ…
796 :
login:Penguin :2010/04/10(土) 23:41:09 ID:IGsQWo8s
grepで検索行以外の行を抽出する方法は無いでしょうか?
grep -v '文字列'
798 :
login:Penguin :2010/04/11(日) 00:34:34 ID:3KDsWIIS
初めてシェルスクリプトを加工としていまうs サブルーチンを作る参考にしようと#!/bin/shなファイルを見ているんですが 関数を使ったスクリプトはほとんどありません こういうものでしょうか? 任意の値を返せないのでグローバルな変数を介する必要があると思いますが 保守性が低下しないうまい定義の仕方というのはあるんでしょうか あるいは関数を使わなくてもいいようなシェルスクリプトの特有のコンセプト とか書き方があるんでしょうか 漠然とした質問ですいません
漠然としてるねぇ。 もうちょっとスクリプト書きに慣れてから考えればいいんじゃないかな。
いやそれより、初心者向きの参考書でも買って
一からじっくり勉強した方が良いと思う。
>>799 は、ここで質問して解決するスキルレベルに程遠い。
>関数を使ったスクリプトはほとんどありません >こういうものでしょうか? いえ。 ただ、スクリプトは、 1) 手っ取り早く仕上げる事が多いので十分に最適化されない 2) 最適化されたスクリプトは必ずしも可読性がよくないので敢えて最適化しない といったことはあると思います。
わざわざ外部関数までつくって何でもシェルスクリプトでやるより多言語から単体のシェルスクリプト叩かせたほうが安心できる
>>803 回答ありがとうございます
最適化というのがどういうものか具体的には分かりませんが、例えば関数を組み合わせようと
すると値をやり取りするグローバル変数が必要になるのではと考えました。しかし、必要に
なるごとに関数内で定義、参照するとそういった変数がどこでどう利用されているか確認しなければ
ちょっとした変更も危険になると思います。あるいはメインの手続き側に定義を羅列するとしても
どう利用するのかはコメントでもしないかぎり分からないし、そもそも構造内部を関数へと段階的に
隠蔽する目的を果たせなくなってしまい、やはり可読性保守性は低下します。一方でルールベース
の対策でこういった問題を解決できるようにも感じたので、そういったことについてベーシックな議論を
している人たちがいるのではと思い質問しました。
しかしこのスレッドを読んでいると
>>803 (1)や
>>804 にあるように、そういう道具だと割りきって使う
ものだという風にも思いました。シェルスクリプトの欠点を何千万人もの人があえて見なかったこと
にして使っているとすると、とても面白いことですね。それだけ目的を満足させる道具で、また知っ
て初めて分かる魅力があるということなんでしょうかね
(2)については一枚目から鱗が落ちました。習作のつもりでUTF8のテキストをEUC-JPに変換して
からa2psでポストスクリプトを生成するコードを再発明しているのですが、たしかに関数を使っても
全然読みやすくなっていない! いや、正確には処理の始点と大枠の処理の流れは把握しやすく
なっていますが、コード量は後付けでどんどん増加するし、ちょっとした読みやすさのために定義
したマクロ的関数は、それ単体でみるとなんとも得体の知れないものになっていました。
色々な機能を試したいというのもあるのですが、やはり簡潔で読みやすいコードを書くということを
前提にして、そのうえでシェルスクリプトらしい書き方を身につけるようにします
勢いでいい子ちゃんぶった嘘をつきました・・ たぶん動けば汚くてもいいやの精神でなんだかよく分からないコードを書き続けると思います ゴメンナサイです
/usr/binの中に'['とかゴミがあったので削除したら、起動しなくなったという 笑い話をよく聞いたな。
>>807 ほう、それは初耳だ。
いまどきの sh は [ を内蔵しているので、
外部コマンドの [ を意図して呼ばないかぎり存在しなくても問題ない。
[ が外部コマンドだった昔は、[ は /usr/bin ではなく /bin にあった。
# つーか、/usr/bin/[ なんて今でも linux だけ。
ここはLinux板ですから
「[ を消してうんぬん」は Linux 以前の時代の話だと思う。
プロプラの古いshを使ってないと通じないジョークだな
812 :
799 :2010/04/17(土) 23:26:31 ID:f4tmK5PF
先だっては大変お世話になりました
なんとか動くっぽいもの書けました
根本的に間違ってるところやイディオムに直すべきところなど多々あるんだろうと
思うんですが、身近に聞ける人がいなくて困ってます。ので誰かにレビューして欲しいです
なにとぞ、なにとぞー
http://up.af/015849
813 :
799 :2010/04/17(土) 23:38:16 ID:f4tmK5PF
わざ。わざ
献上品のTシャツおっぱいが404なので眺めるだけな >#!/bin/sh dashで動作確認したのなら素直に#!/bin/dash > file_num=`expr $file_num + 1` exprいらなそう file_num=$((file_num + 1)) > local num=0 > for num in `seq 1 $file_num`; do > source_files_get $num > MESSAGE "converting: $file" > cat "$file" | $NKF -e > "$temp_dir/${file##*/}" > done seqとcatいらなそう local num=1 while [ $num -le $file_num ]; do source_files_get $num MESSAGE "converting: $file" $NKF -e "$file" > "$temp_dir/${file##*/}" num=$((num + 1)) done >local status=1 local使う意味なし&多分bashでコケる
>>815 式展開というものが色々あるんですね
むやみに外部コマンドを呼ばないという発想もなかったです
マニュアルを引いてあれこれ確認したいと思います
レスありがとうございました
>>813 python風のループだな。
LLみたいに関数を使いたければ値をやり取りするフレームワークを書けばよいかも。
commandA > file commandB > file と { commandA; commandB; } > file はどっちの方がいいの? 後者の場合は、シェルによってはサブシェルが起動するって聞いたけど本当貝。
間違えた! 前者は commandA > file commandB >> file
正直、目くそ鼻くそじゃね?
そう? じゃあ気にしないでいいか。
悩んでるうちに書いて実行した方が仕事は早く終わるだろ。
>>824 スクリプトの一文が長すぎる。
パイプラインもメンドイ。
>>818 前者の場合、commandAの出力はどうなるのかな?w
↑ 大丈夫かな、この人・・・
笑っとけ笑っとけ。
恥ずかしいね
>>825 あれで長いって、普段どんなスクリプト書いてんだ?
>>831 いや、引数が100個とかになってきたら。
潰しが利かない。
意味不明
その価値のある文章を頼む。 引数とはどの部分の引数なのか? 潰しが利かないという主張の根拠は?
これ以上この話を続けても有益な情報は得られないと思う。
>>818 commandA > file
commandB >> file
と
{ commandA; commandB; } > file
コマンドが100個になったのでwhileで省力化したい。
上の方
rm -f file 2>/dev/null
while read cmd;do
$cmd >> file
done < cmds.txt
下の方
xargsを使えば出来そうだけど{}が内部コマンドなのが気になる。
1行のコマンドラインの文字数制限があるシェルもある。
ので、汎用性が無い。
制御構造の使えないシェルスクリプトなんて、バッチファイルの如く、無価値である。
>>837 よくわかんねえけど
そのcmd.txtって、事実上シェルスクリプトだよな
単に
sh cmd.txt >file
でいいんじゃねえの
wwww
for((i=0; i<6; i++)){ array=("${array[@]}" "i") } echo "${array[@]}" これを実行すると下記のように出力されます。 0 1 2 3 4 5 カンマ区切りで下記のように出力する方法ありますか? 0, 1, 2, 3, 4, 5
>>842 最後の出力を実現するのなら seq -s ', ' 0 5 で済むけど、
配列の各要素を任意の区切文字で繋げて出力する方法を知りたいということかな
zsh/ksh なら echo ${(j:, :)array} でできるけど、bash でどうなのかは知らない
>>843 説明不足で申し訳ないです。
配列の各要素をカンマ区切りで出力する方法です。
・訂正します
array=(1 2 a b 3 c )
echo "${array[@]}"
これを実行すると下記のように出力されます。
1 2 a b 3 c
カンマ区切りで下記のように出力する方法ありますか?
1, 2, a, b, 3, c
echo ${(j:, :)array} は使えませんでした。
>>844 IFS="," ; echo "${array[*]}"
echo "${array[@]}" | sed 's/ /, /g'
847 :
844 :2010/04/28(水) 11:26:50 ID:+626EOW1
bashを使っています。 echo hoge > /dev/tcp/192.168.0.10/5000 を実行したのですが、接続されません。 /dev/tcp/192.168.0.10/5000: No such file or directory になってしまいます。なぜでしょうか。 192.168.0.10:5000にはサーバプログラムが存在してて telnet等で接続可能な状態です。
> echo hoge > /dev/tcp/192.168.0.10/5000 そもそも,何がしたいの?
あ,何がしたいのか分かった.でも解決策は分からなかった. すみません,無視して下さい.
すみません自己解決しました。
シェルスクリプト内でexpectを呼んで、リモートホストにログインし コマンドを実行して実行結果を呼び出したシェルの環境変数に入れる事は出来ますか? #!/bin/sh PROMPT="\"\\\\$ $\"" expect -c " spawn ssh リモートホスト expect -re $PROMPT send \"hostname\r\" expect -re \"hostname\\r\\n\" expect -re \"(\\[a-zA-Z\\.\\]+)\\r\\n\" set TEST \$expect_out(1,string) expect -re $PROMPT send \"exit\r\" expect eof " echo "result=$TEST" ←カラになってしまう
子プロセスの環境変数は親プロセスには渡らないだろ。子プロセスがechoしてそれを親で受け取るとか。
854 :
login:Penguin :2010/05/24(月) 23:51:39 ID:Am1WdIur
おもしろいね。 ここw
855 :
login:Penguin :2010/05/25(火) 11:30:05 ID:rQ8o0yBp
画像で貼ることに意味あんのか
date -d '10 days ago' のdateをシステム時刻ではなく、'20050101'を基準にしたい場合はどうすればよいですか?
date -d '20050101 10 days ago'
860 :
login:Penguin :2010/06/02(水) 14:19:20 ID:PFRBtasL
#$ -S /bin/bashの-Sって何? ぐぐれないよお
>>860 man bashすると
-S file
True if file exists and is a socket.
-S Display readline key sequences bound to macros and the strings they output.
-S suffix
suffix is appended to each possible completion after all other options have been applied.
って書いてあるけど?
bashでプロセス監視系のシェル作ってるんですが任意のプロセスのプロセスIDからプロセス名を取得するには ps pidの後でawkとかperl使うしか無いですかね? 綺麗にコマンド1つで片付けられないかと調べてみてるのですがなかなか…
>>862 cat /proc/(pid)/になんかあるんじゃね?
864 :
login:Penguin :2010/06/03(木) 08:42:13 ID:q5DckAvu
SHELLって任意の場所からファイルを 一行づつ読み込んだり出来る? こんな風に while ファイルA ファイルBの末端まで do ファイルAからXに一行読み込み ファイルBからYに一行読み込み if $Xと$Yを比較 then 処理 fi done
865 :
862 :2010/06/03(木) 09:05:02 ID:oG88VoRM
>>863 手当たり次第に見てみましたが、status配下から抜き出すにしても結局awk操作になりそうです
見落としてるだけで上手く拾える物があるんでしょうか?
read a </proc/$pid/cmdline echo $a
867 :
login:Penguin :2010/06/03(木) 10:09:27 ID:8XZFMkrD
>>862 ps --no-headers -o command 25123
とか?
868 :
login:Penguin :2010/06/03(木) 10:13:10 ID:8XZFMkrD
>>864 そういうのは perl か何かでやった方が楽そう。
870 :
login:Penguin :2010/06/03(木) 10:18:28 ID:8XZFMkrD
871 :
869 :2010/06/03(木) 10:21:03 ID:7YfCa7sT
872 :
862 :2010/06/03(木) 11:01:39 ID:oG88VoRM
皆さん色々とアドバイスありがとうございます。 最終
873 :
862 :2010/06/03(木) 11:09:24 ID:oG88VoRM
皆さん色々とアドバイスありがとうございます。 最終的にファイル名に落とす(これは先に言うべきでしたね)事等考慮し、 /proc/pid/statusのName行をawk、あるいはps -e | grep "^pid" | awk '{print $4}' あたりでの抽出を考えてみようと思います
874 :
login:Penguin :2010/06/03(木) 11:13:00 ID:8XZFMkrD
>>873 > ps -e | grep "^pid" | awk '{print $4}'
これだと PID が 234 のをひっかけようとして 2345 も出力したりするよ。
>>867 の1コマンドで済ますのはダメなん?
>>874 >>867 のコマンドだと対象のプロセスがシェルスクリプトの場合に/bin/bash shellname.sh
といった形式で取得となってしまうので…この後ファイル名に落とすのにちょっと扱いづらいかと
思いまして。
/やらを_に置換してもぱっと見どうかな、と。
psでの取得に関するご指摘はまったくもってその通りですね
ひとまず/proc配下のファイルからの取得を軸に考えてみます。
876 :
login:Penguin :2010/06/03(木) 11:24:17 ID:8XZFMkrD
>>875 なら command じゃなく comm で。
>>876 出来ました∩(・ω・)∩バンジャーイ
ありがとうございました
スクリプト以前にコマンドの使い方についてもっと勉強しないとですね…
ps で表示されるコマンド名を自分で書き換えちゃうようなものも存在するので注意。 sendmail とか。 ってゆーか、 >bashでプロセス監視系のシェル作ってるんですが任意のプロセスのプロセスIDからプロセス名を取得するには この発想がすでに間違ってる気がしなくもない。 pidからプロセス名を調べるのがなんで監視になるんだ? ふつーにSNMPとか使ったら?
>>878 監視という言葉に脊髄反射してませんか。
教科書に載ってるのだけが監視じゃないぞと。
>>875 じゃあこれでいいんでね?
basename $(ps --no-headers -o command 30242 )
>>879 cmdlineにはargv[]の内容が\0で区切られて入ってる。
catだとその全部が見えてしまって、argv[0]\0argv[1]\0...という値になってしまう。
readだと\0が終端に見えるのでargv[0]だけを取得できる。
配列の中に特定の要素があるかどうか調べるにはどうやるのが一番スマート でしょうか? 例えば VAR=(a b c) の時に $VAR に b が入ってれば真、なければ偽とする、みたいなのです。 すなおにgrep?
一番スマートなやり方は知らないな
>>884 とりあえず、お前が考えたスマートじゃないやり方を見せてくれよ
>>884 for i in ${VAR[@]}; do 判定; done
>>885 二番くらいでもいいです。
>>886 あの後も引き続き調べまして、いまんとこ以下のようにしています。
VAR=(abb bbb cbb)
case ${VAR[@]} in *bbb*) 真の時の処理 ;; esac
VAR=(abb bbb cbb) test ${VAR[@]/!(bbb)} echo $?
890 :
login:Penguin :2010/06/14(月) 20:31:06 ID:ieeFt0nm
メールの本文を自動処理するようなシェルスクリプトを書きたいのですが、 テキストをcatしてsed通してgrepしてcutしたのを一行ずつreadして… とかパイプでつないでやってると冗長になるし途中でチェックもしにくいです。 あるコマンドの出力を一時的に書き出すにはファイルにリダイレクトするとかしかないでしょうか? 出来るだけ一時ファイルは作りたくないのですが…
>>890 perl か何かで書いた方がいいんじゃね。
俺ならPerlかPHP使う
893 :
login:Penguin :2010/06/14(月) 20:55:45 ID:ieeFt0nm
早速レスありがとうございます。 perlですか。むむ。 なんか管理の都合とかで自動しょりはシェルスクリプトでやれとかいわれんですよね…わけわからんけど… 泣きそうですがなんとかやってみます
>>893 シェルだとやりにくいこともいろいろあるからね。
perl じゃなくてもいいけど、
何かもう一つ LL 使えるよう社内で交渉してみなよ。
>>890 > テキストをcatしてsed通してgrepしてcutしたのを一行ずつreadして…
それ、needless catじゃね?
sedしてgrepってのも、sedだけで済みそうだけど…
cutしたのをreadって、全体では何をするスクリプトなのでしょうか?
上手くすれば、パイプを大幅に減らせるかもしれませんよ。
> とかパイプでつないでやってると冗長になるし途中でチェックもしにくいです。
腐った環境だと、パイプがつまることもありまっせw
#!/bin/sh perl /hogehoge.pl っていうシェルスクリプト書いておけば無問題。 という冗談はともかく、メールの処理となると結構複雑なことを考えないといかんだろうから、 それなりな言語を使ったほうが実現しやすいと思う。 複雑怪奇なシェルスクリプトなんて管理が大変だよ。
898 :
890 :2010/06/17(木) 22:43:10 ID:4hwJRH3Z
>>896 ,897
アドバイスありがとうございます。
catは確かにいらないかもしれません。
やろうとしてるのは、サーバからの週次報告のメール処理です。
メールの情報を元に、沢山あるNFSをいくつかマウントして、中のファイルを操作します。
メールの内容には、/var/log/messages見たいなログが含まれるので、
処理対象の行を抽出して、
そこから処理対象のNFSや処理対象ファイル名のリストを作成して、
リストを元に、NFSをマウントして中のファイルを消したり書いたり読んだり。
というような具合です。
メールの本文の処理を考えてたらやたらコマンドを繋いでしまいましたが、
sedやawkを使えば事足りるような気がしないでもありません。
ファイルサイズが0BYTEを検出するにはどうしたらよいでしょうか?
if test ! -s filename then else fi でよろしいでしょうか?
>>900 レスありがとうございます
調べてみます
>>898 目的の処理を行うシェルスクリプトを生成するような、入力ファイルを解析するだけの
シェルスクリプトを組むという手もあります。解析と実行を分離できるので、見通しも
良くなるし、デバッグも比較的楽になります。
この生成したスクリプトをファイルに書き出しておけば、後々問題が起きたときの
切り分けに役立つと思いますが、どうしても一時ファイルを作りたくないなら、
$ sh parse.sh target-file | sh
のように、解析結果をシェルにパイプでつなげるということで。
906 :
905 :2010/06/19(土) 17:58:05 ID:LxGHTRzC
自レスへの補足。
>>905 の生成というのは、標準出力に出力するという意味です。
907 :
login:Penguin :2010/06/20(日) 16:05:06 ID:M2Bl5krX
whileにパイプで入力すると変数のスコープが変なのなんで。
ggrks
bash の話? 何を言いたいのかさぱーり分からんけど、あえてエスパー気分で答えてみると、 パイプライン内のコマンドはサブシェル内で実行されるから、while ループ外から変数は見えない。 ってことかな?
>>907 C言語でもforで指定してる変数を参照するのはお行儀の悪いことにされてるだろ。
>>907 どうしても while read をカレントシェル内でしたいなら、以下のようにする。
#! /bin/sh
head=
tail=
while read line
do
echo "${line}"
test -n "${head}" || head="${line}"
test -n "${line}" && tail="${line}"
done <<EOF
$(ls)
EOF
echo -----
echo head: "${head}"
echo tail: "${tail}"
echo line: "${line}"
まあ、最後に改行が入ってしまったりと、色々癖があるけど。
ls | { while read line; do echo "${line}" test -n "${head}" || head="${line}" test -n "${line}" && tail="${line}" done echo ----- echo head: "${head}" echo tail: "${tail}" echo line: "${line}" }
913 :
login:Penguin :2010/06/23(水) 23:25:40 ID:GJl6eUSR
コマンド1の標準出力の行数をカウントして、 0じゃなければコマンド1の標準出力をコマンド2の標準入力で処理したいです。 出力行数はwcコマンドでわかりますが、 出力をコマンド2に渡す前に行数をチェックする書き方がわかりません。 コマンド1を2回実行すれば出来るのですが他にうまい書き方あるでしょうか。 sub1(){ cat hoge.txt } sub2(){ ......... } CNT=`sub1 | wc -l` if[ $CNT != 0 ]; then sub1 | sub2 fi
if [ -n "`sub1`" ]; then sub2 fi
あー、ごめん。よく読んでなかった。 s="`sub1`" if [ -n "$s" ]; then echo "$s" | sub2 fi
916 :
login:Penguin :2010/06/24(木) 00:35:03 ID:3fD01YtH
>>915 ありがとうございます。
これって例えば出力が数万行とかでも大丈夫でしょうか。
test
シェルスクリプトの代わりにpythonだけじゃ困ることってありますか。 沢山覚えるの無理なので、、、 どちらもよくわかっていないので何かアドバイスちょーだい。
>>918 python が入ってない環境で困る。
ということは趣味で自分のマシンいじる分には 一切の問題がないということでいいの。
趣味なら困ってから考えてもいいんじゃない。
あー、他人が書いたものを読むときに困る。 起動スクリプトとか。
>>918 日常的に使うUNIXコマンドの処理手順をスクリプト化したものが
シェルスクリプトと考えれば、新しく覚えることはほとんどないのでは。
どっちも必要だけど大した苦労もない。 そんなところですね。 ちなみに皆さんの使用比率はどんな感じでしょうか? bush:python(スクリプト言語)
>>ID:HX9t/VP5 「何をしたいのか」を一切言わずに言語や環境だけ語られても、 単なる釣り、もしくはPython知識の自慢にしか見えないが…
やりたいことは、Linuxを道具として使いたい。 使っている道具をきちんとメンテして把握したい。 そんな所です。 Pythonの知識はまったくですが 他の興味が出てきたときに使いまわしが効くんじゃないかなぁ って思えるから。 どちらか一つでいいならPython一本でいきたいと思う次第です。
そうですか 好きにしてください
>>913 >>916 コマンド1の出力を一旦ファイルに書き出すのが確実かと。
どうしても一時ファイルを作りたくないとか、シェルスクリプトじゃなきゃやだというなら、
builtin の read の癖を容認できれば、以下のように出来なくもないですけど。
command-1 |
(
if IFS= read -r line;
then
( echo "${line}" && exec cat ) | command-2;
fi;
)
>>927 その発想、話にならんね。
ソフトウェアツールというものが、全く分かってない。
まずは、初心者向けの書籍を数冊読んでからだな。
931 :
login:Penguin :2010/06/27(日) 12:04:55 ID:6P+QcdNk
シェルスクリプト関数の中で、perlの-eにヒアドキュメントでperlスクリプトを 渡して、そのスクリプトに引数を渡したいのですが失敗しています say-hello-world-with-perl () { echo -n Hello perl -E <<END say ARGV[0] END World! } まずENDの右に空白があるのでシェルに「parse error near `\n'」と言われsay ARGV[0]をsay "World!"にしたのですが こんどはヒアドキュメントのスクリプトが認識されていないらしく「No code specified for -E.」と言われてしまいました
932 :
login:Penguin :2010/06/27(日) 12:45:45 ID:Hm9ANnqg
#!/bin/sh PATH=/bin:/usr/bin sayhello() { echo -n Hello perl -- - World <<'END' print "$ARGV[0]\n"; END } sayhello
933 :
931 :2010/06/27(日) 13:09:23 ID:6P+QcdNk
できました。 ありがとうございます。
>>918 シェルスクリプト:目の前の問題を解決するのに手軽に使える。
軽量言語:シェルスクリプトだと面倒なちょっとした機能を実現するときに楽。
C言語:バイナリの加工とか速度にシビアな処理を行うときに使う。
コマンド化しておけばシェルスクリプトで使える。
>>930 重要なのはツールボックスアプローチではなくて、問題を実時間で如何に解決するかだ。
>>934 そうなんですよね。
>>930
今日暇だったので県図書行ってきたんだよ
そしたらオライリーのbash詳説本があったので軽く目をとうしたんだ
そしたら前書きに著者が「20年位シェルスクリプトは書いてないけど
昔に比べてずいぶんよくなったよねー」ってオイ!
でもパイプつなげて正規表現使って、はい出来上がりみたいな感じが
魅力的に見えたので、やっぱpythonだけってより両方必要だって思いました。
>>935 何か辛いことでもあったのかい。話聞くぞ
>>937 たった一日でずいぶん上目線になったな、おい。
>>936 みたいな基本的なことがやっと分かっただけでw
>>938 一日で…というか、ID:+b2tR0Mj=ID:HX9t/VP5
最初からだよ。権威主義だし。
自分の意見に賛同を求めてるだけで、他人のアドバイスは全然聴いちゃいない。
それでいて、
>>917 のような初心者丸出しの一面もある。
大体どんな奴か、年代・経歴までほぼ想像できてしまうw
>>939 今度は権威者からプロファイラーですか。
Pythonが出来るなら、シェルスクリプト書くのに困ることはないと思うが。
shスクリプトやMS-DOSのBATファイルは、pythonやperl、visual basic等のわりとモダンな言語と違うので、使えない人は意外と沢山いるよ。
shスクリプトで面倒なことするくらいなら Pythonで書いた方が楽ってことだろ
久々にバッチファイル書いたら、さっぱり分からなくて3時間かかった。 データの場所移動して、ショートカット作って、いらんプロセス止めて、後掃除lするだけなのに・・・
「サーバ管理も結構やってきたしシェルスクリプトくらい勉強しなきゃなぁ」 →誰でも読めるスクリプトを書くが一定以上の要求には答えられない 「コーディングしたいのに鯖管やらされるなんて…。こんなん自動化出来るだろ。シェルスクリプト?なんだよこの実装使いにくい。」 →要求は満たすが本人以外メンテできないスクリプト 「UNIX?わかりますよ。仕事でLinuxバリバリ使ってますから。shなんてコマンドありましたっけ?」 →単なるコマンドの羅列ができあがる
>>946 どんな要求であっても、俺の場合は常に二つ目が出来上がってしまう。
そもそもシェルスクリプトって、そんな意気込んで学習するものか? man sh とか見ながらワンライナーで使ってれば、普通に書けるようになるんじゃ… ログインシェルが /usr/bin/python でもあるまいに。
仕事でバリバリ使ってる→誰かが開発した業務アプリをただ使ってるだけ
>>951 >シェルスクリプトって結局の所、コマンドの羅列に毛の生えたようなものだと思うのだが。
それは大きな誤解。DOSのBATファイルならそう言ってもいいかもしれないが。
>>951 /: : : : : __: :/: : ::/: : ://: : :/l::|: : :i: :l: : :ヽ: : :丶: : 丶ヾ ___
/;,, : : : //::/: : 7l,;:≠-::/: : / .l::|: : :l: :|;,,;!: : :!l: : :i: : : :|: : ::、 / ヽ
/ヽヽ: ://: :!:,X~::|: /;,,;,/: :/ リ!: ::/ノ l`ヽl !: : |: : : :l: :l: リ / そ そ お \
/: : ヽヾ/: : l/::l |/|||llllヾ,、 / |: :/ , -==、 l\:::|: : : :|i: | / う う 前 |
. /: : : //ヾ ; :|!: イ、||ll|||||::|| ノノ イ|||||||ヾ、 |: ::|!: : イ: ::|/ な 思 が
/: : ://: : :ヽソ::ヽl |{ i||ll"ン ´ i| l|||l"l `|: /|: : /'!/l ん う
∠: : : ~: : : : : : : :丶ゝ-―- , ー=z_ソ |/ ハメ;, :: ::|. だ ん
i|::ハ: : : : : : : : : : : 、ヘヘヘヘ 、 ヘヘヘヘヘ /: : : : : \,|. ろ な
|!l |: : : : : : : : :、: ::\ 、-―-, / : : :丶;,,;,:ミヽ う ら
丶: :ハ、lヽ: :ヽ: : ::\__ `~ " /: : ト; lヽ) ゝ
レ `| `、l`、>=ニ´ , _´ : :} ` /
,,、r"^~´"''''"t-`r、 _ -、 ´ヽノ \ノ / お ・
,;'~ _r-- 、__ ~f、_>'、_ | で 前 ・
f~ ,;" ~"t___ ミ、 ^'t | は ん ・
," ,~ ヾ~'-、__ ミ_ξ丶 | な 中 ・
;' ,イ .. ヽ_ ヾ、0ヽ丶 l /
( ;":: |: :: .. .`, ヾ 丶 ! \____/
;;;; :: 入:: :: :: l`ー-、 )l ヾ 丶
"~、ソ:: :い:: : \_ ノ , ヾ 丶
>>951 単なるコマンドの羅列ならシェルをインタプリタとして実行だけできるようになってればいい。
本来純粋なシェルに求められる機能以上のものが備わってるんだから、
そういう使い方が求められて作られてるんじゃないの。
コマンドの羅列以外のことをするのなら 他の言語使う方がいい気がするけど・・・
>>951 と同意見だけど、大きな誤解なのか。。
shファイルの平均行数は10行程度なんだからコマンドの羅列なんだよって言おうと思って計算したら、
110行もあったorz
$ echo $(sed '/^#/d' $(locate -r "\.sh$") | wc -l)/$(locate -r "\.sh$" | wc -l) | bc
110
>>957 あぁ、コマンドの羅列だけではなくて、環境変数の設定ね。
まぁそれもあるだろうけど。
ダメだこりゃ
960 :
login:Penguin :2010/07/03(土) 17:42:04 ID:d1BG5aq/
質問があります。 1.クライエントからubuntuにログインして tcpdumpを実行。ダンプはubuntuのローカルファイルへ 2.クライエントでとあるプログラムを実行 3.クライエントのプログラム終了 4.ubuntuのtcpdumpを終了 5.tcpdumpの結果をscpなどで取得 という流れのスクリプトを書きたいです。 ssh server tcpdump...& とやっても、sshからもどってこれずに、クライエントでプログラム実行の段階へ移行できません。 また、ssh server "tcpdump.. &" とやると、もどってこれるのですが、tcpdumpが中断されてしまっているようです。 どのように書けばいいですか? アドバイスいただけると助かります よろしくお願いします。
961 :
login:Penguin :2010/07/03(土) 18:26:29 ID:d1BG5aq/
Rubyを使って自己解決しました。ご迷惑おかけしました。
マルチは死ね
963 :
955 :2010/07/03(土) 18:47:59 ID:sj4QRtxF
>>957 「言語として使うなら」ってつもりだったけど、
>>955 をどうみてもそういう解釈にならんですまんかった。
>>957 環境に依存するが、/etc 以下の多くはシェルスクリプト以外のものだと思うが…
コマンド以外にゃ、条件判定とループが少し、ブロック化のための単純な関数だけじゃないか。
配列変数やforeachでないforは所詮拡張機能だし、関数内局所変数のlocalですら、複雑になる
からってPOSIXからは除外とか。まあ、シグナルtrapぐらいはできるけど。
. で読み込んでるとは言え、コメント含めて数百行なんぞ、コマンドの羅列と変わらんだろ。
>>959 C言語って結局の所、"hello world!"に毛の生えたようなものだと思うのだが。
などと自己観念を主張している人に、観念外の事を説明しても徒労だよ。
スレ伸びてると思って来たら何この流れ。
おまいら
>>946 に釣られすぎだろw
シェルスクリプトなんぞに期待しすぎwww
所詮はめんどくさがり屋の一括処理ツール
コンピータとはそういうもんです。
お知恵を拝借 mpgの一括処理をしたいのですが 以下の構文の場合、 半角スペースがあるファイル名の場合には、$mpgのなかに 半角スペースまでのファイル名しか取得できません。 #!/bin/sh for mpg in `ls *.mpg` "aaaa bbbb.mpg"の時は $mpg=aaaa となります。 すべてのファイル名を取得するには どうすれば良いでしょうか?
`ls` ってなんでそんなの必要なのさ。 for mpg in *.mpg; do echo "$mpg" done
>>971 >>972 ありがとうございました。
lsで出力するとファイル名がソートされるので見やすいと考えて使いました。
ls なしでもソートされるわけだが。
>>974 ls --sort=time とかってやりたいんじゃない?
>>970 ということで、耳タコなこの台詞。
変数に空白を含む可能性を考慮して、クォートしましょう。
>>975 ls 使いつつクォートしろ、ってこと?
あぁ、 for mpg in "`ls --sort=time *.mpg`" とかできるのか。
>>972 誰も国籍の話なんかしてねえよ
形容詞的に朝鮮人って言ってんだ
972は誤爆だろ
違った、誤爆は978だ、スマソ