1 名前:シェルスクリプトライター mailto:sage [2011/12/10(土) 20:06:40.38 ] シェルスクリプトの総合スレです。 スクリプトのお勉強・自慢・腕試しなどにどうぞ。 □お約束 ・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。 Linuxユーザは/bin/shの正体がbashなので特に注意。 FreeBSDユーザは/bin/shの正体がashなので注意。 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。 src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/ heirloom.sourceforge.net/sh.html ・csh/tcshのシェルスクリプトは推奨されません。 (理由は「csh-whynot」でググれ) ・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。 manや参考リンクを見ましょう。 aproposないしはman -kでそれらしい単語による簡単な検索もできます。 ・シェルスクリプトのことをシェルってゆーな ・シェルで使えるワイルドカード等は正規表現ではありません。 正規表現の話題はスレ違い(正規表現スレへ) □初心者へのアドバイス: ・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも RubyやPerlの方が適した仕事には素直にそちらを使いましょう。 ・知らないコマンドが出てきたらmanを引きましょう。 ・思い通りに動かないときは、まずは sh -x でトレースしましょう。 前スレ シェルスクリプト総合 その18 hibari.2ch.net/test/read.cgi/unix/1308195527/ 次スレは >>970 で。
370 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/24(金) 23:41:20.22 ] 大量のメールアドレスの一部分をマスクしたい。例えば foo.bar@example.com → foo****@example.com ドメイン部分はそのままで、先頭3文字程度残して、残りの部分はメールアドレスの文字数が変わらないように 任意の文字で埋めたい。今は下のように変数にメールアドレスを入れて処理しているけど、ちょっと不恰好 MADR=foo.bar@example.com MASK='*' RC=3 DOM="${MADR##*@}" let MC="${#MADR}"-"$RC"-"${#DOM}"-1 echo "$MADR" echo "${MADR:0:$RC}`yes "$MASK" |tr -d '\n' |head -c"$MC"`@$DOM" もう少し楽に処理できないでしょうか?
371 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 03:53:15.28 ] 素直にrubyで echo foo.bar@example.com | ruby -pe '$_.sub!(/(?<=[^@]{3})[^@]*(?=@\w+)/){|s|"*"*s.size}' perlならもっと短くできるんじゃないかなぁ。
372 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 04:08:45.24 ] >>370 sedを使うのはいかが? echo "user@example.com" | sed -e 's/\(...\).*@\(.*\)/\1...@\2/g' ユーザ名が必ず3文字以上ならこれで良いはず。 ユーザ名が2文字以下だとそのまま出力される。 (元のスクリプトでも2文字以下ならそのままっぽいが。)
373 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 05:22:15.23 ] 長さ保存してないじゃんそれ
374 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 06:52:42.61 ] >>373 あ、長さが変わらないように、か。 「長さが分からないように」と読み違えてた。すまん。
375 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 08:28:46.14 ] >>370 をもとに、おもにyes|trの部分を改良してみた。 不要なクォートや不要な変数も削除した。 ↓ MADR=foo.bar@example.com MASK=* RC=3 DOM=${MADR##*@} echo "$MADR" echo "${MADR:0:$RC}"`echo "${MADR:$RC:${#MADR}-RC-${#DOM}-1}" | sed "s/./$MASK/g"`@"$DOM"
376 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 09:18:35.26 ] つーか、見るからに遅そう。 > 大量のメールアドレスの一部分をマスクしたい。例えば 千通突っ込む気にならない。
377 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 09:27:28.61 ] awkでやってみたよ。 RC=3 MASK='*' echo "$MADR" | awk -F@ -vn="$RC" -vm="$MASK" '{t=substr($1,n+1,length($1));gsub(".",m,t);print(substr($1,1,n) t "@" $2);}'
378 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 09:37:42.09 ] 速度優先ならC言語一択だろ。 標準入力から1行ずつ複数のメールアドレスを読む仕様。 gets()使うなとか、エラーチェックなしとかの突っ込みはなしな #include <stdio.h> #define RC 3 #define MASK '*' int main() { int i; char buf[1024]; while (gets(buf) != NULL) { for (i = RC; buf[i] != '@'; i++) { buf[i] = MASK; } puts(buf); } return 0; }
379 名前:名無しさん@お腹いっぱい。 [2012/02/25(土) 11:10:48.60 ] シェルスクリプトスレでなんという暴論
380 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:17:36.53 ] 速度がそんなに重要じゃないからここで聞いてんのにな。
381 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:19:51.26 ] >>380 >>370 >大量のメールアドレスの一部分をマスクしたい。 速度が重要という質問ですが・・
382 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:20:58.69 ] だが正論。これをシェルスクリプトでというのはコスト高くないかな
383 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:21:00.66 ] 「大量」としか言ってないじゃん。 量は多いけど時間は多少かかってもかまわないんでしょ。
384 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:22:45.37 ] たとえば退社前に処理を開始して 次の日の出社までに終わってればいい、なんてケースだと 7時間が4時間に短縮されてもあんまり意味ない。
385 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:52:15.99 ] 皆さん、レスありがとう御座います 初めは>>372 のように考え、どうしても長さが保存できないので何かやり方は無いかと質問しました >>371 ,377 もっとさくっと書けるコマンドがあるかなと思っていたけど、やはりスクリプト言語使うしかないですか それにしてもrubyは短く書けるんですね。今のシステムには入れていませんが勉強になります >>375 なるほど。任意の長さの文字列を作るのにsedで置換を使う方法は思いつかなかった それを元にすると最終的にこんな感じでしょうか? MADR=foo.bar@example.com MASK=* RC=3 DOM=${MADR##*@} MINV=${MADR:$RC:${#MADR}-RC-${#DOM}-1} echo "$MADR" echo "${MADR:0:$RC}${MINV//?/*}@$DOM" これなら、外部のプログラムを呼び出さないのでそこそこ速そう ただ、bashで動くことは確認したけど、汎用性を考えるとawkを使う>>377 ? 速度についてですが、何度も変換するものではないし、 寝ている間に終わればいいなと思っていたのでシェルスクリプトで十分でした
386 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/25(土) 11:54:23.14 ] 訂正:echo "${MADR:0:$RC}${MINV//?/*}@$DOM" → echo "${MADR:0:$RC}${MINV//?/$MASK}@$DOM"
387 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 01:55:24.94 ] Å ヽ('A`)ノ、スーパーちんぽマン参上!! / ( ) \ んヘヽヽ〜'
388 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 10:43:00.23 ] # Set shell to ignore SIGINT (signal 2), but not children; shell catches # SIGQUIT (signal 3) and returns to single user after fsck. trap : 2 trap : 3 # shouldn't be needed という一文が有るのですが、 SIGINITとSIGQUITを無視(ignore)するならば trap ' ' 2 trap ' ' 3 と言う書き方になるような気がするんですが、 :はどういう意味が有るのでしょうか?
389 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 10:55:51.64 ] >>388 trap '' 2 は、 親(シェル自身)も子プロセス(外部コマンド)もSIGINTを無視する。 trap : 2 は、 親(シェル自身)はSIGINTを無視するが、子プロセス(外部コマンド)はデフォルト動作に戻 る。 あと、' ' じゃなくて '' (空文字列)な。
390 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 11:23:35.81 ] 半二重なら trap : 2、全二重なら trap : 2と trap : 3が要るんじゃねーのー
391 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/26(日) 22:34:59.64 ] >>389 >>390 :ってヌルコマンドって奴ですか? そうすると、 親(シェル自身)はSIGINTを無視するが、子プロセス(外部コマンド)はデフォルト動作に戻る という解釈どうして出てくるかさっぱりなので、教えてください お願いします
392 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 01:17:55.06 ] trapがそういう仕様だから。man読め。
393 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 07:26:12.43 ] シェルのマニュアルのtrap項目だと、指定コマンドが空文字列だと そのシグナルを無視し、子プロセスも無視するとは書かれているけど、 これだけだとわかりにくいかも。 trapで何らかのコマンドを指定すると、それはシグナルハンドラが設定されるので、 シグナルの一般仕様により、シグナルハンドラが設定されている場合の子プロセスでは シグナル設定はデフォルトに戻る。 よって、ダミーのシグナルハンドラを設定するために、: コマンドを指定している。
394 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 13:56:39.45 ] awkで複数のファイルに対して一括処理するときに変数xを初期化したいのですがうまくいきません。 何が間違っているのでしょうか? BEGIN{x = 0} printf("%d\n",x++) END{x=0 }
395 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 14:04:05.23 ] awkがそういう仕様だから。man読め。
396 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 14:11:30.36 ] >>394 BEGIN{}等は使わない ↓ #!/bin/awk -f FNR==1{x=0} {printf("%d?n",x++)}
397 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 15:17:34.24 ] >>391 ":"がnull commandなのは先頭語に出てきた場合だけ。 trapが第一引数の":"をどう解釈しようと自由。 ただnull commandからの類推で「無視するが〜」としただけ。
398 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 15:22:42.53 ] >>397 ちがうよ。 trapは、第1引数を改めてコマンドとして解釈する(2回解釈する)ので、 結局 : は先頭に出てきたのと同じで、null command として解釈される。 (eval : の場合と似てる) trapが:を特別に解釈しているわけではない。 たとえば、trap true 2 って書いても trap : 2 と同じ。
399 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 15:54:02.25 ] むしろ特別に扱っているのは""の方。 これでSIG_IGNにすることになってる。
400 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:12:06.60 ] awkのフィールド分割的なことやるのに while read hoge hage ; do : done <file とかよくやるけど、1行の文字列を分割しようとして echo "hoge hage" | read hoge hage ってやってみても、$hoge にも $hage にも何も入らない なんで?
401 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:28:41.94 ] そういう仕様じゃないから
402 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:29:53.91 ] kshだとできるよ。
403 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:31:57.84 ] echo "hoge hage" | { read hoge hage echo hoge=$hoge hage=$hage }
404 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/27(月) 23:36:20.13 ] >>403 おおー入った! \(@o@)/ どういう仕様になってるんだろう サブシェル的な問題?
405 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 08:06:57.00 ] >>404 その通りだが、そうならないシェルもある。自分なら read hoge hage <<<"hoge hage" って書く
406 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 10:45:26.99 ] ヒアストリングってbash/zsh以外でも使えんの?
407 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 11:12:25.51 ] 古典ヒアストリングならな。
408 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 18:54:44.50 ] ソラリスのkshは冷やすとリング使えないのに、 リナックスのkshは冷やすとリング使える不思議
409 名前:400 mailto:sage [2012/02/28(火) 22:39:16.48 ] ヒアストリングってスレの初めの方で出てたやつですか オイラの読んだ入門書には載ってなかったんだよなぁ と思いながら試してみたら Syntax error: redirection unexpected sh -> dash なうちのDebianじゃダメみたい (・ω・` ) ステキな機能だけに残念 やっぱこういう場合はset使うべきなんですかね…
410 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/28(火) 22:52:20.02 ] >>403 じゃまずいの? 一行で書きたいならセミコロン echo hoge hage | { read hoge hage; echo hoge=$hoge hage=$hage; }
411 名前:名無しさん@お腹いっぱい。 [2012/02/29(水) 02:06:19.12 ] getoptsにて「-yx」のように複数文字のオプションを判定することは可能なのでしょうか? xxx.sh -a test -yx #!/bin/ksh while getopts a:yx opt do case ${opt} in a) YY=${OPTARG} echo "オプション[-a]の引数は${YY}だよ。" ;; yx) echo "オプション[-yx]があるよ。" ;; esac done
412 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 08:15:39.53 ] >>411 getoptsでは、-yx は -y -x と指定したのと同じに解釈されるから無理。
413 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 10:48:10.11 ] 代わりに --xy を使うとよろし。
414 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 10:50:38.33 ] >>413 すみませんが詳しい方のみ回答をお願いします
415 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 10:54:40.48 ] ああ --yx か。とにかく>>412 のいう通りってこった。
416 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 11:34:25.80 ] getopts y: として $OPTARG が x かどうか判定すればいいんじゃね? -y x も受けつけちゃうけど。
417 名前:名無しさん@お腹いっぱい。 [2012/02/29(水) 14:08:24.59 ] どうもこんにちは〜 list=`cat ./file | grep aaa` って感じでlistにaaaを持つ行を全部放り込んでるのですが、 これらを別々の1行ずつに分割して なおかつlistを配列にして格納する事はできますか。 具体的には、fileの中にはaaaの文字列を持つ行が5つあるのですが それをlist[0]〜list[4]に格納したいのです。 よろしくご指導お願いしますm(_ _)m
418 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 14:10:31.36 ] なんで cat 通すんだろ。 grep aaa file でよくね?
419 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/02/29(水) 15:35:13.71 ] >>417 IFSに改行コードのみを代入した状態で、list配列に一括代入する文法を使う。 #!/bin/bash IFS=' ' list=(`grep aaa file`)
420 名前:名無しさん@お腹いっぱい。 [2012/02/29(水) 16:42:01.73 ] >>419 ありがとうございます! できました!
421 名前:400 mailto:sage [2012/02/29(水) 23:33:48.87 ] ロングオプションは getopt でいけるけど何か問題もあったんだっけ >>410 パイプ通すとブレースもサブシェルで動作してるのか 外からは参照できないみたいなんですよね いやもちろん最初の例もサブシェル作ってるんですが (;´Д`) 処理の内容にもよるけど、やっぱりグローバルで使いたいってなると 関数に括り出してバッククォートで呼んだりして結局同じようなことなのかなぁと そんな感じの意味です でも勉強になりましたみなさんありがとう
422 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/01(木) 06:47:03.28 ] >>421 getopt(外部コマンド)はスペース入りファイル名などの引数を正常に扱えない などの仕様バグの固まり。getoptsを使うべし。
423 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 08:04:37.31 ] とあるソースから #define HOGE MAGE HOGE の定義値を抽出したい。 grep HOGE header.h |grep define |awk print $NF みたいな書き方(うろ覚え)すると キャリッジリターンも拾うわ、 タブ(スペース)数でフィールド変わるわなんですが うまい方法ないですか?
424 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 08:12:54.29 ] >>423 $ cat header.h #define HOGE MAGE $ (cat header.h; echo HOGE) | gcc -E -P - MAGE
425 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 08:25:52.14 ] プリプロセッサに置き換えられるからプリプロセッサに置き換えさせるとかワロタw
426 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 09:38:08.86 ] でもうまい方法でしょ?
427 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 10:17:08.26 ] #ifとか考え出したらそれ一択。
428 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 12:00:16.07 ] 複数行に渡るマクロもあるしな。 けどお題はもっと単純な話なんじゃないのかな。 マクロの展開を止めたいなら、 (#define MAGE 〜があってもMAGEを出力したい場合) awkスクリプトになってしまったが、こんな感じ。 awk '$0 ~ /^#define[ ]+HOGE/ { $1=""; $2=""; print $0 }' []の中はスペースとタブ
429 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 22:50:17.04 ] 質問です。 あるディレクトリにある全部のファイルに対して コンパイルをかけるスクリプトをつくりたいです。 TESTLISTには ソース名 コンパイラオプション が書いてあります(hoge.c 5みたいに) --------------------------------------------- #!/bin/sh # プログラム、コンパイルオプション一覧リストを指定 LIST=/home/shell/TESTLIST # コンパイラのパスを設定 CCOM=/home/shell/cc.sh # コンパイルをかける while read ARG1 ARG2 do ${CCOM} ${ARG1} ${ARG2} done < ${LIST} -------------------------------------------- のような簡単な奴で良いんですが、
430 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 22:51:02.05 ] 続き cc.shの中に、 -------------------------------------------- if [ ${RETCD} -ne 0 ] then echo "コンパイルログを表示しますか?" RCV="" while [ `echo "${RCV}" | sed -ne '/^[ ]*[yYNn][ ]*$/p' | wc -l` -eq 0 ] do read RCV done if [ `echo "${RCV}" | sed -ne '/^[ ]*[yY][ ]*$/p' | wc -l` -ne 0 ] then more ${コンパイルログ} fi fi ------------------------------------------- のように書いてあり、コンパイルに失敗した場合、 「コンパイルログを表示しますか?」が端末に表示されたままで、「N」や「Y」を 入力しても反応がなく、Ctr-Cで実行を打ち切っている状態です。
431 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/05(月) 22:52:03.41 ] 続き コンパイルに失敗した場合、Ctr-Cを入力すると 次のファイルにコンパイルをかけるようにしたいのですが、 -------------------------------------------- #!/bin/sh # プログラム、コンパイルオプション一覧リストを指定 LIST=/home/shell/TESTLIST # コンパイラのパスを設定 CCOM=/home/shell/cc.sh # Ctr-Cを無視するように設定(サブシェルには有効) trap : 2 # コンパイルをかける while read ARG1 ARG2 do #サブシェル化 (${CCOM} ${ARG1} ${ARG2}) done < ${LIST} --------------------------------------------- でオッケーでしょうか? ちなみにMakeは使用不可です。また、cc.shはいじれません。
432 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 11:06:00.37 ] >ちなみにMakeは使用不可です。また、cc.shはいじれません。 この状況を何とかした方が建設的かと。
433 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 19:10:20.96 ] >>431 > でオッケーでしょうか? つまり俺たちにデバッグしろと言っているのか?
434 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 19:12:06.02 ] はい
435 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 19:19:26.97 ] はいじゃないだろうが!
436 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 19:21:31.59 ] はいじゃないが
437 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 20:23:39.44 ] はいはい。
438 名前:名無しさん@お腹いっぱい。 [2012/03/06(火) 21:07:07.27 ] >>429 コンパイルに失敗した場合、「N」や「Y」を入力しても反応がない原因を 教えてやる。 >>429 の while do .. done ループで、done < ${LIST} となってるので、 標準入力が ${LIST} にリダイレクトされたままになってて、 その状態で cc.sh が起動されてる。 cc.shの中でキーボードを読んでるつもりが、${LIST}を読んでしまうので、 「N」や「Y」を入力しても反応しない。 解決方法は、>>429 で、 ---------------------------- exec 3< ${LIST} while read ARG1 ARG2 do ${CCOM} ${ARG1} ${ARG2} done 0<&3 ---------------------------- とすること。標準入力をキーボードにしたまま、readには記述子3を読ませる。
439 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 21:12:06.05 ] >>438 おいおい、そのリダイレクト方法だと結局同じ理由で駄目だよ。 標準入力を退避しておいて復帰する。 exec 3<&0 while read ARG1 ARG2 do ${CCOM} ${ARG1} ${ARG2} 0<&3 done < ${LIST}
440 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 21:17:04.64 ] >>439 の方法でもいいが、 >>438 が言いたかったのは ↓じゃないかな exec 3< ${LIST} while read ARG1 ARG2 0<&3 do ${CCOM} ${ARG1} ${ARG2} done
441 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/06(火) 22:15:57.04 ] >431 > でオッケーでしょうか? オッケーだと言う人がいたらしいよ。 ただし私は、貴方の環境と責任を共有していないので、自己責任でやって下さいね。
442 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:36:49.85 ] テキストから読み込んだ文字列内の「\\」をそのまま変数に入れたり表示させたりする方法を 探しています。OSはCentOS6、シェルはbashです 以下のような問題に対処したいのですが、何か手段はありますでしょうか? 以下のsampletext.txt(「\\」や「\」を含む)を、readecho.shのようにreadで読み、 echoで出力すると、「\」がエスケープか何かされているようで、表示されません bashやechoのmanにある-Eオプションを明示的に付与してみても変化が無いようです awkprint.shのようにawkで行うと期待した結果が出るのですが、他の処理の関係上、 できればawkは使わずに、シェルスクリプトで実現させる方法を知りたく思ってます テキストを事前に「\\」から「\\\\」としておく等の対処はせずに済ませたいです $ cat sampletext.txt \\winsv\a\b\c \\sambasv\d\e\f $ cat readecho.sh #! /bin/sh while read STRING do echo -E "${STRING}" done < sampletext.txt $ ./readecho.sh \winsvabc \sambasvdef ←「\\」が「\」になり、「\」が消えている。NG $ cat awkprint.sh #! /bin/sh cat sampletext.txt | awk '{print $0}' $ ./awkprint.sh \\winsv\a\b\c \\sambasv\d\e\f ←上記のような問題はない。OK
443 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:42:21.68 ] >>442 read -r
444 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:42:48.66 ] つread -r
445 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:45:02.83 ] 普通はread -rだけどbashは知らん。
446 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:48:20.73 ] >>443-445 情報ありがとうございました うまくいきました bashでもreadは「Backslash does not act as an escape character.」だそうです なるほどreadで対処するのか... $ cat readecho.sh #! /bin/sh while read -r STRING do echo -E ${STRING} done < sampletext.txt $ ./readecho.sh \\winsv\a\b\c \\sambasv\d\e\f
447 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/07(水) 00:55:51.24 ] >>446 > bashでもread -rは「Backslash does not act as an escape character.」だそうです と書きたかったのか?
448 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 22:27:14.08 ] AとBの処理があって、 Aを開始、 Bを開始 Bの中でAの処理中を待つことできますか? 意味わかりませんかね・・・ mkdirとかロック待ちみたいなやつです。
449 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 22:43:33.00 ] ロック待ちがわかるんなら、そのまんま A で mkdir lock して B で [ -d lock ] かければ? while 文で無限ループ作って、sleep でも挟めば十分「処理待ち」になると思うけど。
450 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 22:44:29.80 ] >>448 FreeBSDなら lockf(1)、Linuxならflock(1)を使ってなんとかしろ。
451 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 23:06:08.54 ] >>449-450 ありがとうございます。 がんばってみます。
452 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/09(金) 23:18:55.14 ] >>450 なんで似てるようで違う名前なの?
453 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/10(土) 00:14:30.88 ] カレーライスとライスカレーみたいなモン
454 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/10(土) 09:50:04.49 ] うまいなあ。それイタダキマス。
455 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 03:13:24.48 ] a=0 for FILE in `find / \( -iname "zoo*.png" -o -iname "land*.png" -o -iname "zoo*.txt -o -iname "land*.txt" \)`; do rm -vf $FILE echo $a done 初心者です、スクリプト書いてみたんですが、この$aで表示される数がおかしくてこまってます。 なぜかrmコマンドでは1つも削除されておらずメッセージも表示されていないのに4と表示されるのです。 やりたい事としてはこうです↓ 「zoo*.png、land*.png、zoo*.txt、land*.txtというファイル名のファイルを全て削除し、その数をカウントする」 何がおかしいのでしょうか?
456 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 04:32:12.07 ] >>455 4が表示されるのはオカルト。君もうすぐ死ぬんじゃない? ファイルを削除して数をカウントしたいだけなら find ほにゃらら -print0 | xargs -0 rm -v | wc -l でよい。変数もforも必要ない。 4が出るのは君がオリジナルのスクリプトをここにコピペするときに何か端折ったせいだろう。
457 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 04:53:51.30 ] >>456 ごめんなさい、a=$(($a + 1))が抜けてました... にしてもこんなにコンパクトになるもんなんですね ありがとうございました
458 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:05:01.28 ] xargsは原始人の道具。 find ほにゃらら -exec rm -v {} + | wc -l で良い。
459 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:11:05.46 ] -deleteが使えるfindもある find ほにゃらら -delete -print | wc -l
460 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:14:18.54 ] >>458 -exec の方が古い感覚だけどどうなんだろ?
461 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:17:25.43 ] >>460 -exec ';' なら古い感覚 -exec + は新しい感覚
462 名前:460 mailto:sage [2012/03/11(日) 08:29:08.31 ] >>460 + はいま使っているマシンの中では使えない物がほとんどかも。 -exec は元々 Unix に魅せられたポイントなので、1989 年には使ってた。 xargs はネットで教えてもらって 1995 年頃から使い始めた。 けど確か元からあったかも。
463 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:32:05.19 ] >>462 -exec + はSolarisでさえ使えるのに、どんな古いOS使ってるんだよ?
464 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 08:54:41.56 ] POSIXにも入っていてSVR4由来(当然Solarisにもある)でHP-UXにもあるのに、 使えないのを探す方が難しいよね。 原始人と言われたからってムキになってウソを教えるのは良くないな。 www.pasc.org/interps/unofficial/db/p1003.2/pasc-1003.2-210.html | One of these extensions, which I believe is supported at least on all | systems derived from SVR4 and on HP-UX (although in some cases it is an | undocumented feature), is a variant of the "find -exec" primary where | "find" does argument aggregation internally: | | find . -type f -exec some_command {} +
465 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 09:52:56.43 ] ちょっと前までテンプレにfindの項があったと思うが、今は無くなってるな。 確かテンプレではfind -print0 | xargs -0推奨で、スレ内議論では-exec +を使えと主張する人がいた。
466 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 10:09:06.10 ] テンプレにあったのはfind -print | xargs という回答には必ず言いがかりが付け られていたから。質問者のためではなく回答者のためのテンプレ。 -exec {} + 構文が紹介されてからはxargsを使う意味がなくなったのか削除された。 それでもしばらくは-exec {} + を知らない原始人がいたけど、そのたびに原始人と 呼ばれて、絶滅していった。テンプレから削除されたのはこの時点(絶滅後)かも。 -exec {} + ですべてが置き換え可能とは言わないが、find+xargsが必要になること は極めてまれ。
467 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 10:32:32.19 ] うーむ、結局その2つ違いって何ですか? あと、パイプで繋がってしまっているrmを画面にも出力する方法ってないんでしょうか?
468 名前:460 mailto:sage [2012/03/11(日) 10:44:50.32 ] 俺が xargs 教えてもらった頃は -exec は fork するから良くないと言われてた。 + は SVR4 に入っているのなら俺のもだいたい動くね。 でも俺まだ Tower の SVR2 や SVR3 とも格闘してるから。 ファイル名の長さが 14 文字までのやつ。
469 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 10:44:55.57 ] >>467 2つの違い -print0や xargs -0は使えないOSがある。 >パイプで繋がってしまっているrmを画面にも tee
470 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 10:55:09.82 ] >>467 1 find -exec \; 構文ではファイル一つ毎に別プロセスが起動されるので効率が悪い。 2 そこでまとめて処理できるようxargsが作られた。初出はPWBだからかなり古い find -print | xargs 3 ファイル名に改行入れられるとヤバいので-print0, -0が設けられた find -print0 |xargs -0 4 そんな面倒な事しなくて済むように-exec {} + 構文が作られた -exec \; 構文と違い、別プロセスは(MAX_ARGSを考慮して)まとめて実行される。 > あと、パイプで繋がってしまっているrmを画面にも出力する方法ってないんでしょうか? find ほにゃらら -delete -print |tee /dev/tty| wc -l find ほにゃらら -exec rm -v {} + |tee /dev/tty| wc -l
471 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 10:56:05.20 ] > -print0や xargs -0は使えないOSがある。 例えば? どっちも相当昔からある気がするけど
472 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 10:58:21.95 ] >>471 ちょっとは自分で調べろよ。Solarisで-print0等が使えないのは常識。
473 名前:460 mailto:sage [2012/03/11(日) 11:04:39.92 ] >>470 + 便利そうだな。
474 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 11:06:35.90 ] -0はFreeBSD 2.1.5-RELEASEにはない。FreeBSD 2.1.6.1-RELEASEにはある。 相当昔といえば言えなくはないが。 www.freebsd.org/cgi/man.cgi?query=xargs&apropos=0&sektion=0&manpath=FreeBSD+2.1.5-RELEASE&arch=default&format=html www.freebsd.org/cgi/man.cgi?query=xargs&apropos=0&sektion=0&manpath=FreeBSD+2.1.6.1-RELEASE&arch=default&format=html
475 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 11:22:05.20 ] 結局、自分が使ってるOSで使える方法を使えって結論になってるよね毎回
476 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 11:29:54.60 ] 答える側は質問者の環境を想像すべきだな。 SVR[23]のような骨董環境前提の回答なんか意味ない。
477 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 11:38:38.97 ] それなら結局xargsでも-exec +でもどっちでも良いんじゃない?十分に新しいLinux/*BSD環境前提なら。 自分はタイプ数の多いxargsは使わないけどね。 無用な-exec \;と-0無しのxargsさえ避ければ良い。 そもそも今回は-deleteが使えるならxargsも-exec +も要らないし。
478 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 11:42:53.84 ] >>477 だから、使える方法を使えばいいってことでしょ? 結論見えてないの?
479 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 11:51:09.25 ] >>469 >>470 できました!!ありがとうございましたm(_ _)m
480 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 15:05:46.64 ] >>470 > 3 ファイル名に改行入れられるとヤバいので-print0, -0が設けられた 改行というか、広い意味での空白($IFS)だな。
481 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 15:27:32.53 ] xargsは、$IFSの改行/スペース/TABだけじゃなく、 シングルクォート/ダブルクォートも解釈しちゃうという問題がある。 it_don't_mean_a_thing.mp3 とかのファイル名もそのまま通らない
482 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 20:30:34.37 ] こういうイヤーンなファイル名があるときって、makeが通らなくなって難儀する。 コロン(:)が含まれてるファイル名なんか最悪。。 FILES = $(wildcard *.mp3) $ make hoge Makefile:〓: *** multiple target patterns. Stop.
483 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 22:43:26.33 ] なんかもう素人の集団みたいになってるな 基本的な歴史としては>>470 の通りなんだが 現代においてはfindで引っかるファイル数が数十万〜数百万ということも珍しくなくなった そしてそのような場合{} +では処理できない、というか渡された先が悲鳴を上げる だから 5. としてxargsを-n付きで使うようになったわけ >>481 みたいな問題にもちゃんと解法はある、つーかググレカス ゆえに{} +はファイルを渡す先が確実に処理できると確信できる場合だけ使うべきで 癖をつけるなら-print0 | xargs -0の流れが正しい 何か問題が起きてもxrgsにオプション足すだけで解決する つーか、初期の頃はちゃんとそう説明する奴が居たはずだけどな…
484 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 23:15:55.26 ] >>483 > 現代においてはfindで引っかるファイル数が数十万〜数百万ということも珍しくなくなった > そしてそのような場合{} +では処理できない、というか渡された先が悲鳴を上げる <limit.h>に従った正しいプログラムなら何の問題もないです。 > だから 5. としてxargsを-n付きで使うようになったわけ これはあほなプログラム向けです。
485 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 23:18:50.93 ] 不特定個数の引数をとれるという仕様にもかかわらず悲鳴あげるのはバグ。 引数の個数に制限がある場合にはxargs -nも有効だが、そんなヘナチョコ コマンド出会ったことない、具体的には何?
486 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 23:24:03.91 ] >>483 その根拠は何? pubs.opengroup.org/onlinepubs/009604599/utilities/find.html > The size of any set of two or more pathnames shall be limited > such that execution of the utility does not cause the system's {ARG_MAX} > limit to be exceeded. >>484 あほなプログラムの実例 savannah.gnu.org/bugs/?func=detailitem&item_id=16738
487 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/11(日) 23:37:58.77 ] というわけで2006年以前のfindutilsを使う可能性がある人は、 バグがあるので -exec {} + はやめたほうがいいということになるのかな
488 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 07:42:10.36 ] >>483 は渡された先が悲鳴あげるといっているので、それは違う。 もっとも、>>483 がその区別をつけられないだけかも知れないが。
489 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 17:53:31.98 ] 結局>>483 はボケ老人のタワゴトって結論でいいですか? ・悲鳴あげるヘナチョココマンドの存在は不明 ・>>481 のようなケースも-print0, -0で対処できるている。
490 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 18:00:08.91 ] >>489 >>481 はそういうことを言ってるんじゃない。 >>480 が $IFSだけが問題と言っているのでは誤解を生じるので、 それだけじゃなくクォートも、と言う話。
491 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 18:05:46.84 ] >>490 ボケ老人のタワゴトとは>>483 の↓この発言。>>481 の指摘は正しい。 > >>481 みたいな問題にもちゃんと解法はある、つーかググレカス
492 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 18:22:03.41 ] まあxargs対策でエスケープすればいいんだから、findの出力をfilterするなり解法はあるわな。 > 何か問題が起きてもxrgsにオプション足すだけで解決する こっちのほうが問題では。
493 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 18:28:41.55 ] GNU findutilsは、デリミタを指定すると(-d, -0)、quoteは無視するようになっている。 他のfindは使ってないので知らないが。
494 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 18:29:11.30 ] print0でNUL文字を区切りにしたんだから、ファイルシステムに 許されているいかなる文字もこれで対応でしょ。 > 何か問題が起きてもxrgsにオプション足すだけで解決する その問題とは? >>483 のボケた脳内にある悲鳴あげるコマンド しかないのですよ。
495 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 19:10:17.94 ] 今までなかったからこれからもないと信じるのはどうなのと思わなくもない
496 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 19:15:52.59 ] >>483 の脳内には現実に存在するみたいですよ。
497 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 22:17:38.36 ] お前らって、本当、どうしようもないバカだよな ちったぁ議論らしいことをしたいなら、前提について定義しろよ お前ら何のOSの事を想定してんだ?Solarisか?AIXか?386BSDか?バージョンは?え? 使ってるコマンドはどこの物だ?OSについてきたコマンドか?GNUのやつか?バージョンは?え? そこが全然明確じゃないから、いっつもいっつもループしてんのか前に進んでんだか 前にも進んでないんだか分からねえグダグダ展開になってんじゃねえか お前らの脳内それぞれで、前提狂った状態で、全然違うOSの事で話をしてたって、 意味も価値も実りある結論も、何もありゃしねえんだよ お前らって、本当、どうしようもないバカだよな
498 名前: 忍法帖【Lv=2,xxxP】 mailto:sage [2012/03/12(月) 22:21:20.93 ] 結局どっちがいいの? find . -print0 | xargs -0 -I{} mv -vb {} ../tmp とかした時って同名なのにバックアップ取られないファイルがあったんだけど、-exec +ならちゃんとバックアップされる?
499 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 22:24:10.73 ] >>497 バカからも得られるものはあるものさ バカってのはこういう事を考えてるんだ、こんな風に誤解してるんだ、その程度しか知らないんだ、 じゃあ分かってない人はその辺が分かっていないのかもしれないから、ちょっと注意しよう そんな目線での考察や気づきは、やっぱりバカからしか得られないものなのさ
500 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 22:33:58.20 ] 分かりやすい自演
501 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 22:37:33.62 ] >>498 find、xargs、mvの仕様、及びファイル名の状態(空白含んでるとか、日本語ファイル名だとか)次第 どんな名前のファイルがこようがこれなら何でもOKという万能包丁は、ぶっちゃけ無い FAQにも割とマジで"Use Samba and explorer.exe"ともある
502 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 23:04:49.76 ] バックグラウンドで何かを起動すると、 ジョブ番号とPIDが表示されるじゃないですか。 あれって表示させなくする方法ってあるんでしょうか? 時間のかかる処理をバックグラウンドで走らせて その間に別の処理をやって、waitで同期する、 みたいなことをやるスクリプトで、邪魔なんですよね。
503 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 23:08:46.69 ] >>498 両方使えば?っていう初心者の意見です
504 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 23:19:19.45 ] >>502 スクリプト実行しているシェルは何?
505 名前:名無しさん@お腹いっぱい。 [2012/03/12(月) 23:21:09.67 ] bourne shだったりcshだったり。 Solarisです。
506 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 23:30:30.20 ] csh使うのやめろ shは出ない
507 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 23:46:04.45 ] >>497 >>1
508 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/12(月) 23:46:40.54 ] >>498 やってみればわかるよ
509 名前:265 mailto:sage [2012/03/13(火) 00:27:03.89 ] >>508 find . -exec cp -vb ../tmp + find: -exec: no terminating ";" or "+" だって・・・
510 名前:265 mailto:sage [2012/03/13(火) 00:27:31.16 ] まちがえた find . -exec cp -vb {} ../tmp +
511 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 04:25:42.37 ] 結局、print0 とかが必要になるのは Windows でファイルを処理しきれなかった時ばかりなので Unix 上のコマンドじゃなく Windows ネイティブな UNIX-Like tools が 完璧なファイル名対応出来ればいいんだけどな。 Unix 上ではそんなファイル作らない。
512 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 10:06:48.40 ] みんなそんなに移植性必要なの?
513 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 10:12:13.36 ] > 結局、print0 とかが必要になるのは > Windows でファイルを処理しきれなかった時ばかりなので 違うよ。root権限で動作するスクリプトが毒食わせられないための用心。
514 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 10:38:44.75 ] >>512 移植性が必要ならシェルスクリプトなんて使わないよ
515 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 12:31:59.14 ] ワンライナー手打ちするだけならそれこそどうでもいいし それ以上気を遣いたいんなら、単にLL使えばよくね Perlなら昔から標準でfind2perlとかついてくるし
516 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 23:03:21.13 ] シェルスクリプトを作る際の考え方はある程度使いまわせるが、移植性は低いわな実際 まぁ考え方っつっても、それは別にシェルスクリプトでしか習得できない考え方ではないけれど
517 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 23:19:15.02 ] autotoolsの中の人に聞かせてあげたい
518 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 23:27:28.51 ] 移植性のために数多くの制約に縛られるなんてのは、 シェルスクリプト的に本末転倒なことなのさ
519 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 23:30:41.17 ] いや、移植性を突き詰めていくとシェルスクリプトで全部やるという結論に至る。
520 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/13(火) 23:50:33.10 ] 幸か不幸か自分のやりたい作業はシェルスクリプトで済んでしまう。perlもpythonもいらない。 だから(個人的には)シェルスクリプト GREAT! だね。
521 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/14(水) 03:14:56.05 ] 質問です。 cp a.txt b.txt というシェルスクリプトが書かれた『hoge.sh』をダブルクリックで実行した場合、 普通はなんの反応もなく、コピーが実行されます。 これを、実行されたコマンドを端末に表示させることはできるでしょうか? はじめから端末内で bash hoge.sh とすればいいのですが、深い階層にあって面倒なので…。 それに、この場合も何のコマンドが実行されたのかが分かりません。
522 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/14(水) 06:51:12.07 ] >>521 hoge.shに以下のように書いておく。 xterm -e sh -xc 'cp a.txt b.txt; set +x; echo -n Hit any KEY:; read key'
523 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/14(水) 12:25:04.10 ] >>522 ありがとうございました m(_ _)m
524 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/14(水) 23:14:00.92 ] tarって入力されたデータをそのままの順でアーカイブするけど -Tで渡すファイル名をソートする意味ってあるかな?
525 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/15(木) 18:42:17.16 ] tarはアーカイブの先頭からファイルを展開していく 遅いテープに書き込むときに、早めに参照したいファイルをアーカイブの先頭付近に書いておくと 早めに展開される そんな特性があるので、その特性を活かすためにアーカイブするファイルの順序を指定することは、 意味がある わざわざソートして渡してるなら、その特性を理解してないだろうから、意味ないだろう
526 名前:名無しさん@お腹いっぱい。 [2012/03/15(木) 21:04:05.76 ] どなたか↓わかる方、今週末中にお願いします。 ──────────────────────────────────── 不定個数の整数の引数を与えて実行すると,それらの整数のGCMとLCMを計算して 表示するようなシェルスクリプトを作成せよ.使用シェルは/bin/shとする. 【実行例】 $ ./kadai15.sh 12 20 24 GCM = 4 LCM = 120 ────────────────────────────────────
527 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/15(木) 21:51:58.41 ] GCMとLCMがわからん
528 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/15(木) 22:02:52.24 ] lcmは最小公倍数だね。 gcmは最大公倍数? w
529 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/15(木) 22:13:31.83 ] Greatest Common Measure Least Common Multiple >>528 はアホ
530 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/15(木) 22:20:19.95 ] 最大公倍数 最小公約数
531 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 00:21:54.70 ] 本当にどうでもいいことだが、gcm ってメジャーなんでしょうか? 普通の数学では gcd が圧倒的で、gcm は数学教育の教科書でしか 見たことがない。
532 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 00:26:08.56 ] 数学板で聞いたら。
533 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 00:49:16.79 ] en.wikipedia.org/wiki/Greatest_common_divisor ejje.weblio.jp/content/%E6%9C%80%E5%A4%A7%E5%85%AC%E7%B4%84%E6%95%B0
534 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 01:11:00.95 ] SEだが>>526 がわからんくて死にたい。 整数と小数の判定ってシェルでどうやんの?
535 名前:531 mailto:sage [2012/03/16(金) 01:13:58.15 ] メジャーなんですねgcmだけに、と無理矢理言っておきます
536 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 05:58:58.34 ] gcd() { a=$1; b=$2 while [ $b != 0 ]; do t=$(($a % $b)); a=$b; b=$t done echo $a } t=$1; shift for i; do gcd=`gcd $t $i` lcm=$(($t * $i / $gcd)) t=$lcm done echo gcd:$gcd lcm:$lcm
537 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 07:15:25.61 ] >>536 不正解 引数 12 20 24 の時、 gcd:12 lcm:120 と表示される。 正しくは GCM = 4 あと、/bin/shでは動かない $(( )) とか
538 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 07:43:40.34 ] >>537 freebsd の /bin/sh で動いたが
539 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 07:54:03.72 ] >>538 >>1 >FreeBSDユーザは/bin/shの正体がashなので注意。 それより、GCMの計算が間違ってるので結局ダメ
540 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 07:54:54.99 ] >>536 posix 互換の /bin/sh なら実装してるんじゃね $((expression)) pubs.opengroup.org/onlinepubs/009695399/toc.htm
541 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 10:00:20.84 ] >>537 Solarisも/bin/shはkshになっちゃいましたよ、おじいちゃん
542 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 10:02:48.59 ] gcdだけ作って秋田。 gcd() { local a b r if [ $1 -gt $2 ]; then a=$1; b=$2 else a=$2; b=$1 fi r=$(( $a % $b )) [ $r -eq 0 ] && { echo $b; return; } gcd $b $r }
543 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 10:09:40.85 ] >>541 なってねーよ。嘘書くな。
544 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 10:37:43.03 ] >>543 なってるよ。おじいちゃん用のshは/usr/sunos/bin/shに隠居しました。
545 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 10:41:42.83 ] >>544 なってないよ。 opensolaris ≠ solaris あと、pdkshになってるopensolarisだとしても、 「正体はkshだから注意」ということで/bin/shのお題の回答としては不正解。
546 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 10:54:47.13 ] ぷぷぷ
547 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 10:59:30.51 ] Solarisなんていつまであるんだろうなぁ。
548 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 11:18:01.21 ] $((expression))がサポートされてなければexprに書き換えれば すむ事だから大した問題じゃないよね。 多分、/bin/shってお題はcsh使うなカスって意味だろうね。 おじいちゃんはこんなところで重箱の隅つついてないで、外へで てゲートボールのエースでも目指した方がいいよ。
549 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 11:18:28.78 ] gcd(){ i=$1 while [ $(($1%i+$2%i)) -ne 0 ];do i=$((i-1)); done echo $i } g=$1 l=$1 while [ $# -gt 1 ]; do shift g=`gcd $g $1` l=$((l*$1/`gcd $l $1`)) done echo gcd=$g lcm=$l
550 名前:526 mailto:sage [2012/03/16(金) 11:44:30.22 ] >>548 >多分、/bin/shってお題はcsh使うなカスって意味だろうね。 違います。従来からの/bin/shを使えという課題です。 >大した問題じゃないよね それでは課題として点がもらえません。 大した問題かどうかは関係なく、課題通りの答が必要です。 引続き回答をお願いします。 表示形式も含めて課題です。
551 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 12:16:37.52 ] User Environment Feature Changes - Transitioning From Oracle Solaris 10 to Oracle Solaris 11 docs.oracle.com/cd/E23824_01/html/E24456/userenv-1.html
552 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 12:19:43.22 ] あらkshからbashになったのね。> Oracle Solaris 11の/bin/sh
553 名前:526 mailto:sage [2012/03/16(金) 12:23:58.00 ] 私の為に争わないでください 課題の回答だけお願いします
554 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 12:24:33.25 ] >>552 えっと……どこをどう読めばそうなるのかとても不思議
555 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 14:29:31.51 ] >>553 ちったぁ自分で考えろ
556 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 14:45:01.99 ] >>552 > The default shell, /bin/sh, is now linked to ksh93. The default user shell is the Bourne-again (bash) shell. the default user shell ってのは useradd したときのデフォルトとかの意味だろうね。 /bin/sh は ksh93 だ。
557 名前:526 mailto:sage [2012/03/16(金) 14:45:06.16 ] 時間が無い。早くしてください。 来週の月曜の朝10時までにお願いします。 過程とか不要です。答えだけ書いてください。 もし回答以外のことも書きたい場合はスクリプトを*で囲って 目立つようにしてください 書き方の例を示します **************************** a = 3 x + y = 5 ****************************
558 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 14:46:05.73 ] 今それどころじゃないからちょっと黙ってて。
559 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 14:51:59.23 ] ここまで、 「宿題は自分でやれ」 「来年はちゃんと講義聞こうな」 なし
560 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 15:38:56.29 ] 分からない人は黙っててください
561 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 18:41:04.43 ] >>560 それって、お前も黙らなきゃいけないんじゃないか?
562 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 18:44:07.77 ] すべて分かった上で言ってるんだよ。
563 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 18:45:05.35 ] **************************** #! /bin/bash set -e function gcd() { local -i i j for ((i="$1";; i--)); do for j in "$@"; do ((j % i != 0)) && continue 2 done echo "$i" return done } function lcm() { local -i i=1 j for j in "$@"; do ((i *= j / "$(gcd "$i" "$j")")) done echo "$i" return } printf "GCM = %d\nLCM = %d\n" "$(gcd "$@")" "$(lcm "$@")" **************************** 空気を読んで? bashで。 大学生はもう春休みなはずだが、実習? それともこれだけできれば単位が貰える系か? # 今年は進級できるかなあ、自分。
564 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 18:47:50.70 ] >>563 だからぁ、bashじゃ駄目だっておっしゃってますが・・
565 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 21:19:30.14 ] >>548 > $((expression))がサポートされてなければexprに書き換えれば > すむ事だから大した問題じゃないよね。 letは使えないの?
566 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 21:21:16.68 ] もうできてる人が何人もいるんです 3/19の10:00まで待つと書きましたが、前倒して3/17の16:30までとします >>557 にあるフォーマットでお願いします
567 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 21:22:56.00 ] >>565 もちろんletも使えない。
568 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 21:41:50.80 ] >>563 最大公約数求めるのに引数デクリメントしながらすべて割って試すとか 総当たりの非効率アルゴリズム使ってボケるんなら、 最小公倍数でもインクリメントしながら順番に割って総当たりするアルゴリズムで ボケるべき。
569 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 21:49:10.39 ] つか, /bin/sh って言ってる奴いるけど, どの時点でどの機能が入った /bin/sh まで許せるんだ? FreeBSD の ports で拡張機能すべて許可した v7sh では func(){} すら Syntax error なんだが... # 少なくとも ``#!/usr/bin/env bash'' くらいにしないと販促だ >>563
570 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 21:54:56.85 ] >>566 バカ共の相手が面倒になったので締め切りました。 やっぱりバカしか居ないんだな。
571 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 22:25:57.27 ] なりすまし多いね
572 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 22:27:13.29 ] >>557 できたよ。GCMとLCMの計算方法が対称的になるようにしたよ。 /bin/sh純正だ。アルゴリズムはウケ狙いだけどな。 #!/bin/sh GCM=$1 while :; do for i in "$@"; do if [ `expr "$i" % "$GCM"` != 0 ]; then GCM=`expr "$GCM" - 1` continue 2 fi done echo GCM = "$GCM" break done LCM=$1 while :; do for i in "$@"; do if [ `expr "$LCM" % "$i"` != 0 ]; then LCM=`expr "$LCM" + 1` continue 2 fi done echo LCM = "$LCM" break done
573 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 22:28:07.31 ] 自演も多いよ
574 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 23:17:57.60 ] 本人です 3/17 17:00までに提出しないと単位が足りなくなるのが分かったので質問してます レポートに貼り付けるのは私がしますので、3/17の16:30までにお願いします また他の皆さんについても、ソースにバグがないかどうか、早急なチェックとデバッグを 期待しています >>557 にあるフォーマットでお願いします
575 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 23:25:20.31 ] そろそろ飽きたわ。もう十分釣れただろ
576 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 23:37:15.49 ] ていうかもうできてんじゃないの?確かめてないけど
577 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 23:39:45.15 ] 編集前ディレクトリと編集後ディレクトリを比較して、 変更がないファイルを編集後ディレクトリから削除する シェルスクリプトを書こうとしています。 diffをディレクトリ同士で実行し同名ファイルを探し その同名ファイルをdiffし返値が空なら削除という操作を 再帰的に階層を掘って実行すれば良いと思うのですが、 どうも何から書けばいいのか詰まってしまいました。 奇特な方居ましたらアドバイスお願いします。
578 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/16(金) 23:45:20.44 ] >>577 まず、man diffをちゃんと嫁
579 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/17(土) 00:14:42.67 ] >>578 オプションよく読んでいませんでした。 読んで出直してきます。ありがとうございました。
580 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/17(土) 05:25:42.88 ] >>577 目的に対する作業の方法が間違ってる気がする。 何のために「編集前ディレクトリと編集後ディレクトリを比較して、 変更がないファイルを編集後ディレクトリから削除する」のか を書いた方が、適切な答えが帰ってくると思う。
581 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/17(土) 07:12:42.07 ] >>577 ひな形っぽいもの。階層が一つだけだからヒントにしかならんだろうけど。変数は出鱈目。 やりたいことのイメージは、こんなもんでしょ? # mkdir /tmp/mae # mkdir /tmp/ato # MAE=/tmp/mae # ATO=/tmp/ato # # touch $MAE/aaa # touch $MAE/bbb # cp -p $MAE/aaa $ATO/ # echo hoge > $ATO/bbb # # cd $ATO # for ii in `ls` > do > [ -f $MAE/$ii ] && diff $ii $MAE > /dev/null 2>&1 > [ $? = 0 ] && rm $ii > done # # ll $ATO bbb ちなみに HP-UX で検証。 ls > tmp.txt して while read LINE; do〜done < tmp.txt とか LINE=`head $NUMBER tmp.txt | tail -1` でも目的だけは達成できる感じ。
582 名前:526 mailto:sage [2012/03/17(土) 07:30:38.91 ] >>572 さんありがとうございます。/bin/sh命令のみですね。 これで提出します。
583 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/17(土) 15:36:57.64 ] >>572 こんなバカみたいな総当たりはダメだって言われちゃいました もっと数学的な解法をアルゴリズム化したものでないとダメです 結果が正しければいいってレベルじゃないんです 100万とか1000万とか、それ位大きな値になると、ちっとも終わらないじゃないですか 期限は今日の16:40までとします くれぐれもよろしくお願いします
584 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/17(土) 16:12:07.29 ] >>583 できたよ。100万でも1000万でも、正しく実行すればすぐ終るよ。 #!/bin/sh while :; do echo -n 'Enter GCM = '; read GCM for i in "$@"; do [ `expr "$i" % "$GCM"` != 0 ] && { echo 'Try again'; continue 2; } done; break; done echo GCM = "$GCM" while :; do echo -n 'Enter LCM = '; read LCM for i in "$@"; do [ `expr "$LCM" % "$i"` != 0 ] && { echo 'Try again'; continue 2; } done; break; done echo LCM = "$LCM"
585 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/17(土) 22:26:32.20 ] >>577 LANG=C diff -qrs a b の出力結果でなんとかする というかバージョン管理システムを使うのが良い気がする
586 名前:名無しさん@お腹いっぱい。 mailto:sega [2012/03/19(月) 12:31:35.64 ] A=*.txt B=$A touch $B とすると、"*.txt"というファイルが出来てしまうんですが これ$Bを展開させたいときはどうすればいいんですかね
587 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 12:40:39.27 ] >>586 本当に >>586 のとおりに実行したのなら *.txt は展開される。 展開されないのはカレントディレクトリに *.txt にマッチするファイルがないから。 すでにファイルがなければ展開しようがない。
588 名前:586 mailto:sage [2012/03/19(月) 12:56:05.81 ] >>587 ヒントありがとうございます oppai.txt がある場合⇒ oppai.txtにタッチ oppai.txt がない場合⇒ *.txt を作成 という動きになりました まーこれはこれで使い物になりませんわ
589 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 13:11:29.40 ] 存在をチェックしてからtouchすればいいじゃない。
590 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 13:13:49.05 ] >>588 もし「存在しなければ作成したくない」という意図なら、 touch -c $B で桶。
591 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 13:45:15.79 ] >>586 エスパーすると、 A=*.txt B=$A mv $A /どこか touch $B みたいなことをやりたいのでは? それなら、 A=`echo *.txt` mv $A /どこか touch $A で桶。変数はAだけでよい。
592 名前:586 mailto:sage [2012/03/19(月) 14:20:52.93 ] >>590 天才や・・・ UNIX板には天才がたくさんいる みんなありがとう
593 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 14:28:02.20 ] いや、みんなは普通だよ。
594 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 15:43:16.30 ] >>591 のアホさが光るな。
595 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 15:45:13.28 ] >>586 これなんでBをはさんでるの?
596 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 17:56:07.30 ] おそらく A=*.txt で *が展開されなかったから Bに代入し直せば再解釈されて展開されると勘違いしたのだろう
597 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 19:53:24.01 ] 結局、どこで展開されたんだろうね
598 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 19:56:34.87 ] ん? A=*.txt でも B=$A でも 変数直接代入時は展開されないよ。 touch $B みたいにクォートなしで参照した時に初めて展開される。
599 名前:586 mailto:sage [2012/03/19(月) 19:58:57.99 ] >>598 ありがとう。それだけが心残りだったんだ
600 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 20:04:56.95 ] shを作ったBourneは天才だね。
601 名前:名無しさん@お腹いっぱい。 [2012/03/19(月) 20:08:20.98 ] あのソースコードは勘弁して欲しい。
602 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 21:12:40.16 ] ソース読んだのか あんたスゲーや
603 名前:名無しさん@お腹いっぱい。 [2012/03/19(月) 22:06:26.63 ] ソースコードつーか、これな。 ttp://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h
604 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 08:01:57.14 ] x68000.q-e-d.net/~68user/unix/pickup?keyword=test&target=command のサイトに、 #!/bin/sh read input if [ $input = 'q' ]; then echo QUIT fi と言うシェルスクリプトを参考に if [ "$input" = 'q' ]; then と $input をダブルクォートで囲めばよい。しかしまだ落とし穴はある。たとえば "!" を入力すると、 [: =: unexpected operator とまたしてもエラーになってしまう。これは "$input" が "!" であるため、 if [ ! = 'q' ]; then として扱われたからだ。 ってありますけれど、何度!を入力しても、 [: =: unexpected operator って表示されません。 それに、 $ test !c = 'q' ; echo $? test cd /etc = 'q' ; echo $? test: too many arguments とエラーが表示されます。 どのような解釈をすると、!cがtest cd /etcに置換されるのでしょうか?
605 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 09:04:17.23 ] > [ ! = 'q' ] これはそのように解釈するtestもあるから注意しろ。くらいでいいと思う。 > どのような解釈をすると、!cがtest cd /etcに置換されるのでしょうか? ヒストリ置換だろ。
606 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 17:36:56.09 ] >>605 今の時代、そのエラーが出るshを使っている人、いるのかね?
607 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 17:41:15.64 ] 今の時代、 [ ! = ! ] [ [ = [ ] [ ] = ] ] [ = = = ] [ -f = -f ] など、すべて文字列の比較として期待通りに動作する
608 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 17:51:22.47 ] しかし未だに [ x"$hoge" = x"yes" ] などと書いてる人を見掛けるな #!/bin/bashとか書いてるのに
609 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 19:57:58.15 ] スクリプトインジェクション対応だよ
610 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 21:45:56.60 ] [ "$hoge" = yes ] だとして具体的にどうインジェクトするんだよ
611 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 23:34:08.60 ] >>610
612 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 09:04:25.40 ] >>611 どうインジェクションするか解説お願いします
613 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 10:08:32.37 ] hoge=']; /bin/sh;'
614 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 10:47:17.62 ] ってゆーか、こういう場合は case "$hoge" in yes) ...;; esac って書くよね、ふつー。[Yy][Ee][Ss] なんかに変えるのも簡単だし。
615 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 11:14:27.91 ] >>613 >>610 はダブルクオートで囲ってるから、[コマンドの第一引数として$hogeの中身が渡るんで、そのhogeの値はそのまま[コマンドが解釈する。 どうあがいてもインジェクションなんて無理だと思うんだが。
616 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 11:26:14.79 ] てきとーに言ったんだろ。 もうカンベンしてやれ。
617 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 12:19:06.39 ] 本人乙
618 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 13:26:55.78 ] 違うよ。
619 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 13:38:09.35 ] 最近のJavaScriptのようにeval使いまくりで威張る奴か。
620 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 14:28:05.05 ] >>619 座布団
621 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 15:37:01.15 ] 全部持ってって〜
622 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 19:24:26.73 ] >>606 $ busybox ash $ hoge=! $ if [ "$hoge" = 'q' ]; then echo QUIT; fi ash: q: unknown operand
623 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 22:56:44.16 ] https://uec.usp-lab.com/SHELL_TIPS/CGI/SHELL_TIPS.CGI?POMPA=TIPS_not_while に >シェルスクリプトに制御構文が増えることを極力避けるように様々な工夫をしている。 >制御構文を避ける理由はコードが読みにくくなるためだ。 >これまで制御構文whileやforのはずし方について書いてきた。 >処理速度を高速化するためにwhileやforをコマンドに置き換えるというのは、 >それなりの効果が期待できる方法だ。 >シェルスクリプトに制御構文であるforやwhileが出てきたら、 >何か避ける方法がないか探してみるとより高速なスクリプトが書けるようになるかもしれない。 ってかいてあって、いろんな例が書いてあったり、 変なパッケージ(python製)を入れて、そのコマンドを使ったりしてるんですね。 僕は制御構文外すと逆に可読性がおちたり、 pythonで書かれたコマンドを呼び出すより、シェルスクリプトで制御構文書いた方が 早いと思うんですけど、おかしいですかね?
624 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 23:01:45.31 ] 質問です。 以下のようなファイルがあるとします。 ----------------- 1. aaa hello 2. bbb 3. ccc 4. ddd hello 5. ddd hello 6. eee hello ----------------- このファイルの2行目から5行目に限定して、helloをgood byに変更したいです。 どのようなやりかたがありますでしょうか? sedを使えばいいのかなと思うのですが。。
625 名前:名無しさん@お腹いっぱい。 [2012/03/21(水) 23:09:05.42 ] お前はマニュアル読むという事を考えたことが無いのか?
626 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 23:34:20.22 ] >>624 うん、sedの超基本的な使い方で出来る
627 名前:名無しさん@お腹いっぱい。 [2012/03/21(水) 23:34:53.13 ] sedを使えばいいと思うよ
628 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 23:41:30.82 ] >>623 そのページを見て思ったことは、xargsは便利だね、くらい
629 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 00:58:20.98 ] >>623 シェルスクリプトに限らず、プログラム書く時に(一部の)制御構文を使わないってのは個人的に良くやる。効率とか性能とか抜きで。 ゲームの縛りプレイみたいなもんだけど、意外なテクニックを発見したりできて楽しめるよ。おすすめ。 上司や同僚に見つかったら>>623 のサイトみたいな適当なウンチクで誤魔化せばOK。
630 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 01:14:19.58 ] >>624 sed で 2行目から5行目は 2,5。 hello を good byに置換するには s/hello/good by/ 接続すると 2,5s/hello/good by/
631 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 02:23:18.01 ] >>629 BASICのころはあったけどな。 if文分岐とかで速度差が出ないようにするとかで。 今はそういうのする必要ないけど。
632 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 08:22:33.32 ] PerlやC#、COBOL、Fortran、アセンブリなんかも、見慣れてなければ読みにくく 感じるものさ
633 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 08:28:41.72 ] Whitespaceもな。
634 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 09:18:49.18 ] 俺はsedが嫌いなので、できるだけperlを使うようにしている
635 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 09:56:14.04 ] それは報告しなくてもいいです。
636 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 11:24:16.01 ] kshで待ち行列を作りたいんですが、どうしたらいいでしょう? 基本動作はキューなんですが、 1 2 3 ↓1を実行 2 3 1 2 3 ↓2を実行 1 3 としたいです unset 配列[N]でインデックスを詰めてくれればこんなの楽勝なのに…
637 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 11:37:02.12 ] >>636 ファイルにしたらいい
638 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 20:00:10.46 ] 位置パラメータ使う。 $ set -- 1 2 3 4 $ shift $ echo $@ 2 3 4 $ set -- 1 2 3 4 $ set -- $1 ${@:3} $ echo $@ 1 3 4
639 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 20:22:13.25 ] >>636 unset array[N] で要素をunsetした後に、 array=(${array[@]}) でセットしなおせばインデックスは詰まる。 >>638 とは違って位置パラメータを壊さずに済む。
640 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 21:29:35.34 ] >>639 かっこういい
641 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/23(金) 22:05:53.20 ] シェルスクリプト学び始めたばかりの初心者です。 ・ファイルを指定フォルダ内へコピー ・同名ファイルが存在する場合は、 既に存在するファイル名を「ファイル名 (1)」へ変更し、 既に「ファイル名 (1)」が存在しているのであれば、 それをさらに「ファイル名 (2)」へ変更し、、、(繰り返し) というシェルスクリプトを書きたいんですが、 既に「ファイル名 (*)」が存在する場合に*の数字を どのようにすれば知ることができますか? *さえ知れたらexprを使えば出来るとは思うのですが... アドバイスお願いします。
642 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/23(金) 22:27:01.94 ] >>641 逆に考える。 変数iとかに1を入れておいて、 "ファイル名($i)" が存在したら iをインクリメントして "ファイル名($i)" にリネームする。
643 名前:名無しさん@お腹いっぱい。 [2012/03/23(金) 22:28:54.51 ] 再帰使わないとややこしいことになりそうだな。
644 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/23(金) 22:32:05.36 ] 最小の空きを使うんでいいの? i=1; while [ -f "file($i).txt" ]; do i=`expr $i + 1`; done; echo $i
645 名前:名無しさん@お腹いっぱい。 [2012/03/23(金) 22:52:22.20 ] 「それを」が何を指すかによる。
646 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/23(金) 22:56:33.59 ] GNU cp なら --backup=numbered とか?
647 名前:名無しさん@お腹いっぱい。 [2012/03/24(土) 01:18:46.16 ] なんか見覚えがある処理だと思ったが logrotate かいな。
648 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 10:30:46.53 ] >>641 つまりアヌスを知りたいと……教えてあげよう
649 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 18:23:06.74 ] >>641 実機が無いので試せないけど・・・ 第一引数:コピー対象ファイル名(絶対パス指定) 第二引数:コピー先ディレクトリパス #!/bin/ksh FILE_NAMEW=`basename ${1}` COUNT=1 TARGET_FILE=${2}/${FILE_NAME} if [[ -e ${TARGET_FILE} ]]; then while true do if [[ -e "${TARGET_FILE}(${COUNT})" ]]; then COUNT=`expr ${COUNT} + 1` else cp ${1} ${TARGET_FILE}(${COUNT}) break fi done else cp ${1} ${TARGET_FILE} fi exit 0
650 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 18:40:54.37 ] 突っ込みどころ多いな
651 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 18:48:18.47 ] もっと単純にこうだろ。 第1引数: コピー元ファイル(絶対/相対path関係なし) 第2引数: コピー先ファイル(ディレクトリではない) #!/bin/sh FILE=$2 if [ -f "$FILE" ]; then i=1 while [ -f "$FILE($i)" ]; do i=`expr $i + 1` done FILE="$FILE($i)" fi cp "$1" "$FILE"
652 名前:641 mailto:sage [2012/03/24(土) 21:11:20.76 ] 皆さんアドバイスありがとうございました。 642さんの意見を参考に書いていたら、 651さんとほぼ同じようなものが書けました。 勉強になりました!
653 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 22:20:08.70 ] その書いたものをさらしてくれると みんなも勉強になるんだけどなぁ
654 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 22:34:45.96 ] #!/bin/bash [ -e "$2" ]&&{ i=0; while [ -e "$2($((++i)))" ];do :;done; set "$1" "$2($i)";} cp "$1" "$2"
655 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 10:39:31.72 ] rm -rf -- * ってどういう風に解釈すれば良いんですか? -- って正規表現ですか? *はファイル名ですか?
656 名前:名無しさん@お腹いっぱい。 [2012/03/25(日) 10:59:50.45 ] >>655 その * は glob。シェルが解釈する。 シェルが展開して rm に渡す。 -- は正規表現でも何でもなくて、ただの --。 シェルは特に何もしない。 そのまま rm に渡される。
657 名前:名無しさん@お腹いっぱい。 [2012/03/25(日) 11:00:45.80 ] rm が -- をどう解釈するかは man rm に載ってるはず。
658 名前:名無しさん@お腹いっぱい。 [2012/03/25(日) 11:28:39.15 ] - で始まるファイル名(コマンドからはオプションに見える)に マッチしたときのための策だな。
659 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 11:51:49.52 ] でも rm -- が使えるのは GNU rmだけだから、使わない方がいいな。
660 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 12:14:56.30 ] >>659 調べたらBSD系はgetopt(3)つこうてるから--大丈夫だよと書いてあったんだけど 他のUNIXはまた違うの?
661 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 12:24:48.03 ] BSD以外のUNIXってあるの?
662 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 13:38:40.68 ] ねーよんなもん
663 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 13:56:37.10 ] Solarisのmanには、BSDユーザーのために仕方なく -- が使えるようにしてあるが、 将来は -- が使えなくなるので注意、と書いてあるね。
664 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 18:55:04.62 ] ワイルドカードを使うときは rm ./* みたいにすれば引数の先頭が - になることはない。 --が使える保証がなければこっちで。
665 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 20:43:30.34 ] この手の問題って rmだけじゃなく cp mv ln等全部なんだよな。 で、-- が使えない ln で、-sという名前を指しているsymlinkを作ろうと、 ln -s ./-s hoge ってやると、hoge -> ./-s というsymlinkができて、 symlink自体に ./ が含まれてしまって美しくない。 -- が使えない条件で 、hoge -> -s は作れないものか。
666 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 22:24:57.35 ] リンク作る部分をスクリプト言語に投げるとかは? じゃあ全部スクリプトでやれよみたいな話になりかねんからダメかね
667 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 23:41:27.50 ] >>664 昔からUnixやってる奴は普通そのやり方だよな --指定してても、引数に./*でなく*を指定するのは違和感を感じる
668 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 06:20:04.43 ] 特定のフォルダのpngファイルを見つけて 「◯◯◯.png」というファイルを見つけました と表示させたいのですが、なるべくコンパクトにするにはどのようにすればいいでしょうか? 自分のやり方だとbasenameで失敗してうまく表示されません あと、そのフォルダにpngファイルがなかった場合は何も表示しないようにしたいです。 find ${DIR}/ -name "*.png" -exec echo "「`basename {}`」というファイルを見つけました" \;
669 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 06:44:41.40 ] >>668 find "$DIR" -name '*.png' -printf '「%f」というファイルを見つけました¥n'
670 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 07:06:33.81 ] >>668 `basename {}`はfind実行より先に展開されてしまうので、 {}という文字列のbasenameが実行されて無意味になっているのが原因。 GNU findなら >>669 でよし。
671 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 07:46:41.98 ] >>668 find "$DIR" -name '*.png' -exec sh -c 'for f;do echo 「`basename "$f"`」というファイルを見つけました;done' - {} +
672 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 14:20:40.93 ] >>669 >>670 >>671 おかげさまでできました! ありがとうございました!!
673 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/27(火) 22:52:24.44 ] 質問です。 開始日付と終了日付を指定したら、その間の日付を出力するスクリプトを作りたいです。 イメージとしては以下のような感じです。 $ ./hoge.sh -s 20120301 -e 20120303 20120301 20120302 20120303 以下の処理までは作ったのですが、ここから先が思いつきません。 --------------------------------------------- $ cat hoge.sh #!/bin/sh while getopts s:e: option do case $option in "s") start_date=$OPTARG ;; "e") end_date=$OPTARG ;; *) ;; esac done --------------------------------------------- よろしくご教示お願いします。
674 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/27(火) 23:18:59.00 ] 日付まわりはシェルでやるとめんどいから perlとか使っちゃう。
675 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/27(火) 23:30:44.14 ] > 以下の処理までは作ったのですが、ここから先が思いつきません。 dateをつかってこんな感じかな ステップ1. 今日の日付を20120301のように出力しよう ステップ2. 20120301のような日付を、UTCエポックからの秒数に換算しよう ステップ3. UTCエポックからの秒数を、20120301のような日付に変換しよう ステップ4. 20120301のような日付を受け取り、その翌日の日付を出力しよう ステップ5. ループを回して指定範囲の日付を全て出力しよう ※UTCエポックは 1970-1-1 00:00:00 UTC
676 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/27(火) 23:42:28.28 ] >>673 bash、GNU date依存 #!/bin/bash while getopts s:e: opt; do case "${opt}" in 's') stime=$(date -d "${OPTARG}" '+%s') ;; 'e') etime=$(date -d "${OPTARG}" '+%s') ;; esac done t=${stime} while (( ${etime} >= ${t} )); do date -d @${t} '+%Y%m%d' t=$(( ${t} + (60 * 60 * 24) )) done
677 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/28(水) 00:15:25.48 ] >>676 bashならこっち for (( t = stime; etime >= t; t += 60 * 60 * 24 )); do date -d @${t} '+%Y%m%d' done
678 名前:676 mailto:sage [2012/03/28(水) 00:53:33.92 ] 添削ありがとう
679 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/28(水) 06:47:17.46 ] >>676 >>677 でOKだね。 そんな中、何の解答にもヒントにもなってない >>675 って・・・
680 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/28(水) 06:56:04.85 ] >>676 >>677 わざわざepochからの秒数に直さなくても、日付だけで行けるよ。 #!/bin/bash while getopts s:e: opt; do case $opt in s) stime=$OPTARG;; e) etime=$OPTARG;; esac done for ((t = stime; etime >= t; t=$(date -d "$t 1 day" '+%Y%m%d'))) { date -d "$t" '+%Y%m%d' }
681 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/28(水) 07:04:16.81 ] >>680 forループ中、dateが1回無駄になってる。せっかく$tに入ってるのでそれ使え。 for ((t = stime; t <= etime; t=$(date -d "$t 1 day" '+%Y%m%d'))) { echo "$t" }
682 名前:680 mailto:sage [2012/03/28(水) 07:10:47.88 ] 添削ども
683 名前:名無しさん@お腹いっぱい。 [2012/03/30(金) 14:34:15.36 ] 標準出力に日付をつけたいんだけど かっこいい方法ありますか?
684 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 14:51:40.88 ] エスパー、日本語解読しろ
685 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 14:55:44.65 ] >>683 #!/bin/sh while IFS= read -r line; do echo "`date`: $line" done
686 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 15:42:18.34 ] >>685 ありがとうございます
687 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 15:44:45.94 ] ∧∧ ヽ(・ω・)/ ズコー \(.\ ノ 、ハ,,、  ̄  ̄
688 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 16:39:16.72 ] ていうかあの文章がわからないとかギャグだろ
689 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 16:44:05.09 ] もうcat --dateでいいよ。 誰かパッチを送れよ。
690 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 17:35:02.11 ] 俺は command > $(date +%Y%m%d) って意味かとオモタ
691 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 18:02:04.91 ] >>690 目的はロギングだな、と想像できれば、毎行にタイムスタンプつけたいんだな ということもわかる
692 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 18:09:51.47 ] >>691 目的はロギングだな、と想像できれば、ログファイル名毎に日付を入れたいんだな と考えるのが自然
693 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 18:15:31.04 ] まぁもう解決したんだからそれでいいんじゃね。
694 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 18:27:01.79 ] 俺は touch -t YYMMDDhhmm /dev/stdout って意味かとオモタ
695 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/31(土) 01:35:03.44 ] 俺はプロンプトに日時を入れるのかと…
696 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/31(土) 04:56:25.93 ] 自分はdate > /dev/tty みたいなことかと思った
697 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/31(土) 17:23:45.97 ] >>680 それだと、1900年とかそれ以前とか、32bit版の場合の2038年以降が動かないし、 GNU dateに依存するのもいやだし、 dateコマンドに頼らずに20120301等のの数字を直接操作して計算する方法ないですか?
698 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/31(土) 17:42:14.02 ] 頑張って書けば可能だけど、 月の長さや閏年とか考えると、GNU dateかLL使うのがいいですよ。 コマンド組み合わせるのがシェルの得意なところだし。
699 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/31(土) 17:47:43.69 ] >>698 GNU date使っても epoch以前の日付には対応できないだろ、って言ってるのでは?
700 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/31(土) 18:35:51.33 ] 昔のこと考えたって、そもそも日本が西暦になったのは明治からだぞ calコマンドが表示してるのはイギリスの暦らしいね $ cal 9 1752 September 1752 Su Mo Tu We Th Fr Sa 1 2 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
701 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/31(土) 18:48:26.54 ] >>700 江戸時代でもそれ以前でも年表は西暦で記述されてるから無問題。 1752年の件も含め、紀元1年以降対応できれば幸いです。 紀元前までは要りません。
702 名前:名無しさん@お腹いっぱい。 [2012/03/31(土) 19:29:56.45 ] localeをイタリアにしたら1582年に暦が切り替わる実装もあるのかな。
703 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/31(土) 20:51:17.87 ] そのくらい前のデータはまだ完全に整備されてない。 ↓こういうデータがあって、Common Lisp, Mathematica, Javaのライブラリがある。 Calendrical Tabulations, 1900?2200 Edward M. Reingold, Nachum Dershowitz www.cambridgejapan.org/academicproduct.html?isbn=9780521782531 けどまあ元のお題についてはGNU dateかLLでやるのがいいかと。
704 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 12:21:49.60 ] >>701 曜日はどうなのよ・・・
705 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 12:24:17.12 ] >>704 20120301 等の数字だけ処理できればいいので、曜日は無視でいいです。
706 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 13:39:02.95 ] >>704 曜日以外はできたのか。じゃあ早く回答してやれよ。
707 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 14:01:13.24 ] >>706 曜日以外は標準で対応し照るじゃん
708 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 14:02:48.07 ] >>707 epoch以前でも?
709 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 14:05:53.14 ] $ date -d "1 years ago" 2011年 4月 1日 金曜日 14:04:49 JST $ date -d "100 years ago" 1912年 4月 1日 月曜日 14:04:55 CJT $ date -d "200 years ago" 1812年 4月 1日 月曜日 14:05:08 CJT できてんじゃん
710 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 14:09:36.73 ] >>709 環境依存なので却下
711 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 14:16:22.13 ] じゃあ環境に依存しない方法を自分で考えてくれ 「すべての環境」に対応するのは骨が折れると思うが 期待しているぞ
712 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 14:21:28.89 ] >>711 >>697 の言うように、20120301等の数字を直接演算すればそもそも環境依存しない。 その演算が場合分けとかでややこしいだけで。
713 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 14:36:54.89 ] >>709 GNU date epoch以前の閏年処理おかしいよ。 $ date -d 16000229 ← 1600年は閏年 Tue Feb 29 00:00:00 LMT 1600 $ date -d 17000229 ← 1700年は閏年 date: invalid date `17000229' ← 駄目じゃん $ cal 2 1700 February 1700 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ← 閏年だよ
714 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 16:31:55.42 ] >>713 グレゴリオ暦で1700年は平年です $ man cal > グレゴリオ暦への切り替えは 1752 年の 9 月 3 日に行われたと仮定している。 $ cal 9 1752 9月 1752 日 月 火 水 木 金 土 1 2 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
715 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 16:37:34.38 ] $ gcal --version | head -n 1 gcal (GNU cal) 3.6 $ gcal 2 1600; gcal 2 1700 ; gcal 9 1752 February 1600 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 February 1700 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 September 1752 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
716 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 16:47:02.18 ] >>714 1700年はまだグレゴリオ暦に切り替わってないのだから、 1700年は閏歳が正しい。 別の例として、 1500年は閏歳なのだが、 calでは閏歳(正しい) GNU dateでは平年(間違い) いずれにしても GNU dateでこの年代の日付処理はできない。
717 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 17:25:06.62 ] 西暦年が100の倍数の時、 1700年以前なら単純にすべて閏年にする。 1800年以降の場合は、400の倍数でない年のみ平年に戻す。 で桶? case文バリバリでだれかシェルで組んでくれ。
718 名前:名無しさん@お腹いっぱい。 [2012/04/01(日) 17:54:49.44 ] 厳密にやるためには国や宗教の情報が必要になるので あまりしゃかりきにならんでええ。 日本は1872年かな。
719 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 18:04:26.31 ] 日本においては閏年の算定を皇紀を用いて行うことが法令で定められています
720 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 18:12:40.42 ] >>717 できた気がする。思ったより場合分け簡単だった。 1752年9月も対応 s_date=20120227 # 仮 e_date=20120305 # 仮 t=$s_date while [ "$t" -le "$e_date" ]; do echo "$t" t=`expr "$t" + 1` case $t in ????0[13578]32|????1032) t=`expr "$t" + 69`;; ????1232) t=`expr "$t" + 8869`;; ????0[469]31|????1131) t=`expr "$t" + 70`;; ????0230) t=`expr "$t" + 71`;; 17520903) t=17520914 esac case $t in ????0229) y=`expr "$t" / 10000` case `expr "$y" % 4` in 0) [ "$y" -le 1700 ] && continue [ `expr "$y" % 400` = 0 ] && continue [ `expr "$y" % 100` != 0 ] && continue ;; esac t=`expr "$t" + 72`;; esac done
721 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/01(日) 19:24:47.68 ] >>720 西暦999年以前がダメ。頭に0付け加える処理が必要。
722 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/03(火) 07:17:19.37 ] >>720-721 ありがとうございました
723 名前:名無しさん@お腹いっぱい。 [2012/04/03(火) 20:05:15.60 ] ファイルがあるかないかだけを調べる標準のコマンドありますか? [ -f /tmp/unko ] よりかっこいい方法募集
724 名前:名無しさん@お腹いっぱい。 [2012/04/03(火) 20:06:28.95 ] test(マテ
725 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/03(火) 20:20:14.40 ] 「標準のコマンド」とは?
726 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/03(火) 20:44:46.90 ] >>725 まず入ってるであろうコマンドのことだよ coreutils と読み替えてもらっても結構
727 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/03(火) 20:46:12.15 ] この程度で揚げ足取ったつもりなのが笑える
728 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/03(火) 20:52:43.65 ] つまりシェルビルトインコマンドは禁止ということですね
729 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/03(火) 21:13:29.78 ] ls /tmp/unko > /dev/null 2>&1 && echo yes || echo no
730 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/03(火) 21:18:54.77 ] >>723 < /tmp/unko 2> /dev/null && echo ある
731 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/03(火) 22:18:53.41 ] (< /tmp/unko) 2> /dev/null && echo ある
732 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 10:03:23.15 ] testと[って同じだって書いてあるけど、]の立場はどうなるの?
733 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 10:04:50.22 ] >>732 ] はコマンドじゃないから
734 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 10:07:01.64 ] ] は [ の引数
735 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 10:52:50.01 ] testの引数にはならないの? $ test -f /tmp/unko ] -bash: test: /tmp/unko: binary operator expected なんかエラーでた
736 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 10:54:52.95 ] 自分が [ って名前かどうかで、 ] が最後にあるべきかどうか判断するんだよ
737 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 10:59:35.40 ] >>723 なんで [ じゃだめなの?
738 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 12:05:16.44 ] >>736 うぉぉ マジだ。 test.c ってこんなことやってんのか。 はぁー 無駄にすげぇーなー
739 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 12:15:50.42 ] 20年遅れてるスレ行けよ。何でいまさら誰でも知ってる話題でこのスレ無駄使いしてるの?
740 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 12:21:38.54 ] test -e
741 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 12:40:51.61 ] >>740 test以外でかっこいい方法で
742 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 13:12:21.67 ] かっこいい(笑)
743 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 13:21:55.37 ] 評価基準がよくわからん。
744 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 15:21:58.49 ] >>743 coolかどうかってことだよ
745 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 15:23:15.61 ] それがわからん。
746 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 15:43:57.60 ] >>739 お前2でなに言ってんだよ
747 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 16:47:37.67 ] >>746 どういう意味?
748 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 23:21:13.48 ] 教えてください TERM=$( (echo 'console() { term="$2"; for i do case $i in term=*) term=$(expr "$i" : "term=¥(.*¥)") esac done; echo "$term"; exit 0 }' というシェル関数なんですが、制御構文が良くわかりません。 for 変数 in 引数1 引数2 … do 処理 done とはかけ離れてますし(変数も引数もない)、 case 変数 in パターン1) 処理;; パターン2) 処理;; パターン3 | パターン4) 処理;; *) 処理;; esac が混じってますし... case文のどのパターンにも当てはまらない時の処理に「term=」がくっついてるし... これってどういう風に解釈すれば良いんでしょうか?
749 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/04(水) 23:30:30.61 ] set a b c for i; do echo $i; done とかやってみれ
750 名前:名無しさん@お腹いっぱい。 [2012/04/04(水) 23:31:20.38 ] for に in がない場合は位置パラメータ($1 $2 ...)を使う。 位置パラメータをiにセットしつつforループを回して、 $iが term=* のパターンにマッチしたとき、 そのなんたらの部分(*にマッチした部分)をexprで抜き出して 変数termにセットする。 位置パラメータ全周したらその時点の $term を出力。 というconsole関数。
751 名前:名無しさん@お腹いっぱい。 [2012/04/05(木) 12:29:39.61 ] 教えてください>< 以下のようなテキストファイルがあって、これを読み込んで下のような結果にするスクリプトを書きたいんですがいい方法が思いつきません; 地区、支店、名前が同じものは一番右にある数値を足しこんで出力すると言うものです。 awk のgetline を使えばどうにかなりそう・・・というイメージなんですが、どなたかご教授ください(泣 テキストファイル ---------------------------- A地区 〇支店 佐藤 5 A地区 〇支店 佐藤 9 B地区 □支店 伊東 3 B地区 □支店 木村 3 B地区 □支店 木村 5 C地区 △支店 青木 4 C地区 △支店 青木 4 C地区 △支店 野村 1 ---------------------------- 結果 ---------------------------- A地区 〇支店 佐藤 14 B地区 □支店 伊東 3 B地区 □支店 木村 8 C地区 △支店 青木 8 C地区 △支店 野村 1 ----------------------------
752 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/05(木) 12:39:50.77 ] >>751 awkで、getlineを使わずに普通にできる。 ただし、数字は半角で書いてないと計算できない。
753 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/05(木) 12:48:51.09 ] >>751 あっちスレの削除依頼出してきてよ。
754 名前:名無しさん@お腹いっぱい。 [2012/04/05(木) 13:03:00.03 ] >>753 すみません、やり方がわからないんで・・・ 後で出します;
755 名前:名無しさん@お腹いっぱい。 [2012/04/05(木) 13:06:43.25 ] >>752 getline を使わずにですか・・・ ちょっとヒントいただけますか?
756 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/05(木) 13:21:01.61 ] >>751 awk使わずにシェルだけでできるよ。 ただし、スペースは半角に、数字も半角にしてから実行すること。 標準入力から入力。 #!/bin/sh p_district= p_branch= p_name= n=0 while read district branch name val; do if [ "$district" = "$p_district" ] && [ "$branch" = "$p_branch" ] && [ "$name" = "$p_name" ]; then n=`expr "$n" + "$val"` else [ "$p_district" ] && echo "$p_district" "$p_branch" "$p_name" "$n" p_district=$district p_branch=$branch p_name=$name n=$val fi done echo "$p_district" "$p_branch" "$p_name" "$n"
757 名前:名無しさん@お腹いっぱい。 [2012/04/05(木) 13:33:45.35 ] >>756 お〜、有難うございます!大変助かります! 半角にして試して見ます。 ちなみに $0 テキストファイル といった具合に、テキストファイルを引数にして読み込み処理する、というようなことも出来るでしょうか?
758 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/05(木) 13:35:37.33 ] >>757 引数にしたかったら、 >>756 のしたから2行目の done のところを done < "$1" に修正すれば良い。 あと、入力ファイルはあらかじめソートされてること
759 名前:名無しさん@お腹いっぱい。 [2012/04/05(木) 13:42:26.55 ] >>758 すごい! 自分もこんなにあっさりスクリプトが書けるようになりたいものです・・・ 758 さん、有難うございました、大変勉強になりました。
760 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/05(木) 13:50:38.48 ] awkなんてAhoでもできることなのに
761 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/05(木) 14:44:15.71 ] だれか>>760 の座布団全部取り上げろ
762 名前:名無しさん@お腹いっぱい。 mailto:sega [2012/04/07(土) 17:42:25.29 ] ディレクトリのmvできるかどうかを事前にチェックしたい 特定のディレクトリ以下に アクセス不能とか移動不能なものが あるかどうかを調べたいんですが、findでいいですかね
763 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/07(土) 19:40:38.64 ] だめだ、難しい グループでOKになってるときのパターンがネックだ これのせいでワンライナーにならん
764 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/07(土) 22:52:59.06 ] >>762 find . ! -readable | wc -l でダメ?
765 名前:sage [2012/04/10(火) 19:58:25.17 ] for i in {1..10}; do command 1> ${i}.txt 2> ${i}.log &; done とかやると, [1] + suspended (tty output) ... とかなって処理が終了しない.なぜぇ・・・
766 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/10(火) 21:04:40.05 ] それはね…
767 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/11(水) 08:00:04.70 ] >>765 面白いと思う
768 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/12(木) 09:02:11.67 ] ;が邪魔だって文句いわれたから、 はずして実行したら {1..10}.txt とかできたぞ どうしてくれる マジレスすると、commandの中身なによ
769 名前:sage [2012/04/12(木) 10:33:02.93 ] Cで書いたプログラムだね.
770 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/12(木) 19:19:17.01 ] commandはシェルビルトインコマンドでしょ
771 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/12(木) 19:30:36.07 ] というか、>>765 実行してもそういう現象は起きないので、 回答欲しかったらもっと具体的に "how to repeat" 書いてくれ
772 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/12(木) 21:09:49.38 ] >>765 そのcommandのプログラムがSIGTTOUをSIG_DFLに戻してしまってるんだろ。 普通ならシェル側でSIGTTOUはSIG_IGNにするからsuspendはしないようになってる。
773 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/12(木) 21:25:50.42 ] >>771 Steps to Reproduce だろ
774 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/12(木) 21:34:14.02 ] >>773 How to repeatで合ってる。というか、そんなところに突っ込んでも面白くない。
775 名前:名無しさん@お腹いっぱい。 [2012/04/12(木) 22:19:43.60 ] 再現性の話ならreproduceがふつー
776 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/12(木) 22:24:50.96 ] SIGTTOUについて答えられない奴が持論の英語を主張して話題逸そうとしてるなw
777 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/12(木) 22:27:19.83 ] 「バグの出し方」と書かれてる文章に、 「バグの再現手順」だろ? と突っ込んでるようなモン。
778 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/12(木) 23:01:56.84 ] GNUのバグトラッキングシステムがHow-To-Repeatってフィールド使ってるね www.gnu.org/software/gnats/doc/3_113_1/gnats_1.html
779 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/13(金) 06:11:12.98 ] >>765 エスパーするとzshの最近のバージョンでのバグ。
780 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/13(金) 14:26:30.54 ] w3m & で起きる奴とおんなじ.どうすればいいんだろ・・
781 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/13(金) 14:34:14.58 ] 何のこと?
782 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/13(金) 14:44:26.87 ] >>781 >>768 の件.
783 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/13(金) 14:44:40.34 ] >>780 set +m で、ジョブコントロールを無効にすれば桶。 ただ、シェルスクリプト中から起動すればデフォで set +m 状態なんだがな。 コマンドラインから直接起動してるのか。
784 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/14(土) 21:01:39.51 ] どこに書いていいのかわかんないから、ここに書いてみる。 shell script書いててはまったんだけど、 ls -l /etc | sort -k4 -n がファイルサイズでソートしてくんない。 こんな↓感じで、なんか部分的にしかソートしてくれないみたい。 dpaste.org/ri4On/ バグ? 理由を知ってる人がいたら教えてちょうだい。 環境: debian squeeze $ uname -a Linux bauhaus 3.2.0-2-rt-686-pae #1 SMP PREEMPT RT Fri Apr 13 02:23:30 JST 2012 i686 GNU/Linux $ sort --version sort (GNU coreutils) 8.5
785 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/14(土) 21:09:58.78 ] >>784 sort -k5 -n だろ
786 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/14(土) 21:10:24.24 ] まぁ、ls -Sで良いんじゃないのか
787 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/14(土) 21:15:57.76 ] >>784 > 理由を知ってる人がいたら教えてちょうだい。 使い方が間違っている。
788 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/14(土) 21:18:22.79 ] 0番目から数えたくなる気持は分からなくもない
789 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/14(土) 21:26:12.51 ] いや、だって、man sort したら、 -k POS1[,POS2] -K POS1[,POS2] ソートフィールド指定の POSIX 形式。今後はこちらが 推奨される。行の POS1 から POS2 までのフィールドを指定する。 POS2 を含む。 POS2 が省略されたら行末まで。 フィールドと文字位置 はそれぞれ 0 から数えはじめる。 て書いてあったんだもん。 それを何も考えず信じたのでした。 LANG=C man sort だと、 -k, --key=POS1[,POS2] start a key at POS1 (origin 1), end it at POS2 (default end of line) てなってるのね。 確かに -k5ならソートしてくれたよ。 なんだかスレ汚し失礼しました。
790 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/14(土) 21:34:49.42 ] 本当だ。普段manpageは英語のものしか見ないから気付かなかった。
791 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 01:03:11.15 ] 俺もだまされた。 さすが Linux とおもた。
792 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 01:13:16.43 ] Linuxの日本語manはまったく整備されてないからなぁ
793 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 01:18:04.06 ] alias man='LANG=C man' しとくのオススメ
794 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 01:20:40.59 ] $ man sort じゃなくて $ info sort がオヌヌメ
795 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 02:33:57.03 ] Linuxの日本語 manと言えば、最近 bash 4.2の manが 翻訳されたのが嬉しかった。 GNU bash 4.2 の翻訳 linuxjm.sourceforge.jp/INDEX/gnu.html#GNU_bash
796 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 11:22:51.82 ] コマンド foo と同名の関数 foo を作成し、後者の中から前者を呼び出そうと思っています。 function foo { foo } しかし当然ながら無限ループになります。 解決策としては function foo { `which foo` } という方法があります。 しかし毎回 which コマンドを起動するのがちょっと気にかかります。 別の方法として function foo { ¥foo } というのを試しましたが、だめでした。¥foo はエイリアスには効くけど関数にはききませんでした。 というわけで、今のところ which コマンドを使う方法しかなさそうですが、もっといい方法があれば教えて下さい。
797 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 11:26:42.70 ] >>796 function foo { command foo } そのための「command」コマンド。
798 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 12:24:24.87 ] 話は変わるけど、bashには`help'という組み込み関数があって、 bash$ help function とか bash$ help command とかするとその部分の説明文だけ表示してくれる
799 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 13:24:53.76 ] 単に /usr/bin/foo とかすればいいんじゃないの?
800 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 13:34:57.91 ] >>799 最適解(>>797 )が既に出てるのに、外した回答するオマエは黙ってろ。 PATHが違ったら適応できないだろw
801 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 16:01:28.21 ] >>799 のレスは別に問題視するようなものじゃない。 〜の方が良いと書いてあれば別だが。
802 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/15(日) 16:16:51.47 ] >>801 >>796 の質問で、わざわざ `which foo` と書いてることから、 絶対PATHで書いたのでは問題の解決にならないことは読みとれる。 質問者自信も絶対PATHを使う方法は知っている(けどそれじゃ駄目)と読みとれる。 質問の回答になってないのだから問題視されてもしょうがない。
803 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/16(月) 01:51:19.72 ] >>801 >>799 みたいなトンチンカンな回答にも丁寧に答えてあげている >>800 の優しさに気づけ
804 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/17(火) 15:40:51.44 ] >>797 「command」なんて初めて知りました。完璧です。ありがとうございました。 >>802 状況としてはまったくそのとおりで、すばらしいエスパーっぷりですが、 799はそこまで敵視されるようなことを書いてるわけじゃないので、 そんなに怖がらせなくてもいいかなと思いました。 技術者同士はみんな仲良くね!戦うべき相手は別にいるよ!
805 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/17(火) 16:49:46.48 ] >>800 は常駐さんのお決まりレスです。 彼なりにイカしたレスだとお考えになっているのでしょう。 しばらくここにいれば慣れます。
806 名前:名無しさん [2012/04/23(月) 01:47:23.08 ] 検索コンプレックス
807 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/28(土) 14:15:07.91 ] 関数もexportできるようにならないかなぁ 環境変数ならぬ環境関数みたいな 便利だと思うんだけど
808 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/28(土) 14:19:23.03 ] >>807 え? できるけど。 export -f
809 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/29(日) 08:45:26.54 ] >>808 bash乙
810 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/29(日) 09:44:51.95 ] ____ / \ / _ノ ヽ、_ \ / o゚⌒ ⌒゚o \ 不毛な言い争いがまた始まるお… | (__人__) | \ ` ⌒´ /
811 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/29(日) 10:46:16.86 ] キミの好物じゃないの
812 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/29(日) 17:13:31.08 ] >>808 ほんとだ、bashだとexport -fでできるのね zshだと駄目なんだけどオプションが違うんだろうか
813 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/29(日) 17:16:47.95 ] zshは今誰も使ってないからバグが放置されてるんじゃないか?
814 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/04/29(日) 18:14:30.17 ] >>813 そうなんだぁ・・・ いっそbashに戻ろうかな
815 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 03:50:24.36 ] 質問です。 複数のコマンドの実行結果をソートしたいですが、うまくいきません。例えば、 イメージ的には以下のような感じ。 { cat FILE_A find PATH1 -print find PATH2 -print find PATH3 -print } | sort > FILE_A 以下を試しました find PATH1 -print >> FILE_A find PATH2 -print >> FILE_A find PATH3 -print >> FILE_A cat FILE_A | sort > FILE_A こうすると最後の FILE_A のファイルに結果がすべて出力されず尻切れになり ます。
816 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 03:59:02.05 ] zshかbash系だとして一行で済ますなら $ cat <(find PATH1) <(find PATH2) <(find PATH3) | sort $ cat < FILE_A | sort > FILE_A が失敗するのはまあそんなものだと思っておけばいい。 同じファイルから読み込んで出力するのは失敗する。 $ cat < FILE_A | sort > FILE_B ならおk
817 名前:名無しさん@お腹いっぱい。 [2012/05/06(日) 04:09:18.13 ] (rm FILE_A; sort > FILE_A) < FILE_A みたいな手もあるが、間違えたら泣ける。
818 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 04:15:04.88 ] 同じ条件で検索するなら find PATH1 PATH2 PATH3 | sort でいいよな。
819 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 05:15:17.42 ] >>815 > cat FILE_A | sort > FILE_A マルチタスクな OS では普通パイプやリダイレクトの際に前後の プロセスが同時に起動する。 ファイルを読むプロセスが終了するのを待ってファイルを書くプ ロセスが起動する訳ではない。 なので、上記の場合は最後に書き込むファイル名を変更しなければならない。
820 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 14:36:51.94 ] TEMP=`tempfile` cat FILE_A > "$TEMP" find PATH1 -print >> "$TEMP" find PATH2 -print >> "$TEMP" find PATH3 -print >> "$TEMP" sort "$TEMP" > FILE_A
821 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 14:53:36.25 ] すみませんが添付ファイルは梨の奉公でお願いします
822 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 15:27:35.80 ] >>815 www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html#sort-invocation cat FILE_A | sort -o FILE_A
823 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 16:20:24.14 ] >>822 catとパイプが無駄です。 sort -o FILE_A FILE_A
824 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 17:20:10.08 ] ランダルシュワルツの不要なcat添削を思いだした
825 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 18:55:31.70 ] cat議論はこのスレの>>147-213 あたりで延々やってるな。
826 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 19:22:02.88 ] 添付ファイルを使わないのは大手SIerじゃ常識だね。
827 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/06(日) 19:23:49.29 ] 思案パイプ
828 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/07(月) 19:19:08.78 ] 対話方式にならないようにシェルスクリプト自信がroot権限で実行されるようにするスクリプトって作れますか?
829 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/07(月) 21:03:44.73 ] >>828 対話的コマンドでもexpectでなんとかなる
830 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/07(月) 21:11:42.22 ] >>829 そういう意味じゃなくて、シェルスクリプト中で su -c hoge とかしないで root権限の動作をさせたいという質問かとエスパー。
831 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/07(月) 21:16:30.15 ] 基本的にsuidはシェルスクリプトでは許可されてないからねえ。 昔あったsuidperlみたいなののbash版を探してみたけどないみたいだし。 sudersに対象となるスクリプトに対してNOPASSWDを設定するぐらいしか思いつかないや。
832 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/08(火) 02:00:49.38 ] >>828 できます コマンドラインを実行するだけのプログラムを作って setuidするば
833 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/08(火) 07:52:21.31 ] >>832 >>831
834 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/09(水) 13:22:49.97 ] forum.xda-developers.com/showthread.php?t=540483 ここに書いてあるシェルスクリプトを動かしてみたんですが、 Syntax error: "do" unexpectedと返されてしまいます ヒントだけでもいいんで教えてください。
835 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/09(水) 13:28:11.27 ] -x 付けて実行してどこでエラーか見てみたら bash -x secrets.sh
836 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/09(水) 13:29:47.52 ] >>835 わからないなら黙ってろ
837 名前:835 mailto:sage [2012/05/09(水) 13:30:45.77 ] あ、スレ間違えてたorz
838 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/09(水) 15:17:41.55 ] なぜかしら、回答としては合ってる気がするぞw
839 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/10(木) 06:54:48.81 ] コピペの際に文の末尾に\rが入っちゃってるとか。
840 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/14(月) 22:36:21.02 ] alias cd=chdir function chdir { if [ -r "$1" -a -d "$1" -o "$1" = "" ] ; then local i for i in 8 7 6 5 4 3 2 1 0 ; do dirstack[$i+1]=${dirstack[$i]} done dirstack[0]=`pwd` \cd $1 fi pwd } function ds { echo "p:"`pwd` local i for i in 0 1 2 3 4 5 6 7 8 9 ; do echo "$i:${dirstack[$i]}" done } bash用のをcsh(tcshですが)に書き換えてもらえないでしょうか。
841 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/14(月) 22:36:59.98 ] function bd { dirstack[10]=`pwd` \cd ${dirstack[0]} local i for i in 0 1 2 3 4 5 6 7 8 9 ; do dirstack[$i]=${dirstack[$i+1]} done pwd } function nd { dirstack[10]=`pwd` \cd ${dirstack[9]} local i for i in 8 7 6 5 4 3 2 1 0 ; do dirstack[$i+1]=${dirstack[$i]} done dirstack[0]=${dirstack[10]} pwd }
842 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/15(火) 09:15:03.98 ] pushd じゃダメなん?
843 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/15(火) 16:36:43.46 ] >>842 体に馴染んでるんで…すいません
844 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 16:34:35.79 ] もっとマシな方法ありますか?考えても、これくらいしか思いつかない。 デフォルトのBourne Shellではチルダ展開がないようなので、posix shellにて チルダ展開が必要な場合がある、ファイル名に空白等を含んだものが、パラメータに入っているとして、 file_name="~/src/te st" echo "${file_name}をチルダ展開しlsします。\n" ls -l "$( eval echo -n ${file_name} )"
845 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 16:40:45.81 ] lsに限らず、それ以外でも扱える、方法が知りたいです。
846 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 17:10:41.70 ] >>844 例が悪い。その1番下の行の ls -l "$( eval echo -n ${file_name} )" だって、複数の空白が空白1個にまとめられちゃうし、 $ < > 等の記号が含まれると ${file_name} (クォートなし)の展開と evalの展開で大変なことになるぞ。
847 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 17:30:39.54 ] >>846 確かに、例は悪いだろうな。大変なことになる。 でも考えても、これくらいしか思いつかなかったので、 いい加減にして、聞いた方が早いかと書き込んだんだよ。
848 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 17:34:06.75 ] シェル変数内にチルダが入っている時、チルダ展開だけやって その他の空白とか * $ < > とかの解釈はさせないって方法がないんだよな。 sedでチルダを $HOME に書き換えろ。
849 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 17:46:31.95 ] >>844 file_name="~/src/te st * $ < >" ls -l "${file_name/\~/$HOME}"
850 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/16(水) 18:49:13.65 ] >>846 , >>848 , >>849 あああ!ありがとう。 ls -l "$( echo -n "${file_name}" | sed s#^~#$HOME# )"
851 名前:844 mailto:sage [2012/05/16(水) 21:00:34.05 ] しばらく考えてこうしました。 ls -l "$( [ "${file_name%%/*}" = "~" ] && echo "$HOME/${file_name#~/}" || echo "${file_name}" )" if [ "${file_name%%/*}" = "~" ] then ls -l "$HOME/${file_name#~/}" else ls -l "${file_name}" fi
852 名前:名無しさん@お腹いっぱい。 [2012/05/18(金) 05:23:42.76 ] v7shについて色々調べてるのですがどうしても関数を使用しようとすると test.sh: syntax error at line 2: `(' unexpected とエラーが出てきて使用できません。空白、頭にfunctionを付ける等いろいろ試してみましたがやはり変わらず・・・ UNIX version 7の頃のshには関数がないということでしょうか?
853 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 05:27:04.29 ] sage忘れました。申し訳ないです。
854 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 06:51:13.40 ] >>852 シェル関数はないよ。 代用として、シェル関数にしたい内容をシェル変数に入れて、その変数を実行する。 func='ls -l' $func で ls -l が実行される。引数を渡したい時は工夫して。
855 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 07:00:59.45 ] >>852 あんまり役に立たないかも知れないですが、無いと思います。 参考までに 1. Bourne Shell Tutorial www.grymoire.com/Unix/Sh.html The original version of the Bourne shell didn't have functions. If you wanted to perform an operation more than once, you either had to duplicate the code, or create a new shell script. 2. Linux におけるシェルの進化 www.ibm.com/developerworks/jp/linux/library/l-linux-shells/?cmp=dw&cpb=dwlin&ct=dwrss&cr=dwrss&ccy=jp&csr=012012 ただし、関数を定義する機能は欠けていました。 3. 知っている限りでは、ここが一番情報が多い traditional Bourne shell family / history and development www.in-ulm.de/~mascheck/bourne/ The Variants A summary of the most important changes ? Version 7 (1979) control structures, cmd substitution, () and {}, arbitrary variable names, trap, eval, special parameter substitutions, case ? System III (1981) #, [!...], colon parameter substitution, set -- ? SVR1 (1983) shift n ? SVR2 (1984) functions, built-ins: unset echo type, redirection for builtins 4. 3の下の方のSource codeにある、Nikola Vladov のマニュアルで、 man v7sh BUGS Coexists with but doesn't understand shell functions. 5. FreeBSD Portsはよく分かりませんが、 v7sh FreeBSD www.freebsdsoftware.org/shells/v7sh.html functions aren't supported and command line input is not 8 bit clean
856 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 15:41:41.74 ] >>854 >>855 ありがとうございます!やっぱりなかったんですね case文で;;を使用してもcase文抜けられないのも仕様なのかなぁ マニュアル読んだら使用できそうではあったんですけども・・・一応使用したテストスクリプト上げておきます。 #!/usr/local/bin/v7sh case $1 in a) echo "A!!" ;; b) echo "B!!" ;; c|d) echo "C or D" ;; [e-h]) echo "E kara H" ;; *) echo "NANIKORE?" ;; esac で結果が以下のようになりました。 $ test.sh a A!! NANIKORE?
857 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 16:34:52.98 ] 仕様じゃね? ソースあるんだから読んで解析してくれ 読みにくいってレベルじゃないけど
858 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 20:07:10.23 ] >>856 なんででしょうね? そのままコピペしてv7shで試しましたが、こちらでは期待通りの動作でした。 $ ./v7case.sh a A!! $
859 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/18(金) 22:31:03.13 ] >>858 謎ですね・・・v7shなんて過去のものですから大差があるとは考えにくいですし 通常のコマンド待ち状態で ;; を打つとエラーが出ますから case内でしか特殊な意味を持たないと思われるんですけどね・・・
860 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/24(木) 17:44:12.51 ] msysgit(windows版git)付属のbashでログイン時のディレクトリをホーム以外にしたいんだけど、どうしたらいい? 例えば、$HOME/work/hogeでいつも作業するのでbash起動時にそこにいて欲しい。 $HOMEを書きかえると他にも影響があり過ぎるので別の方法教えてください。 適切なスレが見つからなかったので、誘導して。
861 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/24(木) 18:49:28.23 ] etc/profileの最後にcd ~/work/hoge?
862 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/24(木) 20:59:36.08 ] そんな単純なことでよかったのか... 恥ずかしいー
863 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/24(木) 21:28:32.29 ] $HOME/.bash_profileの方が良いんじゃ?
864 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/05/25(金) 02:08:36.57 ] かなり遅れましたが>>834 です -xをつけて実行してみたところ、 # bash -x secrets.sh + echo -n : Invalid argument: apks.txt + echo -n : Invalid argument: output.txt secrets.sh: line 5: syntax error near unexpected toke' `do 'ecrets.sh: line 5: `do 以下のようになりました。